准备

模型及映射文件

package com.zze.bean;

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

public class Class {
    public Class() {
    }

    public Class(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    private Integer id;
    private String name;

    private Set<Student> students = new HashSet<>();

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<Student> getStudents() {
        return students;
    }

    public void setStudents(Set<Student> students) {
        this.students = students;
    }

    @Override
    public String toString() {
        return "Class{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

班级模型:com.zze.bean.Class

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="com.zze.bean.Class" table="class">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name" length="32"/>
        <set name="students" cascade="save-update">
            <key column="cid"/>
            <one-to-many class="com.zze.bean.Student"/>
        </set>
    </class>
</hibernate-mapping>

班级映射:com/zze/bean/Class.hbm.xml

package com.zze.bean;

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

public class Student {
    public Student() {
    }

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

    private Integer id;
    private String name;
    private Integer age;
    private String gender;

    private Class clazz;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public Class getClazz() {
        return clazz;
    }

    public void setClazz(Class clazz) {
        this.clazz = clazz;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

学生模型:com.zze.bean.Student

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="com.zze.bean.Student" table="student">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name" length="32"/>
        <property name="age"/>
        <property name="gender"/>
        <many-to-one name="clazz" column="cid" class="com.zze.bean.Class"/>
    </class>
</hibernate-mapping>

学生映射:com/zze/bean/Student.hbm.xml

全局配置

<?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="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://192.168.208.153:3306/1221</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">root</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
        <property name="current_session_context_class">thread</property>
        <property name="hibernate.hbm2ddl.auto">create</property>
        <mapping resource="com/zze/bean/Class.hbm.xml"></mapping>
        <mapping resource="com/zze/bean/Student.hbm.xml"></mapping>
    </session-factory>
</hibernate-configuration>

hibernate.cfg.xml

工具类

package com.zze.util;

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

public class HibernateUtil {
    public static final Configuration cfg;
    public static final SessionFactory sf;

    static {
        cfg = new Configuration().configure();
        sf = cfg.buildSessionFactory();
    }

    public static Session openSession() {
        return sf.openSession();
    }

    public static Session getCurrentSession() {
        return sf.getCurrentSession();
    }
}

com.zze.util.HibernateUtil

初始化数据

@Test
public void initData(){
    Session session = HibernateUtil.getCurrentSession();
    Transaction transaction = session.beginTransaction();
    Class clazz1 = new Class(null,"软件一班");
    Class clazz2 = new Class(null,"软件二班");
    Class clazz3 = new Class(null,"汽修一班");
    Class clazz4 = new Class(null,"汽修二班");

    Student student1 = new Student(null, "张三", 12,"男");
    Student student2 = new Student(null, "李四", 13,"女");
    Student student3 = new Student(null, "王五", 14,"男");
    Student student4 = new Student(null, "赵六", 15,"男");
    Student student5 = new Student(null, "吴刚", 39,"男");
    Student student6 = new Student(null, "王如花", 30,"女");
    Student student7 = new Student(null, "李志静", 49,"女");
    Student student8 = new Student(null, "何王天", 30,"男");

    clazz1.getStudents().add(student1);
    clazz1.getStudents().add(student2);
    clazz2.getStudents().add(student3);
    clazz2.getStudents().add(student4);
    clazz3.getStudents().add(student5);
    clazz3.getStudents().add(student6);
    clazz4.getStudents().add(student7);
    clazz4.getStudents().add(student8);

    session.save(clazz1);
    session.save(clazz2);
    session.save(clazz3);
    session.save(clazz4);
    transaction.commit();
}

init data

几种检索方式

OID检索

  • 简介

    Hibernate 根据对象的 OID(主键)进行检索。

  • 示例

    @Test
    public void test1(){
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Class clazz = session.get(Class.class, 1);
        System.out.println(clazz);
        transaction.commit();
        /*
        Hibernate:
            select
                class0_.id as id1_0_0_,
                class0_.name as name2_0_0_
            from
                class class0_
            where
                class0_.id=?
        Class{id=1, name='软件一班'}
         */
    }

    例 1:使用 get 方法

    @Test
    public void test2() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Class clazz = session.load(Class.class, 1);
        System.out.println(clazz);
        transaction.commit();
        /*
        Hibernate:
            select
                class0_.id as id1_0_0_,
                class0_.name as name2_0_0_
            from
                class class0_
            where
                class0_.id=?
        Class{id=1, name='软件一班'}
         */
    }

    例 2:使用 load 方法

对象导航检索

  • 简介

    Hibernate 根据一个已经查询到的对象,获得其关联的对象的一种查询方式。

  • 示例

    @Test
    public void test3(){
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Class clazz = session.load(Class.class, 1);
        System.out.println(clazz);
        System.out.println(Arrays.toString(clazz.getStudents().toArray()));
        transaction.commit();
        /*
        Hibernate:
            select
                class0_.id as id1_0_0_,
                class0_.name as name2_0_0_
            from
                class class0_
            where
                class0_.id=?
        Class{id=1, name='软件一班'}
        Hibernate:
            select
                students0_.cid as cid5_1_0_,
                students0_.id as id1_1_0_,
                students0_.id as id1_1_1_,
                students0_.name as name2_1_1_,
                students0_.age as age3_1_1_,
                students0_.gender as gender4_1_1_,
                students0_.cid as cid5_1_1_
            from
                student students0_
            where
                students0_.cid=?
        [Student{id=2, name='张三'}, Student{id=1, name='李四'}]
         */
    }

    例 3:

HQL检索

  • 简介

    Hibernate Language Query,Hibernate 本身提供语法支持的一种检索方式。

  • 示例

    /**
     * 查询所有班级
     */
    @Test
    public void test4(){
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        String hql  ="from Class";
        Query query = session.createQuery(hql);
        List<Class> list = query.list();
        System.out.println(list);
        transaction.commit();
        /*
        Hibernate:
            select
                class0_.id as id1_0_,
                class0_.name as name2_0_
            from
                class class0_
        [Class{id=1, name='软件一班'}, Class{id=2, name='软件二班'}, Class{id=3, name='汽修一班'}, Class{id=4, name='汽修二班'}]
         */
    }

    例 4:简单查询

    @Test
    public void test5(){
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        String hql  ="select c from Class c";
        Query query = session.createQuery(hql);
        List<Class> list = query.list();
        System.out.println(list);
        transaction.commit();
        /*
            Hibernate:
                select
                    class0_.id as id1_0_,
                    class0_.name as name2_0_
                from
                    class class0_
            [Class{id=1, name='软件一班'}, Class{id=2, name='软件二班'}, Class{id=3, name='汽修一班'}, Class{id=4, name='汽修二班'}]
         */
    }

    例 5:别名查询

    /**
     * 根据年龄排序
     */
    @Test
    public void test6(){
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        // 升序
        String hql = "from Student order by age";
        // 降序
        // String hql = "from Student order by age desc";
        Query query = session.createQuery(hql);
        List<Class> list = query.list();
        System.out.println(list);
        transaction.commit();
        /*
        Hibernate:
            select
                student0_.id as id1_1_,
                student0_.name as name2_1_,
                student0_.age as age3_1_,
                student0_.gender as gender4_1_,
                student0_.cid as cid5_1_
            from
                student student0_
            order by
                student0_.age
        [Student{id=2, name='张三'}, Student{id=1, name='李四'}, Student{id=3, name='王五'}, Student{id=4, name='赵六'}, Student{id=6, name='王如花'}, Student{id=8, name='何王天'}, Student{id=5, name='吴刚'}, Student{id=7, name='李志静'}]
         */
    }

    例 6:排序查询

    /**
     * 一个条件,查询 name='张三' 的 Student
     * 参数按位置绑定
     */
    @Test
    public void test7() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        String hql = "from Student where name = ?";
        Query query = session.createQuery(hql);
        query.setParameter(0, "张三");
        List<Student> list = query.list();
        System.out.println(list);
        transaction.commit();
        /*
        Hibernate:
            select
                student0_.id as id1_1_,
                student0_.name as name2_1_,
                student0_.age as age3_1_,
                student0_.gender as gender4_1_,
                student0_.cid as cid5_1_
            from
                student student0_
            where
                student0_.name=?
        [Student{id=2, name='张三'}]
         */
    }
    
    /**
     * 多个条件 查询 name 中包含 '王' 且 age 大于 18 的Student
     * 参数按名称绑定
     */
    @Test
    public void test8() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        String hql = "from Student where name like :name and age>:age";
        Query query = session.createQuery(hql);
        query.setParameter("name", "%王%");
        query.setParameter("age", 18);
        List<Student> list = query.list();
        System.out.println(list);
        transaction.commit();
        /*
        Hibernate:
            select
                student0_.id as id1_1_,
                student0_.name as name2_1_,
                student0_.age as age3_1_,
                student0_.gender as gender4_1_,
                student0_.cid as cid5_1_
            from
                student student0_
            where
                (
                    student0_.name like ?
                )
                and student0_.age>?
        [Student{id=6, name='王如花'}, Student{id=8, name='何王天'}]
         */
    }

    例 7:条件查询

    /**
     * 查询单个属性 返回 Object List
     */
    @Test
    public void test9() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        String hql = "select s.name from Student s";
        Query query = session.createQuery(hql);
        List<Object> list = query.list();
        System.out.println(list);
        transaction.commit();
    /*
    Hibernate:
        select
            student0_.name as col_0_0_
        from
            student student0_
    [李四, 张三, 王五, 赵六, 吴刚, 王如花, 李志静, 何王天]
     */
    }
    
    /**
     * 查询多个属性 返回 Object[] List
     */
    @Test
    public void test10() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        String hql = "select s.name,s.age from Student s";
        Query query = session.createQuery(hql);
        List<Object[]> list = query.list();
        for (Object[] objects : list) {
            System.out.println(Arrays.toString(objects));
        }
        transaction.commit();
        /*
        Hibernate:
            select
                student0_.name as col_0_0_,
                student0_.age as col_1_0_
            from
                student student0_
        [李四, 13]
        [张三, 12]
        [王五, 14]
        [赵六, 15]
        [吴刚, 39]
        [王如花, 30]
        [李志静, 49]
        [何王天, 30]
         */
    }
    
    /**
     * 查询多个属性 返回对应对象类型 List
     */
    @Test
    public void test11() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        /*
        需要让模型提供对应构造:
            public Student(String name, Integer age) {
                this.name = name;
                this.age = age;
            }
         */
        String hql = "select new Student(name,age) from Student";
        Query query = session.createQuery(hql);
        List<Student> list = query.list();
        System.out.println(list);
        transaction.commit();
        /*
        Hibernate:
            select
                student0_.name as col_0_0_,
                student0_.age as col_1_0_
            from
                student student0_
        [Student{id=null, name='李四'}, Student{id=null, name='张三'}, Student{id=null, name='王五'}, Student{id=null, name='赵六'}, Student{id=null, name='吴刚'}, Student{id=null, name='王如花'}, Student{id=null, name='李志静'}, Student{id=null, name='何王天'}]
         */
    }

    例 8:投影查询

    @Test
    public void test12() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        String hql = "from Student";
        Query query = session.createQuery(hql);
        query.setFirstResult(0); // 起始行索引
        query.setMaxResults(3); // 每页条数
        List<Student> list = query.list();
        System.out.println(list);
        transaction.commit();
        /*
        Hibernate:
            select
                student0_.id as id1_1_,
                student0_.name as name2_1_,
                student0_.age as age3_1_,
                student0_.gender as gender4_1_,
                student0_.cid as cid5_1_
            from
                student student0_ limit ?
        [Student{id=1, name='李四'}, Student{id=2, name='张三'}, Student{id=3, name='王五'}]
    
        Process finished with exit code 0
         */
    }

    例 9:分页查询

    /**
     * 聚合查询
     */
    @Test
    public void test13() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        // 聚合函数使用 count max min avg sum
        String hql = "select count(1) from Student";
        Query query = session.createQuery(hql);
        Object o = query.uniqueResult();
        System.out.println(o.getClass());
        System.out.println(o);
        transaction.commit();
        /*
        Hibernate:
            select
                count(1) as col_0_0_
            from
                student student0_
        class java.lang.Long
        8
         */
    }
    
    /**
     * 分组查询 返回 Object[] List
     * 根据 gender 分组,查询每个 gender 的对应数据条数
     */
    @Test
    public void test14() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        String hql = "select gender,count(1) from Student group by gender";
        Query query = session.createQuery(hql);
        List<Object[]> list = query.list();
        for (Object[] objects : list) {
            System.out.println(Arrays.toString(objects));
        }
        transaction.commit();
        /*
        Hibernate:
            select
                student0_.gender as col_0_0_,
                count(1) as col_1_0_
            from
                student student0_
            group by
                student0_.gender
        [女, 3]
        [男, 5]
         */
    }

    例 10:聚合及分组统计查询

    @Test
    public void test23() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        String hql = "from Student c join c.clazz";
        Query query = session.createQuery(hql);
        List<Object[]> list = query.list();
        for (Object[] objects : list) {
            System.out.println(Arrays.toString(objects));
        }
        transaction.commit();
        /*
        Hibernate:
            select
                student0_.id as id1_1_0_,
                class1_.id as id1_0_1_,
                student0_.name as name2_1_0_,
                student0_.age as age3_1_0_,
                student0_.gender as gender4_1_0_,
                student0_.cid as cid5_1_0_,
                class1_.name as name2_0_1_
            from
                student student0_
            inner join
                class class1_
                    on student0_.cid=class1_.id
        [Student{id=1, name='李四'}, Class{id=1, name='软件一班'}]
        [Student{id=2, name='张三'}, Class{id=1, name='软件一班'}]
        [Student{id=3, name='王五'}, Class{id=2, name='软件二班'}]
        [Student{id=4, name='赵六'}, Class{id=2, name='软件二班'}]
        [Student{id=5, name='吴刚'}, Class{id=3, name='汽修一班'}]
        [Student{id=6, name='王如花'}, Class{id=3, name='汽修一班'}]
        [Student{id=7, name='李志静'}, Class{id=4, name='汽修二班'}]
        [Student{id=8, name='何王天'}, Class{id=4, name='汽修二班'}]
         */
    }

    例 11:普通内连接

    /**
     * 查询所有学生及其班级
     */
    @Test
    public void test24() {
        /*
        迫切内连接
        其实就是在普通的内连接 inner join 后添加关键字 fetch
        将关联表数据封装到查询对象的属性中
         */
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        String hql = "from Student c join fetch c.clazz";
        Query query = session.createQuery(hql);
        List<Student> list = query.list();
        for (Student student : list) {
            System.out.println(String.format("%s %s", student, student.getClazz()));
        }
        transaction.commit();
        /*
        Hibernate:
            select
                student0_.id as id1_1_0_,
                class1_.id as id1_0_1_,
                student0_.name as name2_1_0_,
                student0_.age as age3_1_0_,
                student0_.gender as gender4_1_0_,
                student0_.cid as cid5_1_0_,
                class1_.name as name2_0_1_
            from
                student student0_
            inner join
                class class1_
                    on student0_.cid=class1_.id
        Student{id=1, name='李四'} Class{id=1, name='软件一班'}
        Student{id=2, name='张三'} Class{id=1, name='软件一班'}
        Student{id=3, name='王五'} Class{id=2, name='软件二班'}
        Student{id=4, name='赵六'} Class{id=2, name='软件二班'}
        Student{id=5, name='吴刚'} Class{id=3, name='汽修一班'}
        Student{id=6, name='王如花'} Class{id=3, name='汽修一班'}
        Student{id=7, name='李志静'} Class{id=4, name='汽修二班'}
        Student{id=8, name='何王天'} Class{id=4, name='汽修二班'}
         */
    }
    
    /**
     * 查询所有班级及属于该班级的学生
     */
    @Test
    public void test25() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        String hql = "select distinct c from Class c join fetch c.students";
        Query query = session.createQuery(hql);
        List<Class> list = query.list();
        for (Class clazz : list) {
            System.out.println(String.format("%s %s", clazz, clazz.getStudents()));
        }
        transaction.commit();
        /*
        Class{id=1, name='软件一班'} [Student{id=2, name='张三'}, Student{id=1, name='李四'}]
        Class{id=2, name='软件二班'} [Student{id=4, name='赵六'}, Student{id=3, name='王五'}]
        Class{id=3, name='汽修一班'} [Student{id=5, name='吴刚'}, Student{id=6, name='王如花'}]
        Class{id=4, name='汽修二班'} [Student{id=7, name='李志静'}, Student{id=8, name='何王天'}]
         */
    }

    例 12:迫切内连接

QBC检索

  • 简介

    Query By Criteria,条件查询,是一种更加面向对象化的查询方式。

  • 示例

    @Test
    public void test15(){
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Criteria criteria = session.createCriteria(Class.class);
        List<Class> list = criteria.list();
        System.out.println(list);
        transaction.commit();
        /*
        Hibernate:
            select
                this_.id as id1_0_0_,
                this_.name as name2_0_0_
            from
                class this_
        [Class{id=1, name='软件一班'}, Class{id=2, name='软件二班'}, Class{id=3, name='汽修一班'}, Class{id=4, name='汽修二班'}]
         */
    }

    例 13:简单查询

    @Test
    public void test16(){
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Criteria criteria = session.createCriteria(Class.class);
        // 升序
        criteria.addOrder(Order.asc("id"));
        // 降序
        // criteria.addOrder(Order.desc("id"));
        List<Class> list = criteria.list();
        System.out.println(list);
        transaction.commit();
        /*
        Hibernate:
            select
                this_.id as id1_0_0_,
                this_.name as name2_0_0_
            from
                class this_
            order by
                this_.id asc
        [Class{id=1, name='软件一班'}, Class{id=2, name='软件二班'}, Class{id=3, name='汽修一班'}, Class{id=4, name='汽修二班'}]
         */
    }

    例 14:排序查询

    @Test
    public void test17() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Criteria criteria = session.createCriteria(Student.class);
        criteria.setFirstResult(0); // 数据起始索引
        criteria.setMaxResults(2); // 每页数据条数
        List<Student> list = criteria.list();
        System.out.println(list);
        transaction.commit();
        /*
        Hibernate:
            select
                this_.id as id1_1_0_,
                this_.name as name2_1_0_,
                this_.age as age3_1_0_,
                this_.gender as gender4_1_0_,
                this_.cid as cid5_1_0_
            from
                student this_ limit ?
        [Student{id=1, name='李四'}, Student{id=2, name='张三'}]
         */
    }

    例 15:分页查询

    /**
     * 简单 and 条件查询
     * 查询 name 包含 '王' 且 age>10
     */
    @Test
    public void test18() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Criteria criteria = session.createCriteria(Student.class);
        // 默认多个 criteria.add 的条件是用 and 连接
        criteria.add(Restrictions.like("name", "%王%"));
        criteria.add(Restrictions.gt("age", 10));
        List<Student> list = criteria.list();
        System.out.println(list);
        transaction.commit();
        /*
        Hibernate:
            select
                this_.id as id1_1_0_,
                this_.name as name2_1_0_,
                this_.age as age3_1_0_,
                this_.gender as gender4_1_0_,
                this_.cid as cid5_1_0_
            from
                student this_
            where
                this_.name like ?
                and this_.age>?
        [Student{id=3, name='王五'}, Student{id=6, name='王如花'}, Student{id=8, name='何王天'}]
         */
    }
    
    /**
     * 简单 or 条件查询
     * 查询 name 包含 '王' 或 name 包含 '张'
     */
    @Test
    public void test19() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Criteria criteria = session.createCriteria(Student.class);
        // or 条件可以通过 Restrictions.or 方法实现
        criteria.add(Restrictions.or(Restrictions.like("name", "%王%"), Restrictions.like("name", "%张%")));
        List<Student> list = criteria.list();
        System.out.println(list);
        transaction.commit();
    
        /*
        Hibernate:
            select
                this_.id as id1_1_0_,
                this_.name as name2_1_0_,
                this_.age as age3_1_0_,
                this_.gender as gender4_1_0_,
                this_.cid as cid5_1_0_
            from
                student this_
            where
                (
                    this_.name like ?
                    or this_.name like ?
                )
        [Student{id=2, name='张三'}, Student{id=3, name='王五'}, Student{id=6, name='王如花'}, Student{id=8, name='何王天'}]
         */
    }
    
    /**
     * 复杂 and 和 or 查询
     * 查询 (name 包含 '王' 且 age>10) 或 name 包含 '张'
     */
    @Test
    public void test20() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Criteria criteria = session.createCriteria(Student.class);
        // 通过 conjunction.add 添加的条件是 and 连接
        Conjunction conjunction = Restrictions.conjunction();
        conjunction.add(Restrictions.like("name", "%王%"));
        conjunction.add(Restrictions.gt("age", 10));
        // 通过 disjunction.add 添加的条件是 or 连接
        Disjunction disjunction = Restrictions.disjunction();
        disjunction.add(conjunction);
        disjunction.add(Restrictions.like("name", "%张%"));
        criteria.add(disjunction);
        List<Student> list = criteria.list();
        System.out.println(list);
        transaction.commit();
        /*
        Hibernate:
            select
                this_.id as id1_1_0_,
                this_.name as name2_1_0_,
                this_.age as age3_1_0_,
                this_.gender as gender4_1_0_,
                this_.cid as cid5_1_0_
            from
                student this_
            where
                (
                    (
                        this_.name like ?
                        and this_.age>?
                    )
                    or this_.name like ?
                )
        [Student{id=2, name='张三'}, Student{id=3, name='王五'}, Student{id=6, name='王如花'}, Student{id=8, name='何王天'}]
         */
    }

    例 16:条件查询

    /**
     * 聚合统计查询
     * 统计男女人数及最大年龄
     */
    @Test
    public void test21() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Criteria criteria = session.createCriteria(Student.class);
        /*
        criteria :
            add : 普通条件,where
            addOrder : 排序
            setProjection : 聚合函数和 group by having
         */
        ProjectionList projectionList = Projections.projectionList();
        projectionList.add(Projections.groupProperty("gender"));
        projectionList.add(Projections.rowCount());
        projectionList.add(Projections.max("age"));
        criteria.setProjection(projectionList);
    
        List<Object[]> list = criteria.list();
        for (Object[] objects : list) {
            System.out.println(Arrays.toString(objects));
        }
        transaction.commit();
        /*
        Hibernate:
            select
                this_.gender as y0_,
                count(*) as y1_,
                max(this_.age) as y2_
            from
                student this_
            group by
                this_.gender
        [女, 3, 49]
        [男, 5, 39]
         */
    }

    例 17:聚合及分组统计查询

    /**
     * 离线条件查询
     * 查询 name 包含 '一'
     */
    @Test
    public void test22(){
        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Class.class);
        detachedCriteria.add(Restrictions.like("name", "%一%"));
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Criteria criteria = detachedCriteria.getExecutableCriteria(session);
        List<Class> list = criteria.list();
        System.out.println(list);
        transaction.commit();
        /*
        Hibernate:
            select
                this_.id as id1_0_0_,
                this_.name as name2_0_0_
            from
                class this_
            where
                this_.name like ?
        [Class{id=1, name='软件一班'}, Class{id=3, name='汽修一班'}]
         */
    }

    例 18:离线条件查询

SQL检索

  • 简介

    Hibernate 支持的原生 SQL 查询。

  • 示例

    /**
     * 查询所有 Class,返回 Object[] List
     */
    @Test
    public void test26() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        String sql = "select * from class";
        SQLQuery sqlQuery = session.createSQLQuery(sql);
        List<Object[]> list = sqlQuery.list();
        for (Object[] objects : list) {
            System.out.println(Arrays.toString(objects));
        }
        transaction.commit();
        /*
        Hibernate:
            select
                *
            from
                class
        [1, 软件一班]
        [2, 软件二班]
        [3, 汽修一班]
        [4, 汽修二班]
         */
    }
    
    /**
     * 查询所有 Class,返回 Class List
     */
    @Test
    public void test27() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        String sql = "select * from class";
        SQLQuery sqlQuery = session.createSQLQuery(sql);
        sqlQuery.addEntity(Class.class);
        List<Class> list = sqlQuery.list();
        for (Class clazz : list) {
            System.out.println(clazz);
        }
        transaction.commit();
        /*
        Hibernate:
            select
                *
            from
                class
        Class{id=1, name='软件一班'}
        Class{id=2, name='软件二班'}
        Class{id=3, name='汽修一班'}
        Class{id=4, name='汽修二班'}
         */
    }

    例 19:原生 SQL 查询

延迟加载

概述

只有真正使用对象的属性时才会发送 SQL 进行查询。如: session.load(Student.class,1); 。

分类

  • 类级别的延迟加载

    指的是查询某个类的对象时,针对这个类的对象是否使用延迟加载。

    除了修改 lazy="false" 这种方式,还可通过如下两种方式让 lazy 失效:

    1、将持久化类以 final 修饰。

    2、通过调用 Hibernate.initialize(proxy); 。

  • 关联级别的延迟加载

    指的是查询到某个对象后,再查询其关联的对象是否使用延迟加载。

示例

/**
 * 懒加载
 * 修改映射文件 :
 * com/zze/bean/Class.hbm.xml :
 * <class name="com.zze.bean.Class" table="class" lazy="true">
 * lazy 默认为 true
 */
@Test
public void test27() {
    Session session = HibernateUtil.getCurrentSession();
    Transaction transaction = session.beginTransaction();
    Class clazz = session.load(Class.class, 1);
    System.out.println(clazz.getClass()); // class com.zze.bean.Class_$$_jvst718_0
    System.out.println(clazz); // 发出 SQL
    transaction.commit();
}

/**
 * 立即加载
 * 修改映射文件 :
 * com/zze/bean/Class.hbm.xml :
 * <class name="com.zze.bean.Class" table="class" lazy="false">
 */
@Test
public void test28() {
    Session session = HibernateUtil.getCurrentSession();
    Transaction transaction = session.beginTransaction();
    Class clazz = session.load(Class.class, 1); // 发出 SQL
    System.out.println(clazz.getClass()); // class com.zze.bean.Class
    System.out.println(clazz);
    transaction.commit();
}

例 20:类级别的延迟加载

/**
 * 懒加载
 * 修改映射文件 :
 * com/zze/bean/Class.hbm.xml :
 * <set name="students" cascade="save-update" lazy="true">
 * lazy 默认为 true
 */
@Test
public void test29() {
    Session session = HibernateUtil.getCurrentSession();
    Transaction transaction = session.beginTransaction();
    Class clazz = session.get(Class.class, 1);
    Set<Student> students = clazz.getStudents();
    System.out.println(students); // 发出 SQL
    transaction.commit();
}

/**
 * 即时加载
 * 修改映射文件 :
 * com/zze/bean/Class.hbm.xml :
 * <set name="students" cascade="save-update" lazy="false">
 */
@Test
public void test30() {
    Session session = HibernateUtil.getCurrentSession();
    Transaction transaction = session.beginTransaction();
    Class clazz = session.get(Class.class, 1);
    Set<Student> students = clazz.getStudents(); // 发出 SQL
    System.out.println(students);
    transaction.commit();
}

/**
 * 懒加载
 * 修改映射文件 :
 * com/zze/bean/Student.hbm.xml :
 * <many-to-one name="clazz" lazy="proxy" column="cid" class="com.zze.bean.Class"/>
 * com/zze/bean/Class.hbm.xml :
 * <class name="com.zze.bean.Class" table="class" lazy="true">
 * <p>
 * proxy : 默认值,表示引用关联类的加载策略。
 */
@Test
public void test31() {
    Session session = HibernateUtil.getCurrentSession();
    Transaction transaction = session.beginTransaction();
    Student student = session.get(Student.class, 1);
    Class clazz = student.getClazz();
    System.out.println(clazz); // 发出 SQL
    transaction.commit();
}

/**
 * 即时加载
 * 当关联类的 lazy="false" 时,无论当前类 many-to-one 标签上的 lazy 如何配置,都是即时加载。
 * 修改映射文件 :
 * com/zze/bean/Student.hbm.xml :
 * * <many-to-one name="clazz" lazy="proxy" column="cid" class="com.zze.
 * com/zze/bean/Class.hbm.xml :
 * * <class name="com.zze.bean.Class" table="class" lazy="false">
 * 或 :
 * com/zze/bean/Student.hbm.xml :
 * * <many-to-one name="clazz" lazy="false" column="cid" class="com.zze.bean.Class"/>
 * com/zze/bean/Class.hbm.xml :
 * * <class name="com.zze.bean.Class" table="class" lazy="true">
 */
@Test
public void test32() {
    Session session = HibernateUtil.getCurrentSession();
    Transaction transaction = session.beginTransaction();
    Student student = session.get(Student.class, 1);
    Class clazz = student.getClazz(); // 发出 SQL
    System.out.println(clazz);
    transaction.commit();
}

例 21:关联级别的延迟加载

抓取策略

概述

通过一个对象抓取关联对象需要发送 SQL ,SQL 如何发送及 SQL 的发送规则就可以通过抓取策略进行配置。

通过 <set> 或 <many-to-one> 上的 fetch 属性进行配置。

要考虑fetch 和这些标签上的 lazy 如何配置才能最大化优化发送的 SQL 语句。

set标签上的fetch和lazy

  • fetch

    抓取策略,控制 SQL 语句格式。

    在这里 fetch 有三个可选值:

    select : 默认值,发送普通 select 语句查询关联对象。

    join: 发送一条迫切左外连接查询关联对象。

    subselect : 发送子查询查询关联对象。

  • lazy

    延迟加载,控制查询关联对象时是否使用懒加载。

    在这里 lazy 有三个可选值:

    true : 默认值,查询关联对象时,使用延迟加载。

    false : 查询关联对象时,不使用延迟加载。

    extra : 及其懒惰。

  • 示例

    /**
     * com/zze/bean/Class.hbm.xml
     * 默认值:
     * <set name="students" cascade="save-update" fetch="select" lazy="true">
     */
    @Test
    public void test33() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Class clazz = session.get(Class.class, 1);
        for (Student student : clazz.getStudents()) {
            System.out.println(student);// 发送 SQL
        }
        transaction.commit();
        /*
        Hibernate:
            select
                class0_.id as id1_0_0_,
                class0_.name as name2_0_0_
            from
                class class0_
            where
                class0_.id=?
        Hibernate:
            select
                students0_.cid as cid5_1_0_,
                students0_.id as id1_1_0_,
                students0_.id as id1_1_1_,
                students0_.name as name2_1_1_,
                students0_.age as age3_1_1_,
                students0_.gender as gender4_1_1_,
                students0_.cid as cid5_1_1_
            from
                student students0_
            where
                students0_.cid=?
        Student{id=2, name='张三'}
        Student{id=1, name='李四'}
         */
    }
    
    /**
     * com/zze/bean/Class.hbm.xml
     *
     * <set name="students" cascade="save-update" fetch="select" lazy="false">
     */
    @Test
    public void test34() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Class clazz = session.get(Class.class, 1); //发送 2 条 SQL
        for (Student student : clazz.getStudents()) {
            System.out.println(student);
        }
        transaction.commit();
        /*
        Hibernate:
            select
                class0_.id as id1_0_0_,
                class0_.name as name2_0_0_
            from
                class class0_
            where
                class0_.id=?
        Hibernate:
            select
                students0_.cid as cid5_1_0_,
                students0_.id as id1_1_0_,
                students0_.id as id1_1_1_,
                students0_.name as name2_1_1_,
                students0_.age as age3_1_1_,
                students0_.gender as gender4_1_1_,
                students0_.cid as cid5_1_1_
            from
                student students0_
            where
                students0_.cid=?
        Student{id=2, name='张三'}
        Student{id=1, name='李四'}
         */
    }
    
    /**
     * com/zze/bean/Class.hbm.xml
     *
     * <set name="students" cascade="save-update" fetch="select" lazy="extra">
     */
    @Test
    public void test35() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Class clazz = session.get(Class.class, 1);
        System.out.println(clazz.getStudents().size()); // 针对数量发送一条sql
        transaction.commit();
        /*
        Hibernate:
            select
                class0_.id as id1_0_0_,
                class0_.name as name2_0_0_
            from
                class class0_
            where
                class0_.id=?
        Hibernate:
            select
                count(id)
            from
                student
            where
                cid =?
         */
    }
    
    /**
     * com/zze/bean/Class.hbm.xml
     * fetch="join" 时,lazy 失效
     * <set name="students" cascade="save-update" fetch="join" lazy="true">
     */
    public void test36() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Class clazz = session.get(Class.class, 1);// 发送 SQL
        for (Student student : clazz.getStudents()) {
            System.out.println(student);
        }
        transaction.commit();
        /*
        Hibernate:
            select
                class0_.id as id1_0_0_,
                class0_.name as name2_0_0_,
                students1_.cid as cid5_1_1_,
                students1_.id as id1_1_1_,
                students1_.id as id1_1_2_,
                students1_.name as name2_1_2_,
                students1_.age as age3_1_2_,
                students1_.gender as gender4_1_2_,
                students1_.cid as cid5_1_2_
            from
                class class0_
            left outer join
                student students1_
                    on class0_.id=students1_.cid
            where
                class0_.id=?
        Student{id=2, name='张三'}
        Student{id=1, name='李四'}
         */
    }
    
    /**
     * com/zze/bean/Class.hbm.xml
     *
     * <set name="students" cascade="save-update" fetch="subselect" lazy="true">
     */
    @Test
    public void test37() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Query query = session.createQuery("from Class");
        List<Class> list = query.list();
        for (Class clazz : list) {
            Set<Student> students = clazz.getStudents(); // 发送 SQL
            System.out.println(students);
        }
        transaction.commit();
        /*
        Hibernate:
            select
                class0_.id as id1_0_,
                class0_.name as name2_0_
            from
                class class0_
        Hibernate:
            select
                students0_.cid as cid5_1_1_,
                students0_.id as id1_1_1_,
                students0_.id as id1_1_0_,
                students0_.name as name2_1_0_,
                students0_.age as age3_1_0_,
                students0_.gender as gender4_1_0_,
                students0_.cid as cid5_1_0_
            from
                student students0_
            where
                students0_.cid in (
                    select
                        class0_.id
                    from
                        class class0_
                )
        [Student{id=1, name='李四'}, Student{id=2, name='张三'}]
        [Student{id=4, name='赵六'}, Student{id=3, name='王五'}]
        [Student{id=5, name='吴刚'}, Student{id=6, name='王如花'}]
        [Student{id=7, name='李志静'}, Student{id=8, name='何王天'}]
         */
    }
    
    /**
     * com/zze/bean/Class.hbm.xml
     *
     * <set name="students" cascade="save-update" fetch="subselect" lazy="false">
     */
    @Test
    public void test38() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Query query = session.createQuery("from Class");
        List<Class> list = query.list(); // 发送 SQL
        for (Class clazz : list) {
            Set<Student> students = clazz.getStudents();
            System.out.println(students);
        }
        transaction.commit();
        /*
        Hibernate:
            select
                class0_.id as id1_0_,
                class0_.name as name2_0_
            from
                class class0_
        Hibernate:
            select
                students0_.cid as cid5_1_1_,
                students0_.id as id1_1_1_,
                students0_.id as id1_1_0_,
                students0_.name as name2_1_0_,
                students0_.age as age3_1_0_,
                students0_.gender as gender4_1_0_,
                students0_.cid as cid5_1_0_
            from
                student students0_
            where
                students0_.cid in (
                    select
                        class0_.id
                    from
                        class class0_
                )
        [Student{id=1, name='李四'}, Student{id=2, name='张三'}]
        [Student{id=4, name='赵六'}, Student{id=3, name='王五'}]
        [Student{id=5, name='吴刚'}, Student{id=6, name='王如花'}]
        [Student{id=7, name='李志静'}, Student{id=8, name='何王天'}]
         */
    }

    例 22:

many-to-one上的fetch和lazy

  • fetch

    抓取策略,控制 SQL 语句格式。

    在这里 fetch 有两个可选值:

    select : 默认值,发送普通的 select 语句查询关联对象。

    join : 发送一条迫切左外连接查询关联对象。

  • lazy

    延迟加载,控制查询关联对象时是否使用懒加载。

    在这里 lazy 有三个可选值:

    proxy : 默认值,引用关联对象类的类级别加载策略。

    flase : 查询关联对象时,不使用延迟加载。

    no-proxy:不使用。

  • 示例

    /**
     * com/zze/bean/Student.hbm.xml
     * 默认值
     * <many-to-one name="clazz" column="cid" class="com.zze.bean.Class" fetch="select" lazy="proxy"/>
     *
     * com/zze/bean/Class.hbm.xml
     * <class name="com.zze.bean.Class" table="class" lazy="true">
     */
    @Test
    public void test39(){
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Student student = session.get(Student.class, 1);
        System.out.println(student.getClazz()); // 发送 SQL
        transaction.commit();
        /*
        Hibernate:
            select
                student0_.id as id1_1_0_,
                student0_.name as name2_1_0_,
                student0_.age as age3_1_0_,
                student0_.gender as gender4_1_0_,
                student0_.cid as cid5_1_0_
            from
                student student0_
            where
                student0_.id=?
        Hibernate:
            select
                class0_.id as id1_0_0_,
                class0_.name as name2_0_0_
            from
                class class0_
            where
                class0_.id=?
        Class{id=1, name='软件一班'}
         */
    }
    
    /**
     * com/zze/bean/Student.hbm.xml
     * 默认值
     * <many-to-one name="clazz" column="cid" class="com.zze.bean.Class" fetch="select" lazy="proxy"/>
     *
     * com/zze/bean/Class.hbm.xml
     * <class name="com.zze.bean.Class" table="class" lazy="false">
     */
    @Test
    public void test40(){
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Student student = session.get(Student.class, 1);// 一次发送 2 条 SQL
        System.out.println(student.getClazz());
        transaction.commit();
        /*
        Hibernate:
            select
                student0_.id as id1_1_0_,
                student0_.name as name2_1_0_,
                student0_.age as age3_1_0_,
                student0_.gender as gender4_1_0_,
                student0_.cid as cid5_1_0_
            from
                student student0_
            where
                student0_.id=?
        Hibernate:
            select
                class0_.id as id1_0_0_,
                class0_.name as name2_0_0_
            from
                class class0_
            where
                class0_.id=?
        Class{id=1, name='软件一班'}
         */
    }
    
    /**
     * com/zze/bean/Student.hbm.xml
     * fetch="join" 时,lazy 失效
     * <many-to-one name="clazz" column="cid" class="com.zze.bean.Class" fetch="join" lazy="proxy"/>
     */
    @Test
    public void test41(){
        Session session = HibernateUtil.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Student student = session.get(Student.class, 1);// 一条关联 SQL
        System.out.println(student.getClazz());
        transaction.commit();
        /*
        Hibernate:
            select
                student0_.id as id1_1_0_,
                student0_.name as name2_1_0_,
                student0_.age as age3_1_0_,
                student0_.gender as gender4_1_0_,
                student0_.cid as cid5_1_0_,
                class1_.id as id1_0_1_,
                class1_.name as name2_0_1_
            from
                student student0_
            left outer join
                class class1_
                    on student0_.cid=class1_.id
            where
                student0_.id=?
        Class{id=1, name='软件一班'}
         */
    }

    例 23:

批量抓取

一批指定数量的关联数据一起查询。

/**
 * 查询所有班级 及 所有班级下的学生信息
 * 默认情况下,查询所有班级会发一条 SQL,然后每次查询班级上的学生也会发送一条 SQL
 * 即如下有 4 个班级,会发 5 条SQL
 */
@Test
public void test42() {
    Session session = HibernateUtil.getCurrentSession();
    Transaction transaction = session.beginTransaction();
    Query query = session.createQuery("from Class");
    List<Class> list = query.list();
    for (Class clazz : list) {
        System.out.println(clazz);
        for (Student student : clazz.getStudents()) {
            System.out.println(student);
        }
    }
    transaction.commit();
    /*
    Hibernate:
        select
            class0_.id as id1_0_,
            class0_.name as name2_0_
        from
            class class0_
    Class{id=1, name='软件一班'}
    Hibernate:
        select
            students0_.cid as cid5_1_0_,
            students0_.id as id1_1_0_,
            students0_.id as id1_1_1_,
            students0_.name as name2_1_1_,
            students0_.age as age3_1_1_,
            students0_.gender as gender4_1_1_,
            students0_.cid as cid5_1_1_
        from
            student students0_
        where
            students0_.cid=?
    Student{id=1, name='李四'}
    Student{id=2, name='张三'}
    Class{id=2, name='软件二班'}
    Hibernate:
        select
            students0_.cid as cid5_1_0_,
            students0_.id as id1_1_0_,
            students0_.id as id1_1_1_,
            students0_.name as name2_1_1_,
            students0_.age as age3_1_1_,
            students0_.gender as gender4_1_1_,
            students0_.cid as cid5_1_1_
        from
            student students0_
        where
            students0_.cid=?
    Student{id=4, name='王五'}
    Student{id=3, name='赵六'}
    Class{id=3, name='汽修一班'}
    Hibernate:
        select
            students0_.cid as cid5_1_0_,
            students0_.id as id1_1_0_,
            students0_.id as id1_1_1_,
            students0_.name as name2_1_1_,
            students0_.age as age3_1_1_,
            students0_.gender as gender4_1_1_,
            students0_.cid as cid5_1_1_
        from
            student students0_
        where
            students0_.cid=?
    Student{id=5, name='王如花'}
    Student{id=6, name='吴刚'}
    Class{id=4, name='汽修二班'}
    Hibernate:
        select
            students0_.cid as cid5_1_0_,
            students0_.id as id1_1_0_,
            students0_.id as id1_1_1_,
            students0_.name as name2_1_1_,
            students0_.age as age3_1_1_,
            students0_.gender as gender4_1_1_,
            students0_.cid as cid5_1_1_
        from
            student students0_
        where
            students0_.cid=?
    Student{id=8, name='李志静'}
    Student{id=7, name='何王天'}
     */
}

/**
 * com/zze/bean/Class.hbm.xml
 *
 * <set name="students" cascade="save-update" batch-size="4">
 * <p>
 * 一次抓取 4 条,就只需要发送 2 次 SQL
 * 一次查询所有班级,一次查询所有班级下的学生
 */
@Test
public void test43() {
    Session session = HibernateUtil.getCurrentSession();
    Transaction transaction = session.beginTransaction();
    Query query = session.createQuery("from Class");
    List<Class> list = query.list();
    for (Class clazz : list) {
        System.out.println(clazz);
        for (Student student : clazz.getStudents()) {
            System.out.println(student);
        }
    }
    transaction.commit();
    /*
    Hibernate:
        select
            class0_.id as id1_0_,
            class0_.name as name2_0_
        from
            class class0_
    Class{id=1, name='软件一班'}
    Hibernate:
        select
            students0_.cid as cid5_1_1_,
            students0_.id as id1_1_1_,
            students0_.id as id1_1_0_,
            students0_.name as name2_1_0_,
            students0_.age as age3_1_0_,
            students0_.gender as gender4_1_0_,
            students0_.cid as cid5_1_0_
        from
            student students0_
        where
            students0_.cid in (
                ?, ?, ?, ?
            )
    Student{id=1, name='李四'}
    Student{id=2, name='张三'}
    Class{id=2, name='软件二班'}
    Student{id=4, name='王五'}
    Student{id=3, name='赵六'}
    Class{id=3, name='汽修一班'}
    Student{id=5, name='王如花'}
    Student{id=6, name='吴刚'}
    Class{id=4, name='汽修二班'}
    Student{id=7, name='何王天'}
    Student{id=8, name='李志静'}
     */
}

/**
 * 查询所有学生 及 所有学生所属班级信息
 * 默认情况下,查询所有学生会发送 1 条 SQL,然后每次查询每个学生的所属班级时也会发送一条 SQL,
 * 有 8 个学生,但一共有 4 个班级,由于一级缓存的作用,查询班级需要发送 4 条 SQL
 * 共发 5 条 SQL
 */
@Test
public void test44() {
    Session session = HibernateUtil.getCurrentSession();
    Transaction transaction = session.beginTransaction();
    Query query = session.createQuery("from Student");
    List<Student> list = query.list();
    for (Student student : list) {
        System.out.println(student.getClazz());
    }
    transaction.commit();
    /*
    Hibernate:
        select
            student0_.id as id1_1_,
            student0_.name as name2_1_,
            student0_.age as age3_1_,
            student0_.gender as gender4_1_,
            student0_.cid as cid5_1_
        from
            student student0_
    Hibernate:
        select
            class0_.id as id1_0_0_,
            class0_.name as name2_0_0_
        from
            class class0_
        where
            class0_.id=?
    Class{id=1, name='软件一班'}
    Class{id=1, name='软件一班'}
    Hibernate:
        select
            class0_.id as id1_0_0_,
            class0_.name as name2_0_0_
        from
            class class0_
        where
            class0_.id=?
    Class{id=2, name='软件二班'}
    Class{id=2, name='软件二班'}
    Hibernate:
        select
            class0_.id as id1_0_0_,
            class0_.name as name2_0_0_
        from
            class class0_
        where
            class0_.id=?
    Class{id=3, name='汽修一班'}
    Class{id=3, name='汽修一班'}
    Hibernate:
        select
            class0_.id as id1_0_0_,
            class0_.name as name2_0_0_
        from
            class class0_
        where
            class0_.id=?
    Class{id=4, name='汽修二班'}
    Class{id=4, name='汽修二班'}
     */
}

/**
 * com/zze/bean/Class.hbm.xml
 * <class name="com.zze.bean.Class" table="class" batch-size="3">
 * <p>
 * many-to-one 关系时需在关联属性类映射文件下配置 batch-size
 * <p>
 * 查询所有学生 1 条 SQL,查询所有班级每次抓取 3 条,一共 4 个班级,会发 2 次 SQL
 */
@Test
public void test45() {
    Session session = HibernateUtil.getCurrentSession();
    Transaction transaction = session.beginTransaction();
    Query query = session.createQuery("from Student");
    List<Student> list = query.list();
    for (Student student : list) {
        System.out.println(student.getClazz());
    }
    transaction.commit();
    /*
    Hibernate:
        select
            student0_.id as id1_1_,
            student0_.name as name2_1_,
            student0_.age as age3_1_,
            student0_.gender as gender4_1_,
            student0_.cid as cid5_1_
        from
            student student0_
    Hibernate:
        select
            class0_.id as id1_0_0_,
            class0_.name as name2_0_0_
        from
            class class0_
        where
            class0_.id in (
                ?, ?, ?
            )
    Class{id=1, name='软件一班'}
    Class{id=1, name='软件一班'}
    Class{id=2, name='软件二班'}
    Class{id=2, name='软件二班'}
    Class{id=3, name='汽修一班'}
    Class{id=3, name='汽修一班'}
    Hibernate:
        select
            class0_.id as id1_0_0_,
            class0_.name as name2_0_0_
        from
            class class0_
        where
            class0_.id=?
    Class{id=4, name='汽修二班'}
    Class{id=4, name='汽修二班'}
     */
}

例 24:

java框架之Hibernate(4)-几种检索方式的更多相关文章

  1. java框架篇---spring aop两种配置方式

    第一种:注解配置AOP 注解配置AOP(使用 AspectJ 类库实现的),大致分为三步: 1. 使用注解@Aspect来定义一个切面,在切面中定义切入点(@Pointcut),通知类型(@Befor ...

  2. Hibernate基础学习(七)—检索方式

    一.概述      Hibernate有五种检索方式. 1.导航对象图检索方式      根据已经加载的对象,导航到其他对象. Order order = (Order)session.get(Ord ...

  3. Java使用SFTP和FTP两种连接方式实现对服务器的上传下载 【我改】

    []如何区分是需要使用SFTP还是FTP? []我觉得: 1.看是否已知私钥. SFTP 和 FTP 最主要的区别就是 SFTP 有私钥,也就是在创建连接对象时,SFTP 除了用户名和密码外还需要知道 ...

  4. Java连接Oracle数据库的三种连接方式

    背景: 这两天在学习Oracle数据库,这里就总结下自己上课所学的知识,同时记录下来,方便整理当天所学下的知识,也同时方便日后自己查询. SQL语句的话,这里我就不多讲了,感觉和其他的数据库(MySQ ...

  5. hibernate的三种查询方式

    hibernate的三种查询方式 目录 hibernate的三种查询方式 1.HQL查询 1.1.SQL概述 1.2.实体查询 1.3.带where的查询 1.3.属性查询 1.4.实体的更新和删除 ...

  6. java框架之Hibernate(2)-持久化类&主键生成策略&缓存&事务&查询

    持久化类 概述 持久化:将内存中的对象持久化到数据库中的过程就是持久化.Hibernate 就是用来进行持久化的框架. 持久化类:一个 Java 对象与数据库的表建立了映射关系,那么这个类在 Hibe ...

  7. java框架篇---hibernate入门

    Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库. Hibernate可以应用在任何使用JDB ...

  8. java框架篇---hibernate之缓存机制

    一.why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数 ...

  9. JAVA框架之Hibernate【Hibernate缓存详解】

    1.缓存介绍 Hibernate中提供了两级Cache,第一级别的缓存是Session级别的缓存,它是属于事务范围的缓存.这一级别的缓存由hibernate管理的,一般情况下无需进行干预:第二级别的缓 ...

随机推荐

  1. 初识go的tomb包

    在分析github.com/hpcloud/tail 这个包的源码的时候,发现这个包里用于了一个另外一个包,自己也没有用过,但是这个包在tail这个包里又起来非常大的作用 当时并没有完全弄明白这个包的 ...

  2. shell 十进制数字转十六进制字符串并将结果保存到变量

    . . . . . 今天写测试脚本的时候需要将生成的十六进制值作为参数传递给某个命令,而循环生成的数值都是十进制的.在网上查了好久也没有找到如何将一个变量中的值进行进制转换,并保存到变量中,网上的办法 ...

  3. mysql主从复制延迟问题的相关知识与解决方案

    一.如何监控发生了主从延迟? 在从库机器上,执行show slave status,查看Seconds_Behind_Master值,代表主从同步从库落后主库的时间,单位为秒,若同从同步无延迟,这个值 ...

  4. 微软Windows10LTSC2019官方三月更新版镜像

    何谓 Windows 10 LTSC?其实,LTSC 是 Long Term Support Channel 的缩写,翻译一下就是“长期服务分支”. Windows 10 LTSC 实际上就是微软官方 ...

  5. 买了第一台mac

    今天,我的第一台mac到手了.是Macbook air 13.3寸屏的.正好这几天bestbuy大打折,索性入手了一台15年最低配的,一共只花了$750,包括税. 还是有点舍不得,而且用不习惯.

  6. 【规范】前端编码规范——jquery 规范

    使用单引号 不推荐 $("div").html("<img src='1.jpg'>"); 推荐 $('div').html('<img sr ...

  7. top-N 抽样

        1, 使用hive标记random:(如果是mr,就自己标记random值) use ps; set mapred.job.priority=VERY_HIGH; set mapred.job ...

  8. [踩坑日记]spring mvc

    目录 找不到javax.servlet.ServletException的类文件 idea 清除tomcat缓存 IOException parsing XML document from Servl ...

  9. Flume的监控参数

    参考 flume的http监控参数说明 普通的flume启动命令 bin/flume-ng agent -c conf -f conf/flume-conf.properties -n agent - ...

  10. spring JdbcTemplate数据库

    DAO package DAO; import org.springframework.jdbc.core.JdbcTemplate; public class OrderDao { private ...