初识Hibernate

书到用时方恨少,是非经过不知难!最近听了一位前辈的课程,随手整理了一份知识点,与大家分享,还望圈内前辈多多指点,本文中有哪些不足,不严谨之处,请在底下留言,我好更正,以免给下一位读者带来不便,感谢各位!!!

Hibernate

好处:操作数据库,可以以面向对象的方式来完成。不需要书写SQL

ORM:对象关系映射

  • hibernate属于4级:完全面向对象操作数据库
  • Mybatis属于2级
  • dbutils属于1级

     

搭建

  • 导包

  1. antlr-2.7.7.jar
  2. dom4j-1.6.1.jar
  3. geronimo-jta_1.1_spec-1.1.1.jar
  4. hibernate-commons-annotations-5.0.1.Final.jar
  5. hibernate-core-5.0.7.Final.jar
  6. hibernate-jpa-2.1-api-1.0.0.Final.jar
  7. jandex-2.0.0.Final.jar
  8. javassist-3.18.1-GA.jar
  9. jboss-logging-3.3.0.Final.jar
  10. mysql-connector-java-5.1.7-bin.jar

     

  • 创建数据库,数据表

  • 书写ORM元数据(对象与表额映射配置文件)

  1. 导入约束
  2. 实体
  3. ORM元数据
  • 书写主配置文件

  1. 必选属性配置(5个与数据库的连接相关属性)

        <property name="hibernate.connection.driver_class">driver</property>
        <property name="hibernate.connection.url">url</property>
        <property name="hibernate.connection.username">username</property>
        <property name="hibernate.connection.password">password</property>  

       <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

  1. 可选属性配置(3个)

        <!-- sql语句是否打印到控制台 -->
        <property name="hibernate.show_sql">true</property>
        <!-- sql语句格式化 -->
        <property name="hibernate.format_sql">true</property>

         create               每次框架运行都会创建新的表,以前表将会被覆盖,表数据会丢失。
        create-drop        每次框架运行结束都会将所有表删除。
        update               如果表已存在不会再生成新表,如果表有变动,自动更新表(不会删除任何数据)。
        validate             数据库中的列与*hbm.xml列是否对应,不对应就抱错
        <property name="hibernate.hbm2ddl.auto">update</property>

  1. 元数据引入配置

<mapping resource="*.hbm.xml" />


    Hibernate API详解

  • Configuration

  1. 加载主配置
  2. 创建sessionFactory
  • SessionFactory

  1. 创建session对象
  2. 属于线程安全的对象
  3. 注意:在web项目中,只创建一个sessionFactory
  • Session

  1. 与数据库之间的连接
  2. 获得事务
  3. CRUD
  • Transaction:封装了事务的操作


     

实体规则

  • 实体类创建的注意事项

  1. 持久化类提供无参构造器
  2. 提供对属性Get/Set方法
  3. 持久化类的属性,尽量使用包装类
  4. 持久化类需要提供oid,与数据库中的主键列对应
  5. 不要用final修饰class(hibernate使用cglib代理生成对象)
  • 主键类型

  1. 自然主键(少见):表的业务类中,某业务列符合:1、必须有,2、不重复的特征,则该列可作为主键使用(身份证)
  2. 代理主键(常见)
  • 主键生成策略

  1. 代理主键生成策略

identity:主键自增,由数据库来维护主键值,录入时不需要指定主键

increment:主键自增,由Hibernate来维护,每次插入前检索id最大值,+1作为新的主键值。(并发时不安全)

sequence:Oracle中主键生成策略

hilo:高低位算法,主键自增,由hibernate来维护。

native:hilo+sequence+identity 自动3选1策略

uuid:产生随机字符串,作为主键,*注意*:主键类型必须为String类型

  1. 自然主键生成策略

assigned:自然主键生成策略。hibernate不会管理主键,由开发人员自主管理


Hibernate中的对象状态

  • 对象3种状态

  1. 瞬时状态:没有id,没有Session缓存中

  2. 持久化状态:有id,在Session缓存中

  3. 游离|托管状态:有id,没有在session缓存中

  • 3种状态转换图


 一级缓存

  • 缓存:提高效率。hibernate中一级缓存也是为了提高操作数据库效率
  • 提高查询效率
  • 减少更改所执行的sql语句

     

hibernate中的事务

事务

  • 事务特性
  1. A 原子性
  2. C 一致性 (数据总量不变)
  3. I 隔离性
  4. D 持久性
  • 事务并发产生问题
  1.  脏读:读到最终未提交的数据
  2. 不可重复读:2次连续读取,由于数据一致性,2次读取数据不一致
  3. 幻|虚读:整表操作,在对其删除同时,增加一条数据
  • 事务隔离级别
  1. 读未提交 123
  2. 读已提交 23
  3. 可重复读 3(mysql默认)
  4. 串行化 没有问题

在hibernate中指定隔离级别

<property name="hibernate.connection.isolation">4</property>

  • 0001   1 读未提交
  • 0010   2 读已提交
  • 0100   4 可重复读
  • 1000   8 串行化

在项目中如何管理事务

  • 事务打开、业务执行、事务提交、回滚事务。
  • Service层及DAO层使用到session保证是同一个session对象
  • 注意1:通过getCurrentSession()获得的session对象,当事务提交时,session会自动关闭,不要手动调用close关闭。
  • 注意2: 调用getCurrentSession方法必须配合主配置中的一段配置。

<property name="hibernate.current_session_context_class">thread</property>


多表关系

1:N

  • 实体对象

1:使用集合

N:直接引用1的一方

  • 关系型数据库

N:使用外键的引用1的一方的主键

  • 映射文件

1:<set name="">
                       <key column="">
                      <one-to-many class="">
               </set>

N:<many-to-one name="" column="" class="" />

  • 操作:操作管理级属性
  1. cascade:级别操作,减少我们书写操作的代码。
                none(默认)          不及联
                save-update         级联保存
                delete              级联删除
                all                 级联保存+级联删除
  2. inverse:反转关系维护
           属于性能优化。关系两端都使用了关系,双发都会发送维护关系语句, 这样就发生了重复,我们可以使用inverse使一的一方放弃维护关系(在1:N中一方可以放弃维护关系)
     true  : 放弃    ,false(默认):    维护     

N:N

  • 实体对象

两方使用集合。

  • 关系型数据库

使用中间表,至少两列,作为外键引用两张表的主键

  • 映射文件

<set name="" table="中间表名">
                   <key column="别人引用我">
                   <many-to-many class="" column="我引用别人">
           </set>

  • 操作:操作管理级属性
  1. cascade:级别保存
                 none(默认)          不及联
                 save-update         级联保存
                 delete              级联删除
                 all                 级联保存+级联删除

  2.  

    inverse:反转关系维护,属于性能优化。关系两端都使用了关系,必须选择一方放弃维护关系,放弃维护关系由业务方向决定(录入员工,员工和角色的关系,就由员工来维护)

                  true             放弃
                  false(默认)    维护      
       

     

查询

查询-HQL语法

基础语法

        String hql3 = " from Student";
        Query query = session.createQuery(hql3);
        List list = query.list();

条件

        String hql2 = " from  Student order by cust_id desc ";  
        Query query = session.createQuery(hql2);
        List list = query.list();

分页

        String hql1 = " from  Student  ";  
        Query query = session.createQuery(hql1);
        query.setFirstResult(2);
        query.setMaxResults(2);   
        List list = query.list();

  • 多表查询

内连接:将连接到的对象分别返回,放到数组中

        String hql = " from Student s inner join s.linkMens ";     
        Query query = session.createQuery(hql);
        List<Object[]> list = query.list();

内连接迫切连接:自行进行封装,返回值就是一个对象

        String hql = " from Student s inner join fetch s.linkMens ";
        Query query = session.createQuery(hql);
        List<Student> list = query.list();

左外连接

        String hql = " from Student s left join s.linkMens ";     
        Query query = session.createQuery(hql);
        List<Object[]> list = query.list();

左外迫切连接

        String hql = " from Student s left join fetch s.linkMens ";
        Query query = session.createQuery(hql);
        List<Student> list = query.list();

右外

右外迫切连接

查询-Criteria语法

  • 离线查询:操作数据库分为Controller、Service、DAO三层,在Controller层就创建离线的Criteria对象,直到DAO层进行执行。

        //Controller/Service层:
        DetachedCriteria dc  = DetachedCriteria.forClass(Student.class);
        dc.add(Restrictions.idEq(6l));//拼装条件    
        //DAO层:----------------------------------------------------
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        //----------------------------------------------------
        Criteria c = dc.getExecutableCriteria(session);  
        List list = c.list();

  • 语法

条件

        Criteria c = session.createCriteria(Student.class);              

         c.add(Restrictions.idEq(2l));   
        List<Customer> list = c.list();

查询优化

  • 类级别查询
  1. get方法:没有任何策略,调用即立即查询数据库加载数据。
  2. load方法(默认): 应用类级别的加载策略。
  • 关联级别查询(集合策略,关联属性策略)

集合策略

          lazy属性: 决定是否延迟加载
                               true(默认值): 延迟加载,懒加载
                               false: 立即加载
                               extra: 极其懒惰,只查询集合的size(count语句)
                     fetch属性: 决定加载策略.使用什么类型的sql语句加载集合数据
                               select(默认值): 单表查询加载
                                join: 使用多表查询加载集合
                                subselect:使用子查询加载集合

关联属性策略

                    fetch 决定加载的sql语句
                             select: 使用单表查询
                             join : 多表查询
                    lazy  决定加载时机
                             false: 立即加载
                             proxy: 由customer的类级别加载策略决定.

no-session问题解决: 扩大session的作用范围.

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值