Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >SSH框架之旅-hibernate(4)

SSH框架之旅-hibernate(4)

作者头像
Wizey
发布于 2018-08-30 01:40:29
发布于 2018-08-30 01:40:29
1.7K00
代码可运行
举报
文章被收录于专栏:编程心路编程心路
运行总次数:0
代码可运行

hibernate

1.hibernate 查询方式


    1. 对象导航查询 一个对象关联了另一个对象,并且两者是一对多的关系,那么通过一个(一方)对象就可以找到另外一个(多方)对象。例如:由一个班级就可以找到班上所有的学生,这种通过班级对象找到学生对象的查询方式就叫做对象导航查询。
    1. OID 查询 又称对象唯一标识符查询。根据对象属性中的唯一标识值来查询这个对象,session 的 get() 方法还有下面说到的 load() 方法,都是 OID 的查询方式。
    1. HQL 查询 使用 Query 对象调用相关的方法来做查询,需要写相关的hql语句,这是 hibernate 提供的查询语言,hql 语句中写的是实体类和属性,而 sql 语句中写的是数据表和字段。
    1. QBC 查询 使用 Criteria 对象调用相关的方法做查询,但是不需要写语句,调用的是方法,操作的也是实体类和属性。
    1. SQL 查询 使用 SQLQuery 对象写普通的 sql 语句来做查询,但由于数据库的不同,sql 语句也有所不同,所以一般不使用这种查询方式。但如果需要底层数据库的 SQL 方言查询时,还是可以使用这种方式的。hibernate 种也封装了 SQL 查询的对象 SQLQuery。

2.基本代码


下面的例子也是基于班级和学生一对多关系说明的。

2.1 实体类代码

  • 学生实体类
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cc.wenshixin.entity;

public class Student {
    private Integer id; // 学号
    private String name; // 姓名
    private Integer age; // 年龄

    private Banji banji; // 所属班级

    public Student() {

    }

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    //get,set方法在此省略,必须要写的
}
  • 班级实体类
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cc.wenshixin.entity;

import java.util.HashSet;
import java.util.Set;

public class Banji {
    private Integer id; //编号
    private String name; //名称
    
    private Set<Student> setStudent = new HashSet<Student>(); //班级里的学生

    public Banji() {

    }

    public Banji(String name) {
        this.name = name;
    }
    //get,set方法在此省略,必须要写的
}
  • 工具类
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cc.wenshixin.utility;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtility {
    private static Configuration cfg = null;
    private static SessionFactory sessionFactory = null;

    static{
        cfg = new Configuration().configure();
        sessionFactory = cfg.buildSessionFactory();
    }
    
    //获得sessionFactory对象的方法
    public static SessionFactory getSessionFactory()
    {
        return sessionFactory;
    }   
}

2.2 映射文件

  • 学生实体类映射文件
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="cc.wenshixin.entity.Student" table="student">
        <id name="id" type="java.lang.Integer" column="sid">
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String" column="sname">
        </property>
        <property name="age" type="java.lang.Integer" column="age">
        </property>
        <many-to-one name="banji" class="cc.wenshixin.entity.Banji" column="sbid">
        </many-to-one>
    </class>
</hibernate-mapping>
  • 班级实体类映射文件
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="cc.wenshixin.entity.Banji" table="banji">
        <id name="id" type="java.lang.Integer" column="bid">
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String" column="bname">
        </property>
        <set name="setStudent" table="student" cascade="save-update">
            <key column="sbid">
            </key>
            <one-to-many class="cc.wenshixin.entity.Student" />
        </set>
    </class>
</hibernate-mapping>
  • 核心配置文件
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
      <!-- 数据库信息配置 -->
      <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
      <property name="connection.url">jdbc:mysql://localhost:3306/数据库名?useUnicode=true&characterEncoding=UTF-8</property>
      <property name="connection.username">用户名</property>
      <property name="connection.password">密码</property>
      
      <!-- hibernate功能选择 -->
      <property name="show_sql">true</property>
      <property name="format_sql">true</property>
      <property name="hbm2ddl.auto">update</property>
      <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
      
      <!-- 加载映射文件 -->
      <mapping resource="cc/wenshixin/entity/Student.hbm.xml"/>
      <mapping resource="cc/wenshixin/entity/Banji.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

2.3 数据初始化

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Test
    //初始化数据
    public void initData()
    {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;
        try{
            sessionFactory = HibernateUtility.getSessionFactory();
            session = sessionFactory.openSession();
            tx = session.beginTransaction();
            
            //插入数据
            Banji banji1 = new Banji("计科一班");
            Banji banji2 = new Banji("计科二班");
            Banji banji3 = new Banji("计科三班");
            Banji banji4 = new Banji("计科四班");
            
            Student student1 = new Student("小明", 20);
            Student student2 = new Student("小红", 19);
            Student student3 = new Student("小智", 21);
            Student student4 = new Student("小张", 20);
            Student student5 = new Student("小李", 19);
            Student student6 = new Student("老王", 23);
            Student student7 = new Student("小魏", 20);
            
            banji1.getSetStudent().add(student1);
            banji1.getSetStudent().add(student3);
            banji2.getSetStudent().add(student2);
            banji2.getSetStudent().add(student5);
            banji2.getSetStudent().add(student4);
            banji3.getSetStudent().add(student6);
            banji4.getSetStudent().add(student7);
            
            session.save(banji1);
            session.save(banji2);
            session.save(banji3);
            session.save(banji4);
            
            tx.commit();
        }catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }

2.4 对象导航查询测试

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Test
    //对象导航查询方式
    public void test()
    {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;
        try{
            sessionFactory = HibernateUtility.getSessionFactory();
            session = sessionFactory.openSession();
            tx = session.beginTransaction();
            
            Banji banji = session.get(Banji.class, 2);
            Set<Student> setStudent = banji.getSetStudent();

            System.out.println(setStudent.size());
            for (Student student : setStudent) {
    System.out.println(student.getId()+":"+student.getName()+":"+student.getAge());
            }
            
            tx.commit();
        }catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }

3.HQL 查询


常用的 hql 语句(关键字大小写都可以的):

    1. 查询所有: from 实体类名称
    1. 条件查询(使用 AS 关键词设置别名): from 实体类名称 as 别名 where 别名.属性名称=? from 实体类名称 as 别名 where 别名.属性名称=? and 别名.属性名称=? from 实体类名称 as 别名 where 别名.属性名称 like ?
    1. 排序查询: from 实体类名称 as 别名 order by 别名.属性名称 asc/desc
    1. 分页查询: 通过调用方法来实现,设置开始位置 query.setFirstResult(0);,设置每页记录数 query.setMaxResults(3);
  • 5.投影查询: 在投影查询中才会用到 SELECT 关键字,在前面的查询中是用不到的,并且不能使用 * 号。 select 属性名称 from 实体类名称
  • 6.函数查询: 在HQL中也是可以使用 sql 函数的,count()函数计算数量,sum()函数求和,avg()函数计算平均值,max()函数计算最大值,min()函数计算最小值。

hql语句查询步骤:

    1. 创建 Query 对象,写 hql 语句
    1. 调用 query 对象里面的方法得到结果

3.1 查询所有

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Test
    //HQL查询表中所有数据
    public void testQueryAll()
    {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;
        try{
            sessionFactory = HibernateUtility.getSessionFactory();
            session = sessionFactory.openSession();
            tx = session.beginTransaction();
            
            Query<Banji> query = session.createQuery("FROM Banji");
            
            List<Banji> list = query.list();
            
            for(Banji banji:list)
            {
                System.out.println(banji.getId()+":"+banji.getName());
            }
            
            tx.commit();
        }catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }

3.2 条件查询

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Test
    //HQL带条件的查询
    public void testQueryWhere1()
    {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;
        try{
            sessionFactory = HibernateUtility.getSessionFactory();
            session = sessionFactory.openSession();
            tx = session.beginTransaction();
            
            Query<Banji> query = session.createQuery("FROM Banji AS banji WHERE banji.id=?");
            query.setParameter(0, 2);
            
            List<Banji> list = query.list();
            
            for(Banji banji:list)
            {
                System.out.println(banji.getId()+":"+banji.getName());
            }
            
            tx.commit();
        }catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }

    @Test
    //模糊条件查询
    public void testQueryWhere2()
    {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;
        try{
            sessionFactory = HibernateUtility.getSessionFactory();
            session = sessionFactory.openSession();
            tx = session.beginTransaction();
            
            Query<Banji> query = session.createQuery("FROM Banji AS banji WHERE banji.name LIKE ?");
            query.setParameter(0, "%计科%");
            
            List<Banji> list = query.list();
            
            for(Banji banji:list)
            {
                System.out.println(banji.getId()+":"+banji.getName());
            }
            
            tx.commit();
        }catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }

3.3 排序查询

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Test
    //排序查询
    public void testQueryOrder()
    {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;
        try{
            sessionFactory = HibernateUtility.getSessionFactory();
            session = sessionFactory.openSession();
            tx = session.beginTransaction();
            
            Query<Banji> query = session.createQuery("FROM Banji AS banji ORDER BY banji.id DESC");
            
            List<Banji> list = query.list();
            
            for(Banji banji:list)
            {
                System.out.println(banji.getId()+":"+banji.getName());
            }
            
            tx.commit();
        }catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }

3.4 分页查询

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Test
    //分页查询
    public void testQueryPage()
    {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;
        try{
            sessionFactory = HibernateUtility.getSessionFactory();
            session = sessionFactory.openSession();
            tx = session.beginTransaction();
            
            Query<Student> query = session.createQuery("FROM Student");
            
            query.setFirstResult(2);
            query.setMaxResults(3);
            
            List<Student> list = query.list();
            
            for(Student student : list)
            {
                System.out.println(student.getId()+":"+student.getName()+":"+student.getAge());
            }
            
            tx.commit();
        }catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }

3.5 投影查询

听起来很高大上,其实就是查询数据表中的某一列。。。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
    //投影查询
    public void testQueryShade()
    {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;
        try{
            sessionFactory = HibernateUtility.getSessionFactory();
            session = sessionFactory.openSession();
            tx = session.beginTransaction();
            
            //注意返回的结果是一个object类型,而不是一个实体类的类型
            Query<Object> query = session.createQuery("SELECT name FROM Student");
            
            List<Object> list = query.list();
            
            for(Object object : list)
            {
                System.out.println(object);
            }
            
            tx.commit();
        }catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }

3.6 函数查询

需要类型转换

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Test
    //函数查询
    public void testQueryFunction()
    {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;
        try{
            sessionFactory = HibernateUtility.getSessionFactory();
            session = sessionFactory.openSession();
            tx = session.beginTransaction();
            
            Query<Object> query = session.createQuery("SELECT COUNT(id) FROM Student");
            
            Object object = query.uniqueResult(); //获取查询结果唯一值
            
            //先转换为long类型,再转换成int类型
            Long obj = (Long)object;
            int count = obj.intValue();
            System.out.println(count);
            
            tx.commit();
        }catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }

4.QBC 查询


QBC 查询是通过 Restrictions 类的静态方法来实现的,具体的方法如下表所示。

静态方法

说明

Restrictions.eq()

等于

Restrictions.allEq()

使用 Map,使用 key/value 进行多个等于的比较

Restrictions.gt()

大于 >

Restrictions.ge()

大于等于 >=

Restrictions.lt()

小于 <

Restrictions.le()

小于等于 <=

Restrictions.between()

对应 sql 语句中的 between 语句

Restrictions.like()

对应 sql 的like 语句

Restrictions.in()

对应 sql 的 in 语句

Restrictions.and()

and 关系

Restrictions.or()

or 关系

Restrictions.sqlRestriction()

sql 限定查询

4.1 查询所有

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Test
    public void testAll()
    {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;      
        try{
            sessionFactory = HibernateUtility.getSessionFactory();
            session = sessionFactory.openSession();
            tx = session.beginTransaction();
            
            //查询所有
            Criteria criteria = session.createCriteria(Student.class);
            List<Student> list = criteria.list();
            
            for (Student student : list) {
                System.out.println(student.getId()+":"+student.getName()+":"+student.getAge());
            }
            
            tx.commit();
        }catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }

4.2 条件查询

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Test
    public void testWhere1()
    {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;      
        try{
            sessionFactory = HibernateUtility.getSessionFactory();
            session = sessionFactory.openSession();
            tx = session.beginTransaction();
            
            //条件查询
            Criteria criteria = session.createCriteria(Student.class);
            criteria.add(Restrictions.eq("id", 4)); //相当于where sid = 4
            criteria.add(Restrictions.eq("age", 19)); 
            List<Student> list = criteria.list();
            
            for (Student student : list) {
                System.out.println(student.getId()+":"+student.getName()+":"+student.getAge());
            }
            
            tx.commit();
        }catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }

    @Test
    public void testWhere2()
    {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;      
        try{
            sessionFactory = HibernateUtility.getSessionFactory();
            session = sessionFactory.openSession();
            tx = session.beginTransaction();
            
            //模糊查询
            Criteria criteria = session.createCriteria(Student.class);
            criteria.add(Restrictions.like("name", "%小%"));
            List<Student> list = criteria.list();
            
            for (Student student : list) {
                System.out.println(student.getId()+":"+student.getName()+":"+student.getAge());
            }
            
            tx.commit();
        }catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }

4.3 排序查询

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Test
    public void testOrder()
    {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;      
        try{
            sessionFactory = HibernateUtility.getSessionFactory();
            session = sessionFactory.openSession();
            tx = session.beginTransaction();
            
            //排序查询
            Criteria criteria = session.createCriteria(Student.class);
            criteria.addOrder(Order.desc("id"));
            List<Student> list = criteria.list();
            
            for (Student student : list) {
                System.out.println(student.getId()+":"+student.getName()+":"+student.getAge());
            }
            
            tx.commit();
        }catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }

4.4 分页查询

话不多说,请看代码。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Test
    public void testPage()
    {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;      
        try{
            sessionFactory = HibernateUtility.getSessionFactory();
            session = sessionFactory.openSession();
            tx = session.beginTransaction();
            
            //分页查询
            Criteria criteria = session.createCriteria(Student.class);
            criteria.setFirstResult(1);
            criteria.setMaxResults(4);
            List<Student> list = criteria.list();
            
            for (Student student : list) {
                System.out.println(student.getId()+":"+student.getName()+":"+student.getAge());
            }
            
            tx.commit();
        }catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }

4.5 函数查询

同 HQL 一样,QBC 也有函数查询,通过 Projections 类中的静态方法实现。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Test
    public void testFunction()
    {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;      
        try{
            sessionFactory = HibernateUtility.getSessionFactory();
            session = sessionFactory.openSession();
            tx = session.beginTransaction();
            
            //函数查询
            Criteria criteria = session.createCriteria(Student.class);
            criteria.setProjection(Projections.rowCount());
            List<Student> list = criteria.list();
            
            Object obj = criteria.uniqueResult();
            Long lobj = (Long)obj;
            int count = lobj.intValue();
            
            System.out.println(count);
            
            tx.commit();
        }catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }

4.6 离线查询

DetachedCriteria 翻译为离线条件查询,他不不依赖 Session 来创建,所以 DetachedCriteria 可以被其他层使用条件封装,在交给 DAO 层查询,在 SSH 框架的整合上经常使用。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Test
    public void testOutLine()
    {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;      
        try{
            sessionFactory = HibernateUtility.getSessionFactory();
            session = sessionFactory.openSession();
            tx = session.beginTransaction();
            
            //离线查询
            DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Student.class);
            Criteria criteria = detachedCriteria.getExecutableCriteria(session);
            List<Student> list = criteria.list();
            
            for (Student student : list) {
                System.out.println(student.getId()+":"+student.getName()+":"+student.getAge());
            }
            
            tx.commit();
        }catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }

5.hibernate 检索策略


5.1 多表连接查询。

在做表的查询时,有时要采用连接查询进行对表联合查询,下面是 mysql 中的多表查询写法。

  • 交叉查询 查询的结果是返回被连接的表中的所有数据行的笛卡尔积,返回的结果条数也就是一个表的数据记录乘以另一个比表的数据记录数,在开发中最好不要使用交叉查询,因为数据量不算很大时,查询效率就极低,在设计数据表时应该避免这种查询方式。 select * from student, banji;
  • 内连接 select * from student, banji where student.sid=banji.bid; select * from student inner join banji on student.sid=banji.bid;
  • 外连接
    • 左外连接 select * from student left outer join banji on student.sid=banji.bid;
    • 右外连接 select * from student right outer join banji on student.sid=banji.bid;

5.2 HQL 连接查询

5.2.1 内连接查询

内连接有一般的内连接查询,还有迫切内连接查询,迫切连接查询比一般的内连接查询多了一个 fetch 关键字两种方式返回的结果集不同。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Test
    //内连接查询
    public void testQueryInner()
    {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;
        try{
            sessionFactory = HibernateUtility.getSessionFactory();
            session = sessionFactory.openSession();
            tx = session.beginTransaction();
            
            Query<Object> query = session.createQuery("from Banji as b inner join b.setStudent");
            
            List<Object> list = query.list(); //返回的是一个二维对象数组,list的每部分包含两个表中的数据
            
            tx.commit();
        }catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }

    @Test
    //迫切内连接查询
    public void testQueryInnerFecth()
    {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;
        try{
            sessionFactory = HibernateUtility.getSessionFactory();
            session = sessionFactory.openSession();
            tx = session.beginTransaction();
            
            Query<Object> query = session.createQuery("from Banji as b inner join fetch b.setStudent");
            
            List<Object> list = query.list(); //返回的是一个一维对象数组,只包含联合表student中的数据
            
            tx.commit();
        }catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }
5.2.2 外连接

外连接也分一般的外连接查询和迫切外连接查询,并且还有左外连接和右外连接之分。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Test
    //迫切外连接查询
    public void testQueryOuterFecth()
    {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;
        try{
            sessionFactory = HibernateUtility.getSessionFactory();
            session = sessionFactory.openSession();
            tx = session.beginTransaction();
            
            Query<Object> query = session.createQuery("from Banji as b left outer join fetch b.setStudent");
            
            List<Object> list = query.list(); //返回的是一个一维对象数组,只包含联合表student中的数据
            
            tx.commit();
        }catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }
    
    @Test
    //外连接查询
    public void testQueryOuter()
    {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;
        try{
            sessionFactory = HibernateUtility.getSessionFactory();
            session = sessionFactory.openSession();
            tx = session.beginTransaction();
            
            Query<Object> query = session.createQuery("from Banji as b left outer join b.setStudent");
            
            List<Object> list = query.list(); //返回的是一个二维对象数组,包含两个表中的数据
            
            tx.commit();
        }catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }

5.3 HQL 检索(抓取)策略

hibernate 的检索策略也是提升性能的一种方式,可以在获取关联对象的时候,对发送的语句进行优化,但是抓取策略需要和延迟加载一起使用来提升性能。

在前面,使用的是 session 对象的 get() 方法来发送语句查询数据库,但还可以 load() 来做查询,两者的区别是:get() 方法会马上发送语句查询数据库,而 load() 方法只有在执行到使用查询对象语句时才会发送语句查询数据库,load的延迟方式就是延迟查询方式。

延迟查询分为两类:

    1. 类级别延迟:根据 id 查询返回实体类对象,调用 load 方法不会马上发送语句。
    1. 关联级别延迟:查询一个班级,再查询一个班级的所有学生是否需要延迟,这个过程就称为关联级别延迟。

延迟就是发送 sql 语句的时间是否是随写随发的,还是用到的数据值的时候再发。

关于类级别延迟就是方法的区别,而关联级别延迟需要在映射文件中进行配置,根据班级来得到所有学生,就需要在班级实体类的映射文件中配置。在 set 标签上使用fetch属性和 lazy 属性。fetch 的默认就是 select 值,如果 fetch 属性的值为 join 那么 lazy 里面的值设置就失效了。设置 lazy 的值:true:表示延迟(默认);false:表示不延迟;extra表示极其延迟。

下面是示例代码:

类级别延迟

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @Test
    //get查询方式
    public void testGet()
    {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;
        try{
            sessionFactory = HibernateUtility.getSessionFactory();
            session = sessionFactory.openSession();
            tx = session.beginTransaction();
            
            Banji banji = session.get(Banji.class, 2);
            //这一句就发送sql语句
            Set<Student> setStudent = banji.getSetStudent();
            
            //这一句要打印的值只有在事务提交成功后才会显示
            System.out.println(setStudent.size()); 
            
            tx.commit();
        }catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }

    @Test
    //load查询方式
    public void testLoad()
    {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;
        try{
            sessionFactory = HibernateUtility.getSessionFactory();
            session = sessionFactory.openSession();
            tx = session.beginTransaction();
            
            Banji banji = session.load(Banji.class, 2);
            //这一句没有发送sql语句
            Set<Student> setStudent = banji.getSetStudent();

            //这一句才发送了sql语句,在事务提交后显示需要打印的值
            System.out.println(setStudent.size());
            
            tx.commit();
        }catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }

关联级别延迟

在班级实体类的配置文件中增加如下配置:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<set name="setStudent" table="student" cascade="save-update" lazy="false">
    <key column="sbid">
    </key>
    <one-to-many class="cc.wenshixin.entity.Student" />
</set>

批量抓取配置

为了进一步的提高查询的效率,hibernate 还有批量抓取的配置,只需要在set文件中加上 batch-size 的属性,在里面写上数字,数字越大,查询时发送的语句就越少,最大一般写 10。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<set name="setStudent" table="student" cascade="save-update" lazy="false"  batch-size="10">
    <key column="sbid">
    </key>
    <one-to-many class="cc.wenshixin.entity.Student" />
</set>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017.09.27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Hibernate文件配置
映射需要通过XML的配置文件来完成,这个配置文件尽量统一(xxx.hbm.xml) Hibernate核心的配置:必须的配置、可选的配置、映射文件的引入
用户3112896
2019/09/26
4290
Hibernate文件配置
Hibernate的缓存机制如何应用?
2.一级缓存应用: save()。当session对象调用save()方法保存一个对象后,该对象会被放入到session的缓存中。 get()和load()。当session对象调用get()或load()方法从数据库取出一个对象后,该对象也会被放入到session的缓存中。 使用HQL和QBC等从数据库中查询数据。
小小鱼儿小小林
2020/06/24
4570
hibernate系列之二
持久化:将程序数据在持久状态和瞬时状态间转换的机制;即将内存的数据永久存在关系型数据库中;
沁溪源
2020/09/03
4650
SSH框架之Hibernate第一篇
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
海仔
2019/09/18
5840
走进JavaWeb技术世界13:Hibernate入门经典与注解式开发
本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看
Java技术江湖
2019/10/24
1.8K0
Java面试之JDBC & Hibernate
1、数据库,比如100 用户同时来访,要采取什么技术解决?【基础】 答:可采用连接池。 111、什么是ORM?【基础】 答:对象关系映射(Object—Relational Mapping,简称ORM)是一种为了解决面向对象与面向关系数据库存在的互不匹配的现象的技术;简单的说,ORM 是通过使用描述对象和数据库之间映射的元数据,将java 程序中的对象自动持久化到关系数据库中;本质上就是将数据从一种形式转换到另外一种形式。 2、Hibernate 有哪5 个核心接口?【基础】 答: Configuration 接口:配置Hibernate,根据其启动hibernate,创建SessionFactory 对象; SessionFactory 接口:初始化Hibernate,充当数据存储源的代理,创建session 对象, sessionFactory 是线程安全的,意味着它的同一个实例可以被应用的多个线程共享,是重量级、二级缓存; Session 接口:负责保存、更新、删除、加载和查询对象,是线程不安全的,避免多个线程共享同一个session,是轻量级、一级缓存; Transaction 接口:管理事务;Query 和Criteria 接口:执行数据库的查询。 3、关于hibernate: 【基础】 1)在hibernate 中,在配置文件呈标题一对多,多对多的标签是什么;2)Hibernate 的二级缓存是什么;3)Hibernate 是如何处理事务的; 答:1)一对多的标签为 ;多对多的标签为; 2)sessionFactory 的缓存为hibernate 的二级缓存; 3)Hibernate 的事务实际上是底层的JDBC Transaction 的封装或者是JTA Transaction 的封装;默认情况下使用JDBCTransaction。
全栈程序员站长
2022/08/04
3360
Hibernate_day02总结
Hibernate_day02总结 今日内容 l Hibernate持久化对象的状态 l Hibernate的一级缓存 l Hibernate操作持久化对象的方法 l Hibernate 关联关系映射 1.1 上次课内容回顾: Hibernate框架的概述. * 什么是Hibernate * 持久层的ORM框架. * ORM:对象关系映射. * 常见的持久层框架 * JPA * Hibernate * Mybatis * JdbcTemplate * Hibernate流行版本: * 3.x和4.x H
Java帮帮
2018/03/19
1.5K0
Hibernate_day02总结
Hibernate二级缓存的使用「建议收藏」
SessionFactory 级别缓存 —- 二级缓存(进程范围)
全栈程序员站长
2022/08/31
1.3K0
Hibernate二级缓存的使用「建议收藏」
Hibernate第二天:Hibernate的一级缓存、其他的API
持久化,将内存中的一个对象持久化到数据库的过程。Hibernate框架就是用来进行持久化的框架。
AlbertYang
2020/09/08
7050
SSH框架之Hibernate第二篇
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
海仔
2019/09/18
5250
[Java面试八]Hibernate总结以及在面试中的一些问题.
1.为什么要使用Hibernate开发你的项目呢?Hibernate的开发流程是怎么样的? 为什么要使用 ①.对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。
一枝花算不算浪漫
2018/05/18
1.6K0
day32_Hibernate学习笔记_04
  缓存(Cache):是计算机领域非常通用的概念。它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写硬盘(永久性数据存储源)的频率,从而提高应用的运行性能。缓存中的数据是数据存储源中数据的拷贝。缓存的物理介质通常是内存。   缓存:程序 <-- (内存) --> 硬盘
黑泽君
2018/10/11
9910
day32_Hibernate学习笔记_04
Hibernate_day03总结
Hibernate_day03总结 今日内容 l Hibernate的检索方式 l Hibernate的抓取策略 l Hibernate的批量检索 l 事务的并发问题 1.1 上次课内容回顾: Hibernate的持久类三种状态: * 瞬时态:没有唯一标识OID,没有被session管理 * 持久态:有唯一标识OID,被session管理 * 脱管态:有唯一标识OID,没有被session管理. * 状态转换: 瞬时态:new 获得. * 瞬时à持久:save/saveOrUpdate * 瞬时à脱管:
Java帮帮
2018/03/19
1.1K0
Hibernate_day03总结
Hibernate的入门(Hibernate的环境搭建、Hibernate的API)
Hibernate第一天(Hibernate的环境搭建、Hibernate的API、Hibernate的CRUD)
AlbertYang
2020/09/08
1.2K0
Hibernate的入门(Hibernate的环境搭建、Hibernate的API)
Hibernate第三天:Hibernate的一对多配置、Hibernate的多对多的配置
* * 前提:一对多的双方都设置cascade="save-update"
AlbertYang
2020/09/08
1.9K0
Hibernate第三天:Hibernate的一对多配置、Hibernate的多对多的配置
Hibernate_day01总结
第1章 Hibernate_day01总结 今日内容 Hibernate框架的概述 Hibernate的快速入门 Hibernate核心API的介绍 Hibernate的持久化类 主键的生成策略 1.
Java帮帮
2018/03/19
1.3K0
Hibernate_day01总结
day30_Hibernate学习笔记_02
对象状态 瞬时态|临时态:Transient     1、没有与Hibernate产生关联(没有与Session有关联)。     2、与数据库中的记录没有产生关联,即对象没有ID(有关联:就是与数据库中的ID有对应)。 持久态:Persistent     1、与Hibernate有关联(与session有关联)。     2、对象有ID。 游离态|脱管态:Detached     1、没有与Hibernate产生关联。     2、对象有ID。 三种状态转换如下图所示:
黑泽君
2018/10/11
1.1K0
day30_Hibernate学习笔记_02
hibernate笔记(一)
原始的jdbc操作, Connection/Statement/ResultSet
HUC思梦
2020/09/03
8270
day31_Hibernate学习笔记_03
在数据库表中如何表达多对多关系:   使用中间表,分别引用两方的ID。 在对象中如何表达多对多关系:   两方都使用集合表达。 在配置文件中如何表达一对多关系:
黑泽君
2018/10/11
2.5K0
day31_Hibernate学习笔记_03
Hibernate第四天:Hibernate的查询方式、抓取策略
在Hibernate中提供了很多种的查询的方式。Hibernate共提供了五种查询方式。
AlbertYang
2020/09/08
1.7K0
Hibernate第四天:Hibernate的查询方式、抓取策略
推荐阅读
相关推荐
Hibernate文件配置
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验