【学习笔记】Hibernate HQL连接查询和数据批处理 (Y2-1-7)

HQL连接查询

和SQL查询一样 hql也支持各种链接查询 如内连接 外连接

具体如下

左外连接    left (outer) join

迫切左外连接  left (outer) join fetch

右外连接    right (outer) join

内连接     (inner) join

迫切内连接   (inner) join fetch

那么今天举的例子仍然是学生Student和Grade

学生和年级的一对多的关系

一个学生属于一个年级 一个年级有多个学生

已经配置好了一对多双向关联 在此不做截图 因为不是主要内容

两个实体类如下

public class Student {
private Integer stuid;
private String sname;
private Grade grade;
public class Grade {
private Integer gid;
private String gname;
private Set<Student> stus=new HashSet<Student>();

我们可以看到 Grade里面有一个存放学生类的集合

@Test
//查询
public void select() {
String hql="FROM Grade";
List<Grade> list=session.createQuery(hql).list();
for (Grade item:list){
System.out.println(item.getGname());
System.out.println("----------");
for (Student stu:item.getStus()){
System.out.println(stu.getSname());
}
System.out.println();
}
} @Test
//左外连接
public void leftOuter() {
String hql="select distinct g FROM Grade g LEFT JOIN g.stus";
List<Grade> list=session.createQuery(hql).list();
for (Grade item:list){
System.out.println(item.getGname());
System.out.println("----------");
for (Student stu:item.getStus()){
System.out.println(stu.getSname());
}
System.out.println();
}
} @Test
//迫切左外连接
public void leftOuterFetch() {
String hql="select g FROM Grade g LEFT JOIN fetch g.stus";
List<Grade> list=session.createQuery(hql).list();
for (Grade item:list){
System.out.println(item.getGname());
System.out.println("----------");
for (Student stu:item.getStus()){
System.out.println(stu.getSname());
}
System.out.println();
}
} @Test
//右外连接
public void rightOuter() {
String hql="select distinct g FROM Grade g right join g.stus";
List<Grade> list=session.createQuery(hql).list();
for (Grade item:list){
System.out.println(item.getGname());
System.out.println("----------");
for (Student stu:item.getStus()){
System.out.println(stu.getSname());
}
System.out.println();
}
} @Test
//内连接
public void inner() {
String hql="select distinct g FROM Grade g join g.stus";
List<Grade> list=session.createQuery(hql).list();
for (Grade item:list){
System.out.println(item.getGname());
System.out.println("----------");
for (Student stu:item.getStus()){
System.out.println(stu.getSname());
}
System.out.println();
}
} @Test
//迫切内连接
public void innerFetch() {
String hql="select g FROM Grade g join fetch g.stus";
List<Grade> list=session.createQuery(hql).list();
for (Grade item:list){
System.out.println(item.getGname());
System.out.println("----------");
for (Student stu:item.getStus()){
System.out.println(stu.getSname());
}
System.out.println();
}
}

以上是五种连接查询方式

(返回的都是一个Grade类型的集合 然后从Grade中获取stus集合 遍历学生)

其中迫切外连接和 不迫切的区别:

迫切外连接会直接把所有内容查询到 即年级和学生一并查询

而如果不是迫切连接  不会直接查询到学生

而是先查询年级 用到学生的属性时再去查询学生.

数据批处理

1.使用HQL进行批量操作
HQL可以查询数据 也可以批量插入 更新 删除
操作时机在数据库中完成 处理的数据不需要加载到Session缓存中

session.executeUpdate()

@Test
//HQL批量插入
public void hqlInsert(){
String hql="insert into Grade(gname) select g.gname||g.gid from Grade g where g.gid>0";
session.createQuery(hql).executeUpdate();
} @Test
//HQL批量更新
public void hqlUpdate(){
String hql="update Grade g set g.gname='zz' where g.gid>5";
session.createQuery(hql).executeUpdate();
} @Test
//HQL批量删除
public void hqlDelete(){
String hql="delete from Grade g where g.gid>5";
session.createQuery(hql).executeUpdate();
}

2.JDBC API进行批量操作
Work work=new Work();

我们这里使用的是一个work类 和session的doWork方法

执行的是JDBC的内容

因此控制台不会生成sql

@Test
//JDBC API 进行批量更新
public void jdbcUpdate(){
Work work=new Work() {
public void execute(Connection connection) throws SQLException {
PreparedStatement ps=connection.prepareStatement("update grade set gname='pp' where gid>?");
ps.setInt(1,2);
ps.executeUpdate();
}
};
session.doWork(work);
System.out.println("更新完成");
}

3.使用session进行批量操作
Grade grade=null;

使用两个方法

session.flush()

session.evict()

进行强制刷新缓存和清空缓存

上一篇:转: Hibernate HQL查询 插入 更新(update)实例


下一篇:Minecraft Fabric 教程 #1 开发环境配置