Hibernate相关笔记

Hibernate 相关笔记

一、核心API

1.SessionFactory接口

Configuration对象根据当前的配置信息生成 SessionFactory 对象。SessionFactory 对象一旦构造完毕,即被赋予特定的配置信息(SessionFactory 对象中保存了当前的数据库配置信息和所有映射关系以及预定义的SQL语句。同时,SessionFactory还负责维护Hibernate的二级缓存)。

加载过程是线程安全的

//加载配置文件
Configuration cfg = new Configuration().configure();
SessionFactory sf = cfg.buildSessionFactory();

SessionFactory是生成Session的工厂:

   Session session = sf.openSession();

构造SessionFactory很消耗资源,一般情况下一个应用中只初始化一个 SessionFactory对象。

2.Session接口

  • Session是应用程序与数据库之间交互操作的一个单线程对象,是 Hibernate 运作的中心,所有持久化对象必须在 session
    的管理下才可以进行持久化操作。此对象的生命周期很短。Session 对象有一个一级缓存,显式执行 flush
    之前,所有的持久层操作的数据都缓存在 session 对象处。相当于 JDBC 中的 Connection。

  • 持久化类与 Session 关联起来后就具有了持久化的能力。

  • 是线程不安全的

  • Session类的方法

    • 取得持久化对象的方法: get() load()
    • 持久化对象都得保存,更新和删除:save(),update(),saveOrUpdate(),delete()
    • 开启事务: beginTransaction().
    • 管理 Session 的方法:isOpen(),flush(), clear(), evict(), close()等

3.Transaction接口

代表一次原子操作,它具有数据库事务的概念。所有持久层都应该在事务管理下进行,即使是只读操作。

Transaction tx = session.beginTransaction();
//一次操作
tx.commit();  
  • 常用方法:
    • commit():提交相关联的session实例
    • rollback():撤销事务操作
    • wasCommitted():检查事务是否提交

4.主要API整理(*)

|– Configuration 配置管理类对象

    config.configure();    加载主配置文件的方法(hibernate.cfg.xml),默认加载src/hibernate.cfg.xml
    config.configure(“cn/config/hibernate.cfg.xml”);   加载指定路径下指定名称的主配置文件
    config.buildSessionFactory();   创建session的工厂对象

|– SessionFactory session的工厂(或者说代表了这个hibernate.cfg.xml配置文件)

sf.openSession();   创建一个sesison对象
sf.getCurrentSession();  创建session或取出session对象

|–Session session对象维护了一个连接(Connection), 代表了与数据库连接的会话。
Hibernate最重要的对象: 只用使用hibernate与数据库操作,都用到这个对象

    session.beginTransaction(); 开启一个事务; hibernate要求所有的与数据库的操作必须有事务的环境,否则报错!
更新:
    session.save(obj);   保存一个对象
    session.update(emp);  更新一个对象
    session.saveOrUpdate(emp);  保存或者更新的方法:

 - 没有设置主键,执行保存;
 - 有设置主键,执行更新操作; 
 - 如果设置主键不存在报错!

查询方式:
1.主键查询:
session.get(Employee.class, 1); 主键查询
session.load(Employee.class, 1); 主键查询 (支持懒加载)

2.HQL查询:
HQL查询与SQL查询区别:
SQL: (结构化查询语句)查询的是表以及字段; 不区分大小写。
HQL: hibernate query language 即hibernate提供的面向对象的查询语言
查询的是对象以及对象的属性。
区分大小写。

3.Criteria查询:
完全面向对象的查询。
本地SQL查询:
复杂的查询,就要使用原生态的sql查询,也可以,就是本地sql查询的支持!
(缺点: 不能跨数据库平台!)

|– Transaction hibernate事务对象

5.主要API使用实例

public static void main(String[] args) throws Exception{
           // 1. 加载默认的hibernate.cfg.xml的配置文件
        Configuration config = new Configuration().configure();
          // 2. 加载hbm文件  (Test.hbm.xml)
          config.addClass(cn.itcast.hibernate.api.Test.class);
          // 3. 根据配置生成表
          SchemaExport schema = new SchemaExport(config);
          schema.create(true, true);
          // 4. 构建SessionFactory对象
          SessionFactory factory = config.buildSessionFactory();
          Session session = factory.openSession();         // 5. 建立连接
          Transaction tran = session.beginTransaction(); // 6. 开启事务
          Test t = new Test();
          t.setName("test hibbernate");
          session.save(t);
          tran.commit();    // 7. 提交事务
          session.close();  // 8. 关闭会话
    }

二、Hibernate对象映射配置

这里写图片描述

Hibernate主键生成策略


<id name="id" column="id" type="long">
    <generator class="?" />
</id>

class处表示主键生成策略

generator class说明
identity采用数据库生成的主键,用于为long、short、int类型生成唯一标识, Oracle 不支持自增字段
sequenceDB2、Oracle均支持的序列,用于为long、short或int生成唯一标识,需要oracle创建sequence
native根据底层数据库的能力,从identity、sequence、hilo中选择一个,灵活性更强。
increment个是由Hibernate在内存中生成主键,每次增量为1,不依赖于底层的数据库,因此所有的数据库都可以使用。(适用性强)
uuid.hex使用一个128-bit的UUID算法生成字符串类型的标识符
uuid.stringhibernate会算出一个16位的值插入

Hibernate数据类型映射

映射数据类型1
映射数据类型2

  1. 在实际开发中需要在hbm文件中使用的type属性值是指定的类型。那
    么指定的类型一般的是基于hibernate的类型。
  2. 当然在实际过程中也可以在hbm文件中指定java类型。
public class DataType {
    private long id;    private boolean tag;    private Date createDate;
    private char vip;  private Timestamp logTime; private byte[] description;
    ….
}
<hibernate-mapping>
    <class name="cn.itcast.hibernate.datatype.DataType" table="datatype">
    //主键设置
     <id name="id" column="id" type="long">
       <generator class="increment"></generator>
     </id>
     //name=对象属性名称 column=对应的sql字段名 type=hibernate类型
     <property name="tag" column="tag" type="boolean"></property>
     <property name="createDate" column="createDate" type="date"></property>
     <property name="vip" column="vip" type="character"></property>
     <property name="logTime" column="logTime" type="timestamp"></property>
     <property name="description" column="description" type="binary"></property>
   </class>
</hibernate-mapping>

Hibernate对象映射配置文件实例

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


<!-- 映射文件: 映射一个实体类对象;  描述一个对象最终实现可以直接保存对象数据到数据库中。  -->
<!-- 
    package: 要映射的对象所在的包(可选,如果不指定,此文件所有的类都要指定全路径)
    auto-import 默认为true, 在写hql的时候自动导入包名
                如果指定为false, 再写hql的时候必须要写上类的全名;
                  如:session.createQuery("from cn.itcast.c_hbm_config.Employee").list();
 -->
<hibernate-mapping package="cn.itcast.c_hbm_config" auto-import="true">

    <!-- 
        class 映射某一个对象的(一般情况,一个对象写一个映射文件,即一个class节点)
            name 指定要映射的对象的类型
            table 指定对象对应的表;
                  如果没有指定表名,默认与对象名称一样 
     -->
    <class name="Employee" table="employee">

        <!-- 主键 ,映射-->
        <id name="empId" column="id">
            <!-- 
                主键的生成策略
                    identity  自增长(mysql,db2)
                    sequence  自增长(序列), oracle中自增长是以序列方法实现
                    native  自增长【会根据底层数据库自增长的方式选择identity或sequence】
                            如果是mysql数据库, 采用的自增长方式是identity
                            如果是oracle数据库, 使用sequence序列的方式实现自增长

                    increment  自增长(会有并发访问的问题,一般在服务器集群环境使用会存在问题。)

                    assigned  指定主键生成策略为手动指定主键的值
                    uuid      指定uuid随机生成的唯一的值
                    foreign   (外键的方式, one-to-one讲)
             -->
            <generator class="uuid"/>
        </id>

        <!-- 
            普通字段映射
            property
                name  指定对象的属性名称
                column 指定对象属性对应的表的字段名称,如果不写默认与对象属性一致。
                length 指定字符的长度, 默认为255
                type   指定映射表的字段的类型,如果不指定会匹配属性的类型
                    java类型:     必须写全名
                    hibernate类型:  直接写类型,都是小写
        -->
        <property name="empName" column="empName" type="java.lang.String" length="20"></property>
        <property name="workDate" type="java.util.Date"></property>
        <!-- 如果列名称为数据库关键字,需要用反引号或改列名。 -->
        <property name="desc" column="`desc`" type="java.lang.String"></property>

    </class>


</hibernate-mapping>

复合主键配置

public class User {

    // 名字跟地址,不会重复
    private CompositeKeys keys;
    private int age;
}
//***复合主键构成的单独类必须实现Serializable接口
//why?只有主键实现了Serializable接口才可以调用get()方法
public class CompositeKeys implements Serializable{
    private String userName;
    private String address;
   // .. get/set
}
<class name="User">

        <!-- 复合主键映射 -->
        <composite-id name="keys">
            <key-property name="userName" type="string"></key-property>
            <key-property name="address" type="string"></key-property>
        </composite-id>

        <property name="age" type="int"></property>     

</class>

三、对象-关系映射基础

1. 对象映射关系-1:n关系

需求1:
部门与员工
一个部门有多个员工; 【一对多】
多个员工,属于一个部门 【多对一】
需求2:
项目与开发员工
一个项目,有多个开发人员!
一个开发人员,参与多个项目! 【多对多】

    public class Dept {
    private int deptId;
    private String deptName;
    // 【一对多】 部门对应的多个员工
    private Set<Employee> emps = new HashSet<Employee>();
public class Employee {

    private int empId;
    private String empName;
    private double salary;
----------------------Dept.hbm.xml----------------------
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="cn.itcast.b_one2Many">

    <class name="Dept" table="t_dept">
        <id name="deptId">
            <generator class="native"></generator>
        </id>   
        <property name="deptName" length="20"></property>

        <!-- 
            一对多关联映射配置  (通过部门管理到员工)
            Dept 映射关键点:
            1.  指定 映射的集合属性: "emps"
            2.  集合属性对应的集合表: "t_employee"
            3.  集合表的外键字段   "t_employee. dept_id"
            4.  集合元素的类型

         -->
         <set name="emps">   <!-- table="t_employee" -->
             <key column="dept_id"></key>
             <one-to-many class="Employee"/>
         </set>


    </class>


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

<hibernate-mapping package="cn.itcast.b_one2Many">

    <class name="Employee" table="t_employee">
        <id name="empId">
            <generator class="native"></generator>
        </id>   
        <property name="empName" length="20"></property>
        <property name="salary" type="double"></property>

        <!-- 
            多对一映射配置
            Employee 映射关键点:
            1.  映射的部门属性  :  dept
            2.  映射的部门属性,对应的外键字段: dept_id
            3.  部门的类型
         -->
         <many-to-one name="dept" column="dept_id" class="Dept"></many-to-one>

    </class>


</hibernate-mapping>
<set name="emps"  table="t_employee" inverse="false"  cascade="save-update,delete">   <!-- table="t_employee" -->
             <key column="dept_id"></key>
             <one-to-many class="Employee"/>
</set>
  • inverse属性

Inverse属性,是在维护关联关系的时候起作用的。
表示控制权是否转移。(在一的一方起作用)

Inverse , 控制反转。
Inverse = false 不反转; 当前方有控制权
True 控制反转; 当前方没有控制权

  • cascade属性。cascade 表示级联操作 【可以设置到一的一方或多的一方】
    • none 不级联操作, 默认值
    • save-update 级联保存或更新
    • delete 级联删除
    • save-update,delete 级联保存、更新、删除
    • all 同上。级联保存、更新、删除

总结:
在一对多与多对一的关联关系中,保存数据最好的通过多的一方来维护关系,这样可以减少update语句的生成,从而提高hibernate的执行效率!

配置一对多与多对一,这种叫“双向关联”
只配置一对多, 叫“单项一对多”
只配置多对一, 叫“单项多对一”

注意:
配置了哪一方,哪一方才有维护关联关系的权限!

2.对象映射关系-1:1关系

①基于外键的映射

需求: 用户与身份证信息
一条用户记录对应一条身份证信息! 一对一的关系!

//身份证
public class IdCard {

    // 身份证号(主键)
    private String cardNum;// 对象唯一表示(Object Identified, OID)
    private String place; //  身份证地址
    // 身份证与用户,一对一的关系
    private User user;
}
// 用户
public class User {

    private int userId;
-------------------IdCard.hbm.xml-------------------------
<hibernate-mapping package="cn.itcast.c_one2one">

    <class name="IdCard" table="t_IdCard">
        <id name="cardNum">
            <generator class="assigned"></generator>
        </id>   
        <property name="place" length="20"></property>

        <!-- 
            一对一映射,有外键方
            unique="true"   给外键字段添加唯一约束
         -->
         <many-to-one name="user" unique="true" column="user_id" class="User" cascade="save-update"></many-to-one>

    </class>


</hibernate-mapping>
-------------------User.hbm.xml-------------------------
<hibernate-mapping package="cn.itcast.c_one2one">

    <class name="User" table="t_user">
        <id name="userId">
            <generator class="native"></generator>
        </id>   
        <property name="userName" length="20"></property>
        <!-- 
            一对一映射: 没有外键方
         -->
         <one-to-one name="idCard" class="IdCard"></one-to-one>

    </class>


</hibernate-mapping>
②基于主键的映射
<hibernate-mapping package="cn.itcast.c_one2one2">

    <class name="IdCard" table="t_IdCard">
        <id name="user_id">
            <!-- 
                id 节点指定的是主键映射, 即user_id是主键
                主键生成方式: foreign  即把别的表的主键作为当前表的主键;
                        property (关键字不能修改)指定引用的对象     对象的全名 cn..User、  对象映射 cn.User.hbm.xml、   table(id)
             -->
            <generator class="foreign">
                <param name="property">user</param>
            </generator>
        </id>   
        <property name="cardNum" length="20"></property>
        <property name="place" length="20"></property>

        <!-- 
            一对一映射,有外键方
            (基于主键的映射)
             constrained="true"  指定在主键上添加外键约束
         -->
        <one-to-one name="user" class="User" constrained="true"  cascade="save-update"></one-to-one>

    </class>


</hibernate-mapping>

3. 对象映射关系-n:n关系

需求:项目与开发人员
1. Project Developer
电商系统
曹吉
王春
2. OA系统
王春
老张

public class Developer {
    private int d_id;
    private String d_name;
    // 开发人员,参数的多个项目
    private Set<Project> projects = new HashSet<Project>();
}
public class Project {
    private int prj_id;
    private String prj_name;
    // 项目下的多个员工
    private Set<Developer> developers = new HashSet<Developer>();
}
---------------------------Project.hbm.xml----------------------
<hibernate-mapping package="cn.itcast.c_many2many">

    <class name="Project" table="t_project">
        <id name="prj_id">
            <generator class="native"></generator>
        </id>   
        <property name="prj_name" length="20"></property>
        <!-- 
            多对多映射:
            1.  映射的集合属性: “developers”
            2.  集合属性,对应的中间表: “t_relation”
            3. 外键字段:  prjId
            4. 外键字段,对应的中间表字段:  did
            5.   集合属性元素的类型
         -->
         <set name="developers" table="t_relation" cascade="save-update">
            <key column="prjId"></key>
            <many-to-many column="did" class="Developer"></many-to-many>
         </set>

    </class>


</hibernate-mapping>
---------------------------Developer.hbm.xml----------------------
<hibernate-mapping package="cn.itcast.c_many2many">

    <class name="Developer" table="t_developer">
        <id name="d_id">
            <generator class="native"></generator>
        </id>   
        <property name="d_name" length="20"></property>

        <!-- 
            多对多映射配置: 员工方
                name  指定映射的集合属性
                table 集合属性对应的中间表
                key   指定中间表的外键字段(引用当前表t_developer主键的外键字段)
                many-to-many
                    column 指定外键字段对应的项目字段
                    class  集合元素的类型
         -->
        <set name="projects" table="t_relation">
            <key column="did"></key>
            <many-to-many column="prjId" class="Project"></many-to-many>
        </set>


    </class>


</hibernate-mapping>

在进行多对多映射的时候,需要一张中间表。

四、Hibernate主配置文件

默认放在src目录下,命名为hibernate.cfg.xml

Configuration cfg = new Configuration().configure();

通过Configuration类来加载配置文件
config.configure(“cn/config/hibernate.cfg.xml”); 加载指定路径下指定名称的主配置文件

<!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节点代表一个数据库 -->
    <session-factory>

        <!-- 1. 数据库连接配置 -->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        //**************************
        <property name="hibernate.connection.url">jdbc:mysql:///hibernate_demo</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">Zh86278789</property>
        //***************************
        <!-- 
            数据库方法配置, hibernate在运行的时候,会根据不同的方言生成符合当前数据库语法的sql
         -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>

<!-- 3.(可选)【连接池配置】 -->
        <!-- 配置连接驱动管理类 -->
        <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
        <!-- 配置连接池参数信息 -->
        <property name="hibernate.c3p0.min_size">2</property>
        <property name="hibernate.c3p0.max_size">4</property>
        <property name="hibernate.c3p0.timeout">5000</property>
        <property name="hibernate.c3p0.max_statements">10</property>
        <property name="hibernate.c3p0.idle_test_period">30000</property>
        <property name="hibernate.c3p0.acquire_increment">2</property>


        <!-- 2. 其他相关配置 -->
        <!-- 2.1 显示hibernate在运行时候执行的sql语句 -->
        <property name="hibernate.show_sql">true</property>
        <!-- 2.2 格式化sql -->
        <property name="hibernate.format_sql">true</property>
        <!-- 2.3 自动建表  -->
        <property name="hibernate.hbm2ddl.auto">update</property>
        <!-- 2.4 根据线程创建Session,自动绑定至线程 -->
        <property name="hibernate.current_session_context_class">thread</property>



        <mapping resource="cn/itcast/a_hello/Employee.hbm.xml"/>
        <mapping resource="cn/itcast/d_compositeKey/User.hbm.xml" />
    </session-factory>
</hibernate-configuration>

五、Hibernate查询

1.查询概述

1) Get/load主键查询
2) 对象导航查询
*3) HQL查询, Hibernate Query language hibernate 提供的面向对象的查询语言。()
4) Criteria 查询, 完全面向对象的查询(Query By Criteria ,QBC)
5) SQLQuery, 本地SQL查询
缺点:不能跨数据库平台: 如果该了数据库,sql语句有肯能要改
使用场景: 对于复杂sql,hql实现不了的情况,可以使用本地sql查询。


    public void all() {

        Session session = sf.openSession();
        session.beginTransaction();

        //1) 主键查询
//      Dept dept =  (Dept) session.get(Dept.class, 12);
//      Dept dept =  (Dept) session.load(Dept.class, 12);

        //2) 对象导航查询
//      Dept dept =  (Dept) session.get(Dept.class, 12);
//      System.out.println(dept.getDeptName());
//      System.out.println(dept.getEmps());

        // 3)   HQL查询
        // 注意:使用hql查询的时候 auto-import="true" 要设置true,
        //  如果是false,写hql的时候,要指定类的全名
//      Query q = session.createQuery("from Dept");
//      System.out.println(q.list());

        // a. 查询全部列
//      Query q = session.createQuery("from Dept");  //OK
//      Query q = session.createQuery("select * from Dept");  //NOK, 错误,不支持*
//      Query q = session.createQuery("select d from Dept d");  // OK
//      System.out.println(q.list());

        // b. 查询指定的列  【返回对象数据Object[] 】
//      Query q = session.createQuery("select d.deptId,d.deptName from Dept d");  
//      System.out.println(q.list());

        // c. 查询指定的列, 自动封装为对象  【必须要提供带参数构造器】
//      Query q = session.createQuery("select new Dept(d.deptId,d.deptName) from Dept d");  
//      System.out.println(q.list());

        // d. 条件查询: 一个条件/多个条件and or/between and/模糊查询
        // 条件查询: 占位符
//      Query q = session.createQuery("from Dept d where deptName=?");
//      q.setString(0, "财务部");
//      q.setParameter(0, "财务部");
//      System.out.println(q.list());

        // 条件查询: 命名参数
//      Query q = session.createQuery("from Dept d where deptId=:myId or deptName=:name");
//      q.setParameter("myId", 12);
//      q.setParameter("name", "财务部");
//      System.out.println(q.list());

        // 范围
//      Query q = session.createQuery("from Dept d where deptId between ? and ?");
//      q.setParameter(0, 1);
//      q.setParameter(1, 20);
//      System.out.println(q.list());

        // 模糊
//      Query q = session.createQuery("from Dept d where deptName like ?");
//      q.setString(0, "%部%");
//      System.out.println(q.list());


        // e. 聚合函数统计
//      Query q = session.createQuery("select count(*) from Dept");
//      Long num = (Long) q.uniqueResult();
//      System.out.println(num);

        // f. 分组查询
        //-- 统计t_employee表中,每个部门的人数
        //数据库写法:SELECT dept_id,COUNT(*) FROM t_employee GROUP BY dept_id;
        // HQL写法
//      Query q = session.createQuery("select e.dept, count(*) from Employee e group by e.dept");
//      System.out.println(q.list());




        session.getTransaction().commit();
        session.close();
    }

    // g. 连接查询
    @Test
    public void join() {

        Session session = sf.openSession();
        session.beginTransaction();

        //1) 内连接   【映射已经配置好了关系,关联的时候,直接写对象的属性即可】
//      Query q = session.createQuery("from Dept d inner join d.emps");

        //2) 左外连接
//      Query q = session.createQuery("from Dept d left join d.emps");

        //3) 右外连接
        Query q = session.createQuery("from Employee e right join e.dept");
        q.list();

        session.getTransaction().commit();
        session.close();
    }

    // g. 连接查询 - 迫切连接
    @Test
    public void fetch() {

        Session session = sf.openSession();
        session.beginTransaction();

        //1) 迫切内连接    【使用fetch, 会把右表的数据,填充到左表对象中!】
//      Query q = session.createQuery("from Dept d inner join fetch d.emps");
//      q.list();

        //2) 迫切左外连接
        Query q = session.createQuery("from Dept d left join fetch d.emps");
        q.list();

        session.getTransaction().commit();
        session.close();
    }

    // HQL查询优化
    @Test
    public void hql_other() {
        Session session = sf.openSession();
        session.beginTransaction();
        // HQL写死
//      Query q = session.createQuery("from Dept d where deptId < 10 ");

        // HQL 放到映射文件中
        Query q = session.getNamedQuery("getAllDept");
        q.setParameter(0, 10);
        System.out.println(q.list());

        session.getTransaction().commit();
        session.close();
    }
}

//-----------------------   Criteria 查询   -------------------
    public void criteria() {

        Session session = sf.openSession();
        session.beginTransaction();

        Criteria criteria = session.createCriteria(Employee.class);
        // 构建条件
        criteria.add(Restrictions.eq("empId", 12));
//      criteria.add(Restrictions.idEq(12));  // 主键查询

        System.out.println(criteria.list());


        session.getTransaction().commit();
        session.close();
    }

    -------------------SQLQuery, 本地SQL查询-------------------------------
    // 不能跨数据库平台: 如果该了数据库,sql语句有肯能要改。
    @Test
    public void sql() {

        Session session = sf.openSession();
        session.beginTransaction();

        SQLQuery q = session.createSQLQuery("SELECT * FROM t_Dept limit 5;")
            .addEntity(Dept.class);  // 也可以自动封装
        System.out.println(q.list());

        session.getTransaction().commit();
        session.close();
    }

2.分页查询

------------------------------分页查询----------------------------------
    @Test
    public void all() {

        Session session = sf.openSession();
        session.beginTransaction();

         Query q = session.createQuery("from Employee");

         // 从记录数
         ScrollableResults scroll = q.scroll();  // 得到滚动的结果集
         scroll.last();                         //  滚动到最后一行
         int totalCount = scroll.getRowNumber() + 1;// 得到滚到的记录数,即总记录数

         // 设置分页参数
         q.setFirstResult(0);
         q.setMaxResults(3);

         // 查询
         System.out.println(q.list());
         System.out.println("总记录数:" + totalCount);

        session.getTransaction().commit();
        session.close();
    }

六、项目中Session的管理方式

public void testSession() throws Exception {
        //openSession:  创建Session, 每次都会创建一个新的session
        Session session1 = sf.openSession();
        Session session2 = sf.openSession();
        System.out.println(session1 == session2);
        session1.close();
        session2.close();

        //getCurrentSession 创建或者获取session
        // 线程的方式创建session  
        // 一定要配置:<property name="hibernate.current_session_context_class">thread</property>
        Session session3 = sf.getCurrentSession();// 创建session,绑定到线程
        Session session4 = sf.getCurrentSession();// 从当前访问线程获取session
        System.out.println(session3 == session4);

        // 关闭 【以线程方式创建的session,可以不用关闭; 线程结束session自动关闭】
        //session3.close();
        //session4.close(); 报错,因为同一个session已经关闭了!
    }

七、Hibernate中的部分概念

一级缓存
二级缓存
懒加载

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值