Hibernate-----阶段总结

Hibernate -----总结

 

一、在使用Hibernate的时候

         首先我们要导入Hibernate类库,导入Hibernate压缩包中lib文件中required中的包

         其后我们要进行对数据的操作,所以还需要一个数据库驱动包,例如mysqlconnector....,

二、准备工作

        1)首先我们要建立好实体类和映射文件(通过注解也可以实现,在后面会讲到)

         在实体类的同目录下创建映射文件(类名.hbm.xml),导入dtd约束(hibernate-mapping-3.0dtd)

 

 1 <?xml version="1.0"?>
 2 <!--约束文件-->
 3 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4         "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 
 6 <hibernate-mapping package="包名">
 7     <class name="类名" table="类对应的表名">
 8         <id name="类中要作为主键的属性" column="no" length="200">
 9             <generator class="主键生成策略"></generator>
10         </id>
11 
12 
13         <property name="money"  column="money"></property>
14         <property name="createTime" column="createTime"></property>
15         <property name="status"  column="status"></property>
16 
17         <!--集合属性的配置-->
18         <set name="orderItems">
19             <key column="ono"></key>
20             <one-to-many class="OrderItem"></one-to-many>
21         </set>
22 
23 
24     </class>
25 
26 
27 </hibernate-mapping>

 

2)准备主配置文件

在src目录下,新建hibernate.cfg.xml文件,导入dtd约束(在hibernate-configuration-3.3.dtd)中

 

<!--约束文档-->
<!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>
        <!--四本一言
        四个基本项:
        1、驱动的类全称
        2、连接的url
        3、用户名
        4、密码
        一言:数据库方言
        MySQL数据库,选择合适的方言,5.6和5.7需要选择57方言-->
        <!--方言-->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL55Dialect</property>
        <!--数据库驱动-->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <!--用户名-->
        <property name="hibernate.connection.username">root</property>
        <!--密码-->
        <property name="hibernate.connection.password">123456</property>
        <!--数据库的url-->
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernateStudy?characterEncoding=UTF-8</property>
        <!--标记如何执行DDL语句-->
        <property name="hibernate.hbm2ddl.auto">update</property>
        <!--格式化自动生成的sql语句-->
        <property name="hibernate.format_sql">true</property>
        <!--显示sql语句-->
        <property name="hibernate.show_sql">true</property>
        <!--开启ThreadLocal存储Session,才可以使用getCurrentSession-->
        <property name="hibernate.current_session_context_class">thread</property>


        <!--启用二级缓存-->
        <property name="hibernate.cache.use_second_level_cache">true</property>
        <!--配置二级缓存的类-->
        <!-- Hibernate4.0之前-->
        <!--<property name="hibernate.cache.provider_class"></property>-->
        <property name="cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>

        <!--查询缓存-->
        <property name="hibernate.cache.use_query_cache">true</property>

        <!--数据库表与类的映射文件-->

        <mapping resource="com/luo/domain/BankCard.hbm.xml"></mapping>
        <!--演示注解映射-->
        <mapping class="com.luo.domain.Product"></mapping>


        <!--配置二级缓存 指定哪些类-->
<!--       <class-cache class="com.luo.domain.Product" usage="nonstrict-read-write"></class-cache>-->
    </session-factory>
</hibernate-configuration>

 

3、配置解释

hibernate-mapping:  package-在下面的配置文件中的类就默认为这个包下的类  不用每次都写包名在写类名

class属性:映射表与类的对应  name:类名   table:该类对应数据库中建表的名字

id属性:id代表主键(映射主键

name:类中主键属性名字

column:主键所在列的名字

length:主键字段的长度,默认为数据库对应数据类型的最大长度  

type:当前列的数据类型,默认自动检测  (可以不写,我就不写,写还容易写错,还不如让他默认找)

 

generator属性:代表的是主键生成策略

         代理主键:increment   先查询表中的主键最大值,加1作为新的主键(不建议使用,效率低)

                          identity:主键自增   只能用于支持主键自增的数据库    mysql支持  oracle不支持

                          sequence:使用数据库中的序列 每次取得时候会自动增加  ORacle中所使用的

                          hilo:hibernate自己用高低算法完成主键自增

                          uuid:生成随机字符作为主键  默认(32位)

                          native(常用):自动根据数据库的三选一(identity   sequence   hilo)

 

        自然主键:

                         assigned:hibernate不生成主键,由开发人员自己设置主键值

 

property属性:(映射的普通列)

       name属性:类中属性名

       column:表中字段名

       length  和 type   同上面  length type

主配置文件中:

自动建表 :(hibernate.hbm2ddl.auto)

                        create:自动建表,每次启动hibernate的时候都还自动创建表,如果表存在,那就删除之后在创建

                        create-drop:自动建表,每次运行完成后再将表删除

                        update:自动建表,如果有表,就不在重新建表,如果配置改变,自动更改表的结构

                        validate:不会自动创建表的结构,只负责在启动的时候检验表的结构,如果有问题就会抛出异常

API详解

     configuration:config    读取配置文件

                                buildSessionFactory      创建sessionFactory

                                Configuration conf = new Configuration().config;

                                SessionFactory  sf = conf.buildSessionFactory();

      SessionFactory:

                               根据配置信息创建session对象

                               1、SessionFactory创建需要消耗较多的内存资源

                               2、SessionFactory是线程安全的设计。

                               在一个web项目中确保只有一个SessionFactory存在 

     获得session: 

                              Session session = sf.openSession();  //获得一个新的session  每个session都不同

                              Session session = sf.getCurrentSession();//获得与线程绑定的session,需要在主配置文件中配置,不需要手动关闭session,线程安全的。

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

 

Session:

             hibernate中操作数据的核心对象

             1、操作增删改查

             2、获得事务操作对象

            beginTransaction | getTransaction   获得事务对象,第一个还具有开启事务的功能

            get|load      oid操作     根据给定标识和实体类返回持久化对象的实例

            save     插入

            delete  删除

            update  修改

            saveOrupdate    如果表中没有要操作的对象 那么就执行save  否则执行update

            createQuery      根据给定的HQL查询条件创建一个新的Query的实例

            createCriteria    根据给定的实体名称,创建一个新的Criteria实例   (过时)

            createSQLQuery 根据给定的SQL查询条件创建一个新的SQLQuery实例(过时)

            createNativeQuery  就是根据原生的sql语句来创建一个query实例

            

            注意的地方: get 是立即加载 

                                 load 是延迟加载   调用的时候不会发送sql语句,返回一个代理对象,使用对象的时候才执行查询语句

 

Transaction(事务)

           用于操作事务的对象

           try{

                 Transaction transaction = session.beginTransaction(); //开启事务

                 transaction.commit(); //事务提交

           }catch(Exception e){

                 transaction.rollback(); //事务回滚  当出现异常的时候

           }

 

创建实体对象的规则:

          1、public的空参构造方法

          2、私有化属性    public的get/set方法

          3、提供oid,映射主键字段

          4、标识属性尽量使用基本数据类型的包装类  例如: 能用Integer尽量别用int  能用Long尽量别用long

          5、类不能被final修饰 

 

Hibernate中对象的三种状态

          1、瞬时态     没有id     没关联

          2、持久态     有id        有关联

          3、游离态     有id        无关联

 

持久化状态:持久化状态对象会在事务提交的时候持久化到数据库,我们需要将对象持久化到数据库,就需要把对象转换为持久化状态。(注意在对象已经是持久态的情况下,对对象重新赋值,在事务提交之后会生成一条update的sql语句,来更新数据库中的对象的值让其与当前对象保持一致)  不用你自己去调用session.update()方法,没有用,只有在事务提交后才会生成一条sql语句

 

还有:当session进行 get、load方法的时候,如果数据库中有这个对象,则表示这个对象已经是持久化状态,当你对他进行重新赋值的时候,(他会将数据库中的值和session中的值进行比较)在事务提交的时候仍然会向数据库发送一条update语句。来更新对象

 

他就是拿数据库中的值和session中保存的对象进行比较 如果在事务提交之前你进行了session.clear()的时候,session中不存在该对象了,事务提交的时候他也不会去执行update

 

User u = new User();  //游离态

u.setId(3);

session.update(u); //完成update后也会变成持久化状态

u.setId(5);   //当你设置一个持久化对象的主键值的时候就会抛出异常

transaction.commit();

 

一个session中不能存在对一个持久化对象的双重Copy

例如:User user1 = (User)session.get(User.class,1);   user1是持久态度

          User user2 = new User();              user2是瞬时态

          user2.setId(1);

          session.saveOrupdate(user2) ;  //此时user2也会变成持久态度,但是session中不能存储同样的对象两份会抛出异常。

         解决方法: 用session.merge(u2); //该方法的作用就是先判断是否包含同一对象,如果包含则合并 (基本不用)

 

二、缓存

      一级缓存:也称为session缓存,属于线程级别缓存,该缓存的本质就是一个集合,该集合被放置到了session对象中,所以也称为session缓存,因为session是线程级别的,所以该缓存也称为线程级别缓存。

      缓存的作用:提高查询,修改的效率

   

      查询:根据id查询对象

                ResultSet会被封装成对象,放入缓存以及返回程序。如果缓存中存在要查找的id,返回缓存中的对象。

      修改:根据id查询对象

                ResultSet会被封装成对象,一式两份,分别放入session缓存以及缓存快照中

                事务在提交的时候,会比对session缓存中的以及快照中的对象是否发生变化。如果发生变化执行修改

     

三、Hibernate中的事务管理

     设置事务的隔离级别:  

               有4种等级   1  2  4   8

               Read uncommitted(读未提交)  最低级别(脏读、虚读(幻读)、不可重复读都可能发生)

               Read committed     (读已提交) 可以避免脏读的发生,虚读和不可重复读可能发生

               Repeatable  read      (可重复读) 可以避免脏读 和不可重复读的发生 

               Serializable(串行化)     全都可以避免  

 

               事务有service(逻辑层)管理,确保service层和dao层使用的是同一个连接 session(Connection)

               可以用getCurrentSession从ThradLocal中获得与线程绑定的session

               

               getCuurentSession配置之后才能使用

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

               getCurrentSession获得的session对象会在事务提交的时候自动关闭,不用手动关闭。

 

四、一对多  多对一  关系

ORM:对象关系映射

          o:一的一方使用集合,多的一方直接引用一的属性

          r:多的一方使用外键引用一的一方

         m:一对多关系映射   多对一关系映射

     

         一般我们用的时候都用set集合    list集合还得添加一个index字段   

       一对多的关系:

        <set name="集合属性名">

                    <key  column="外键名"></key>

                    <one-to-many class="多的一方的类名"/>

        </set>

       多对一的关系:

        <many-to-one name="引用一方的属性名"  column="外键名字"  class="一的一方的类名"/>

 

五、级联操作

      Cascade属性:级联操作

                 none:默认值   不级联

                 save-update:级联保存或者更新

                 delete:级联删除

                 all:save-udate   delete

     其实级联的作用就是减少书写代码, 删除不建议使用  风险较大

     inverse:是否维护关系

                 true:放弃

                 false:维护(默认)

  一对多中可以使用inverse属性放弃维护关系,多对一中不能放弃维护关系

    <set name="Order"  inverse="true">

              <key column="oid"/>

              <one-to-many class="orderItem"/>

    </set>

    为了避免维护关系SQL打印冗余,可以在一的一方放弃维护。配置后,表达关系只能通过多的一方来维护

 

六、多对多

    ORM:

        o:使用第三张表,该表至少有两列,两列都是外键

        r:两方都用集合来表达引用多个对方

       m:多对多映射文件

 

  七、Hibernate中的查询

         a.根据oid进行查询

         b.对象属性导航  

         c.HQL查询

         d.Criteria查询

         e.原生SQL查询

  

      1、HQL:  hibernate查询语言     只在hibernate使用

            基础查询:String hql=“select  o  from Order o”;

                                             ="from Order"

                             Query  query = session.createQuery(hql);

                             List<Order>  list = query.list();

            投影查询:

                         查询一个属性:

                             String  hql="select o.money from Order o";

                             Query  query = session.createQuery(hql);

                             List<String>  list = query.list();

                        查询两个属性:

                            String  hql="select o.money,o.id from Order o";

                            Query  query = session.createQuery(hql);

                            List<Object[]>  list = query.list();

                        查询多个对象,并封装到对象中

                            String hql="select new Order(o.id,o.money)  from Order o";

                             Query  query = session.createQuery(hql);

                            List<Order>  list = query.list();

                          //要在实体类中的构造方法中写  id 和  money

 

         条件查询:

                        问号?占位符

                       String hql="from Order o where o.money=?";

                       Query  query = session.createQuery(hql);

                       query.setParameter(0,"220");   //hql 从0开始  原始sql从1开始

                       List<Order>  list = query.list();

 

                       命名占位符    :low   (冒号后面加变量名字)

                         String hql=" from Order  o where o.id between  :low and :high"

                         Query  query = session.createQuery(hql);

                        query.setParameter(0,"20");   //hql 从0开始  原始sql从1开始

                        queey.setParameter(1,"89");

                        List<Order>  list = query.list();

     分页查询:

                    hql不支持   insert  limit   *

                    limit可以用  setFirstResult()     setMaxResult()

                    String hql=" from Order"

                    Query  query = session.createQuery(hql);

                     query.setFirstResult(0);  //从几开始

                    query.setMaxResult(4);   //查询几条数据

                    List<Order>  list = query.list();

 

    排序:

                desc  降序   asc 升序

                   String hql=“from Order  o    order by   o.id  desc ”;

                   .....

 聚合函数查询:Count   Max   Sum   Avg

                    String hql="select count(Order) from Order";

                       、。。。。。

                  Long count = (Long) query.uniqueResult();

                    count  返回的值是Long类型

 多表查询:

                   内连接: 两个表 一个Order  一个 OrderItem

                    hql=“select  o.id,o.money,od.id   from  Order o inner join on OrderItem od

                                where   o.id==od.id

                   左连接:select o.id,o.money,od.id  from  Order o left  join   OrderItem od  where

                                o.id==od.id"

                    右连接:left 换成right 就好了

                  

                     HQL适用于单表和简单多表   如果复杂的你就用 原生的sql写吧

 

 

Criteria  查询   (现在已经过时)

              hibernate 框架中独有的查询方式

               Criteria    无语句面向对象查询

               Criteria   一般用于单表查询

        

                1、基础查询:

                       创建查询对象   Criteria c =  session.criteria(Order.class);

                                               List<Order>  list = c.list();

                2、条件查询:

                         Criteria c =  session.criteria(Order.class);

                        c.add(Restrictions.and(Restrictions.between("id",2,5),Restrictions.like("name","李%")));

                        查询~~·

                3、分页查询:

                       c.setFirstResult(2);

                       c.setMaxResult(21);

                4、排序查询

                      c.addOrder(Order.asc("age"));  //升序

                     List<Order>  list = c.list();

                 5、聚合查询

                      c.setProjection(Projections.Count("id"));

                     Long count = (Long)c.uniqueResult();

 

                离线Criteria查询对象       不需要session就可以直接创建

                DetachedCriteria  dc  =DetachedCriteria.forClass(Order.class);

               //设置条件

               dc.add(Restrictions.and(Restrictions.between("id",2,5),Restrictions.like("name","李%")));

                //将离线查询与session相关联

                Criteria  c = dc.getExecutableCriteria(session);

                //执行操作 

                List<Order>  order = c.list();

    适合单表

 

查询策略:

          类级别查询策略:

                   lazy属性:是否懒加载|延迟加载

                                    true:  默认懒加载   用load

                                     false:立即加载

          :返回对象的初始化操作一定要咋session关闭之前完成    否则就会跑出  no-session  异常

 

 

Hibernate注解式开发

使用了注解就不用写映射配置文件

Hibernate的注解是基于JPA(java持久化api)---spring Data JPA

映射配置文件:
类--表
主键
属性---字段


常用的注解:
1、修饰类:
1、@Entity 标记实体 也可以指明表名
2、@Table 设置对应的表的信息,必须有
常用属性:
name 表名
2、修饰属性:

1、@Column 设置字段信息,比如字段名称、长度、约束等
常用属性:
name 字段名称
length 字段长度
unique 是否唯一
2、@Basic 标记属性是字段 默认有

3、@Transient 标记该属性不是字段

4、@Temporal 设置日期的类型
常用属性:
value 取值说明:
TemporalType.DATE 日期
TemporalType.Time 时间
TemporalType.TIMESTAMP 日期+时间

5、@Lob 设置大数据的类型 对应的blob或clob

3、主键:
1、@Id 主键
2、@GeneratedValue 自增策略
常用属性:
1、strategy 使用自带的增长机制
GenerationType
2、generator 使用自定义的增长策略

@GenericGenerator(name = "assigned",strategy = "七中主键增长策略")//定义增长策略
@GeneratedValue(generator = "assigned")//使用自定义的增长策略


4、多表关系
1、@OneToOne 一对一
常用属性:
1、targetEntity 目标类的Class对象
2、mappedBy 设置关联属性
3、fetch 设置加载类型 --lazy
取值: FetchType.EAGER 立即加载 FetchType.LAZY 懒加载
4、cascade 设置级联关系
取值:
CascadeType.PERSIST 级联保存
CascadeType.ALL 所有
CascadeType.MERGE 修改
CascadeType.REMOVE 删除
CascadeType.REFRESH 刷新
CascadeType.DETACH 不使用级联 none
2、@JoinColumn 设置外键字段 ,关联字段
常用属性:
name 字段名称
3、@Fetch
标记抓取策略
多表关系中,如何关联查询相关表
取值:
FetchMode.JOIN 使用连接查询
FetchMode.SELECT 使用独立好像
4、@ManyToOne---一般是拥有外键
标记多对一
常用属性:
targetEntity
cascade
5、@OneToMany
一对多
常用属性:
mappedBy 设置关联属性
6、@ManyToMany
多对多--隐式
常用属性:
targetEntity
7、@JoinTable
设置关联表
常用属性:
name 关联表表名
joinColumns 数组 标记当前表在关联表中的外键名称 使用的@JoinColumn
inverseJoinColumns 数组 标记另一个表在关联表中的外键名称 使用的@JoinColumn

 

基于注解的映射配置:
<mapping class="包名.类名">

 

 

 

 

  

 

 

 

 

 

 

 

 

 

 

 

 

 

           

           

                        

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/Leroyo/p/8324817.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值