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. python操作pymysql数据库

    首先需要导入通过import pymysql导入数据库模块 已经创建好一个数据库test,数据库中有一个空表t,只有两个字段id int(5),name varchar(20) import pymy ...

  2. 面试官问我“Java中的锁有哪些?以及区别”,我跪了

    在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类.介绍的内容如下: 公平锁/非公平锁 可重入锁 独享锁/共享锁 互斥锁/读写锁 乐观锁/悲观锁 分段锁 偏向锁/轻量级 ...

  3. 动态令牌验证遇到的问题(判断用户长按backspace键)

    因为最近负责泰康项目的前端工作,他们的登录需要进行安全验证,也就是所谓的双因素验证,即在OA平台登录过后,还需要安全部门发送安全令牌进行验证.令牌验证效果如下: 主要功能有:1.默认第一项focus. ...

  4. 软件测试3gkd

        一.单元测试的任务 单元测试主要是对软件的基本组成单元进行测试,且所测试单元与程序的其他部分在测试中相隔离. 在单元测试中,我们需要对与程序构建中的单位测试以保证其可靠运行与代码规范. 单元测 ...

  5. javascript自定义一个全类型读取的函数

    我爱撸码,撸码使我感到快乐!大家好,我是Counter.因为我们知道,在JavaScript中有自带的方法可以读取类型,但是不很全面,今天来分享下如何自己定义一个函数,将所有传入参数的类型给打印出来, ...

  6. VS2110。VC++编译错误"error LNK2005: 已经在 XXX.obj 中定义的问题"

    有时候我们会在头文件当中定义一些全局变量或者全局函数,这种做法会比较方便,但有时候会出现“编译错误"error LNK2005: 已经在 XXX.obj 中定义的问题"的链接问题. ...

  7. 【ASP.NET】 HttpContext.Current.User.Identity.Name 返回值为空

    问题起因 在做项目的时候,我使用HttpContext.Current.User.Identity.Name来获取Web应用程序正在使用时的用户名. 在开发过程中,我使用了我的本地iis,启用了集成的 ...

  8. Java问题解决:使用maven install 和 package时出错

    今天在idea中使用maven install 和 package时出现以下问题: [WARNING] The POM for org.apache.maven.plugins:maven-compi ...

  9. Ctrl+Alt+Down/Up 按键冲突

    I mapped Ctrl-Alt-Up/Down to open web-browser and email client but it didn't take effect. Ctrl-Alt-U ...

  10. vi编程技巧:

    h #向上j #向左k #向右l #向下a #插入o #插入一行,并在行首开始O #在当前行前插入一行,并在行首开始dd #删除当前行x #删除当前字符yy #复制当前行p #在当前行后面粘贴P #在 ...