【学习笔记】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()
进行强制刷新缓存和清空缓存