Hibernate -----总结

一、在使用Hibernate的时候

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

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

二、准备工作

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

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

 <?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="包名">
<class name="类名" table="类对应的表名">
<id name="类中要作为主键的属性" column="no" length="200">
<generator class="主键生成策略"></generator>
</id> <property name="money" column="money"></property>
<property name="createTime" column="createTime"></property>
<property name="status" column="status"></property> <!--集合属性的配置-->
<set name="orderItems">
<key column="ono"></key>
<one-to-many class="OrderItem"></one-to-many>
</set> </class> </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="包名.类名">

 

  

           

           

                        

 

Hibernate-----阶段总结的更多相关文章

  1. 浅谈JavaWeb架构演变

    一  JavaWeb架构演变 在java架构模式中,我们可以将MVC架构模式抽象为如下结构: 1.View层.View层即UI层,可采用的技术如JSP,Structs,SpringMVC等 2.Con ...

  2. srm开发(基于ssh)(4)

    1 input处理内容补充 -在struts2里面有错误处理机制,当上传文件超过默认的大小,自动返回结果input -在struts.xml中配置input的返回结果 <!-- 配置input结 ...

  3. Hibernate 小阶段总结

    (一)Hibernate入门 通俗的话来说:Hibernate是用于面向对象操控数据库,对JDBC进行轻量级封装.(在java世界中传统的来说是JDBC访问数据库.) 1)Hibernate定性:对象 ...

  4. 深入浅出Struts2+Spring+Hibernate框架

    一.深入浅出Struts2 什么是Struts2? struts2是一种基于MVC的轻量级的WEB应用框架.有了这个框架我们就可以在这个框架的基础上做起,这样就大大的提高了我们的开发效率和质量,为公司 ...

  5. Hibernate(1)——数据访问层的架构模式

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及到的知识点总结如下: 数据库的概念.逻辑.数据模型概念 应用程序的分层体系结构发展 MVC设计模式与四层结构的对应关系 持久层的设 ...

  6. Hibernate 系列 07 - Hibernate中Java对象的三种状态

    引导目录: Hibernate 系列教程 目录 1. Java对象的三种状态 当应用通过调用Hibernate API与框架发生交互时,需要从持久化的角度关注应用对象的生命周期. 持久化声明周期是Hi ...

  7. hibernate+mysql的连接池配置

    1:连接池的必知概念    首先,我们还是老套的讲讲连接池的基本概念,概念理解清楚了,我们也知道后面是怎么回事了. 以前我们程序连接数据库的时候,每一次连接数据库都要一个连接,用完后再释放.如果频繁的 ...

  8. Hibernate配置方式

    Hibernate配置方式 Hibernate给人的感受是灵活的,要达到同一个目的,我们可以使用几种不同的办法.就拿Hibernate配置来说,常用的有如下三种方式,任选其一. 在 hibernate ...

  9. 【Hibernate框架】关联映射(一对多,多对一)

    根据我们的总结计划,上篇文章我们总结了有关于一对一映射相关知识,接下来,我们进行下一个阶段,一对多.多对一映射相关知识. 场景设定: 国家规定,一个人只能在一个公司上班,一个公司可以拥有很多员工.我们 ...

  10. 浅谈Hibernate入门

    前言 最近打算做一个自己的个人网站,经过仔细思考,打算使用hibernate作为开发的ORM框架,因此各种找资料,由于本人是刚刚接触这技术的,所以就找了比较基础的知识来分享下 基本概述 Hiberna ...

随机推荐

  1. 前端框架bootstrap(响应式布局)入门

    Bootstrap,是基于HTML,CSS.javascript的前端框架 该框架已经预定义了一套CSS样式和与样式相对应的js代码(对应的样式有对应的特效.) 开发人员只需要编写HTML结构,添加b ...

  2. archer docker安装部署

    1.准备配置文件从archer项目官网下载/archer/settings.py文件,根据自己情况放到相应的目录我下载后放到如下目录[root@lenovo opt]# mkdir -p /opt/a ...

  3. IDEA修改显示星号*和热部署

    IDEA修改显示*星号: IDEA热部署: 两步: 1. 2. Ctrl+Alt+Shift+/ 打开下面界面,选Registry 对于Springboot应用,可能无法启动,在上述两步不起作用的情况 ...

  4. windows微信双开

    下面的代码写到xxx.bat文件中 @echo off start /d "D:\software\WeChat\" WeChat.exe start /d "D:\so ...

  5. topcoder srm 625 div1

    problem1 link 假设第$i$种出现的次数为$n_{i}$,总个数为$m$,那么排列数为$T=\frac{m!}{\prod_{i=1}^{26}(n_{i}!)}$ 然后计算回文的个数,只 ...

  6. heartbeat 非联网安装(通过配置本地yum文件库安装heartbeat)

    软件环境:centos6.5 一.下载rpm包 首先找一台联网的centos6.5机器 安装epel扩展源: yum install -y epel-release 安装yum-plugin-down ...

  7. dvi接口介绍

    Most graphics cards and motherboards feature a Digital Video Interface (DVI) connector for connectin ...

  8. 创建X个任意元素数组并且可以遍历的的一个方法

    方法一: Array.apply(null, { length: 20 })分析:apply 第二个参数应该是数组,现在把 { length: 20 } 转化为数组,就是一个长度为X的数组(类数组对象 ...

  9. [English] Time complexity wise this solution is the best among all

    Time complexity wise this solution is the best among all, we can do all operations in O(1) time. 时间复 ...

  10. LeetCode--031--下一个排列(java)*

    实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只允许使用额外常数空间. ...