zoukankan      html  css  js  c++  java
  • Hibernate 基础解析(Configuration,SessionFactory,Session,Transaction,Query,Criteria)

    1       框架体系结构

       对象关系映射(英语:(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实

    现面向对象编程语言里不同类型系统的数据之间的转换[1]  。从效果上说,它其实是创建了一个可在编程语言里使用的--“虚拟

    对象数据库”。

    2       hibernate入门

    2.1   ORM框架

      对象关系映射(英语:(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实

    现面向对象编程语言里不同类型系统的数据之间的转换[1]  。从效果上说,它其实是创建了一个可在编程语言里使用的--“虚拟

    对象数据库”。

    Hibernate是一个数据持久化层的ORM框架.

    Object:对象,java对象,此处特指JavaBean

    Relational:关系,二维表,数据库中的表。

    映射|映射元数据:对象中属性,与表的字段,存在对应关系。

       

    2.2   什么是hibernate

       Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,

    是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。

    Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,

    Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。

      Hibernate是轻量级JavaEE应用的持久层解决方案,是一个关系数据库ORM框架

    • ORM 就是通过将Java对象映射到数据库表,通过操作Java对象,就可以完成对数据表的操作

      Hibernate提供了对关系型数据库增删改成操作

    2.3   主流的ORM框架

      JPA Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系(只有接口规范)

      Hibernate 最流行ORM框架,通过对象-关系映射配置,可以完全脱离底层SQL

      MyBatis  本是apache的一个开源项目 iBatis,支持普通 SQL查询,存储过程和高级映射的优秀持久层框架

      Apache DBUtils 、Spring JDBCTemplate

    2.4   优点

      Hibernate对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码

      Hibernate是一个基于jdbc的主流持久化框架,是一个优秀的orm实现,它很大程度的简化了dao层编码工作  session.save(User);

      Hibernate使用java的反射机制

      Hibernate的性能非常好,因为它是一个轻量级框架。映射的灵活性很出色。它支持很多关系型数据库,从一对一到多对多的各种复杂关系

    3       入门案例【掌握】

    3.1   编写流程

    l  1. 导入jar包

    l  2. 创建数据库和表

    l  3. 编写核心配置文件(hibernate.cfg.xml)--> 配置获得链接等参数

    l  4. 编写映射文件 hibernate mapping(*.hbm.xml)

    l  5 使用api测试

    3.2   数据库和表

    3.3   导入jar包 

    l  版本:3.6.10   --> hibernate 4 建议注解开发,hibernate 4 对 3 不兼容。

    l  目录结构

       

        

    l  jar介绍

        Hibernate3.jar

           核心:

           必须:lib equired

           jpa规范:libjpa

        Mysql-connector-java-5.0.8-bin.jar

           mysql驱动:

     

    3.4   编写JavaBean + 映射文件

    l  文件位置:javabean同包

    l  文件名称:javabean同名

    l  扩展名:*.hbm.xml

    l  内容:

           添加约束

                 hibernate3.jar 下 org.hibernate 下 的 hibernate-mapping-3.0.dtd  

     1 <!DOCTYPE hibernate-mapping PUBLIC
     2 
     3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
     4 
     5     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
     6 
     7 <hibernate-mapping>
     8 
     9    <class name="com.itheima.a_hello.User" table="t_user">
    10 
    11       <!-- 主键 -->
    12 
    13       <id name="uid">
    14 
    15          <!-- 固定值:主键生成策略 -->
    16 
    17          <generator class="native"></generator>
    18 
    19       </id>
    20 
    21       <!-- 普通属性 -->
    22 
    23       <property name="username"></property>
    24 
    25       <property name="password"></property>
    26 
    27    </class>
    28 
    29 </hibernate-mapping>
    映射文件

    3.5   编写核心配置文件

    l  位置:类路径(classpath、src)-->WEB-INF/classes

    l  名称:hibernate.cfg.xml

    l  内容:

                  添加约束

     1 <!DOCTYPE hibernate-configuration PUBLIC
     2 
     3    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
     4 
     5    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
     6 
     7 <hibernate-configuration>
     8 
     9    <!-- SessionFactory,相当于之前学习连接池配置 -->
    10 
    11    <session-factory>
    12 
    13       <!-- 1 基本4项 -->
    14 
    15       <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    16 
    17       <property name="hibernate.connection.url">jdbc:mysql:///h_day01_db</property>
    18 
    19       <property name="hibernate.connection.username">root</property>
    20 
    21       <property name="hibernate.connection.password">1234</property>
    22 
    23   
    24 
    25       <!-- 添加映射文件 -->
    26 
    27       <mapping resource="com/itheima/a_hello/User.hbm.xml"/>
    28 
    29    </session-factory>
    30 
    31  
    32 
    33 </hibernate-configuration>
    hibernate.xml

    3.6   测试 

     1 @Test
     2 
     3    public void demo01(){
     4 
     5       User user = new User();
     6 
     7       user.setUsername("伟哥哥");
     8 
     9       user.setPassword("1234");
    10 
    11      
    12 
    13      
    14 
    15       //1 加载配置文件获得核心配置对象
    16 
    17       Configuration config = new Configuration().configure();
    18 
    19       //2 获得工厂 SessionFactory,相当于连接池
    20 
    21       SessionFactory factory = config.buildSessionFactory();
    22 
    23       //3获得会话session,相当于链接Connection
    24 
    25       Session session = factory.openSession();
    26 
    27       //4 开启事务
    28 
    29       Transaction transaction = session.beginTransaction();
    30 
    31      
    32 
    33       //操作
    34 
    35       session.save(user);
    36 
    37      
    38 
    39       //5 提交事务 | 回滚事务
    40 
    41       transaction.commit();
    42 
    43       //6 释放资源--关闭session
    44 
    45       session.close();
    46 
    47       //7 释放资源--关闭工厂factory
    48 
    49       factory.close();
    50 
    51    }
    Test

    3.7   注意事项 

           将映射文件添加到核心配置文件中  hbm.xml  --> hibernate.cfg.xml

    4       api详解【多练】

    4.1   体系结构

     

    PO:persistent object ,用于与数据库交互数据。--dao层  (JavaBean + hbm )

    BO:Business object 业务数据对象。--service层

    VO:Value Object 值对象。--web层

    开发中:直接使用JavaBean 描述三个对象。

    4.2   Configuration 配置对象

    l  hibernate 核心配置文件种类

           hibernate.cfg.xml 通常使用xml配置文件,可以配置内容更丰富。

           hibernate.properties 用于配置key/value 形式的内容,key不能重复的。配置有很多的局限性。一般不用。

                  参考文件:hibernate-distribution-3.6.10.Finalprojectetc hibernate.properties

                         提供了核心配置文件常用的配置项,及选择参数。

    1.提供构造  new Configuration()    hibernate将自动加载 hibernate.properties文件

                                                          hibernate.properties文件必须存放在类路径(src)下

    2.提供方法 configure() 将加载src下的hibernate.cfg.xml

    3.扩展api(如果核心配置文件不符合默认加载规则)

           configure(String  path ) 加载指定目录下的 xml文件

           configure(File  file) 通过file加载指定的xml文件。

    4.手动加载配置文件(User.hbm.xml)

                  (推荐在 hibernate.cfg.xml 文件中使用  <mapping resource="com/itheima/a_hello/User.hbm.xml"/>  加载配置文件)

            手动加载指定的配置文件

               config.addResource("com/ittest/a_Test/User.hbm.xml");

            手动加载指定类,对应的映射文件 User--> User.hbm.xml

                config.addClass(User.class);

    l  常见异常:

           开发中:将hbm.xml映射 配置 hibernate.cfg.xml

           学习中:可以使用 addClass  或 addResource

    4.3   SessionFactory工厂

    l  SessionFactory 相当于java web连接池,用于管理所有session

    l  获得方式:config.buildSessionFactory();

    l  sessionFactory hibernate缓存配置信息 (数据库配置信息、映射文件,预定义HQL语句 等)

    l  SessionFactory线程安全,可以是成员变量,多个线程同时访问时,不会出现线程并发访问问题。

    l  提供api:

          打开一个新的会话 session

              factory.openSession();

          获得当前线程中绑定的会话session

              factory.getCurrentSession();

                  hibernate支持,将创建的session绑定到本地线程中,底层使用ThreadLocal,在程序之间共享session。

                         1.必须在hibernate.cfg.xml 配置

    <!-- 2 与本地线程绑定 -->

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

       

                         2.如果提交或回滚事务,底层将自动关闭session

    4.4   Session 会话

    l  Session 相当于 JDBC的 Connection -- 会话

          

    l  通过session操作PO对象 --增删改查

    l  session单线程,线程不安全,不能编写成成员变量。

    l  session api

    l   

            save  保存

     

           update  更新

     

           delete  删除

     

           get  : 通过id查询,如果没有 null;(其一查询就立刻使用sql语句查询数据库,并返回对象)

     

      load : 通过id查询,如果没有就会抛异常;(其查询的时候只是给程序反回了一个代理对象,当我们要使用这个对象的时候,

                           代理对象才会使用session发送sql语句到数据库进行查询,并初始化属性)

                                特点: 继承代理, 一次查询(有一个初始化标记变量)

                                优点: 使用延迟加载,提高了运行效率(对于不需要具体内容的查询时可以使用load )

     

           createQuery("hql")  : 获得Query对象(然后查询数据库所有数据)

                                         Query   query = session.createQuery("from com.itheima.a_hello.User");

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

           createCriteria(Class)   : 获得Criteria对象(然后查询数据库所有数据)

                                       Criteria   criteria = session.createCriteria(User.class);

                                       List<User>   list =    criteria.list();

           CreateSQLQuery(“SQL”)   : 获得SQLQuery对象(然后查询数据库中所有的数据,并指定封装对象)

                                       SQLQuery   query = session.createSQLQuery("select * from t_user");                                                               

                      query.addEntity(User.class); (指定封装对象)

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

    4.5   Transaction 事务

    开启事务 beginTransaction() : 开启一个新的事物。

    获得事务 getTransaction()   : 获得一个绑定在此线程上的事物。

    提交事务:commit()

    回滚事务:rollback()

           (事务关闭时,会自动把与当前线程关联的session关闭,并删除)

    try{

       //开启

       //session操作

       //提交

    } catch(e){

       //回滚

    }

    扩展:不需要手动的管理事务,之后所有的事务管理都交予spring。

    4.6   Query对象

    l  hibernate执行hql语句

    l  hql语句:hibernate提供面向对象查询语句,使用对象(类)和属性进行查询。区分大小写。

    l  获得 session.createQuery("hql")

    l  方法:

           list()  查询所有

           uniqueResult() 获得一个结果。如果没有查询到返回null,如果查询多条则抛返回异常。

           setFirstResult(int) 分页,开始索引数startIndex

           setMaxResults(int) 分页,每页显示个数 pageSize

    4.7   Criteria对象(了解)

    l  QBC(query by criteria),hibernate提供纯面向对象查询语言,提供直接使用PO对象进行操作。

    l  获得方式:Criteria  criteria   =   session.createCriteria(User.class);

    l  条件

      criteria.add(Restrictions.eq("username", "tom"));

            Restrictions.gt(propertyName, value)    大于

            Restrictions.ge(propertyName, value) 大于等于

            Restrictions.lt(propertyName, value) 小于

            Restrictions.le(propertyName, value) 小于等于

            Restrictions.like(propertyName, value)  模糊查询,注意:模糊查询值需要使用 % _   。

       之后也要使用uniqueResult方法。(也可以直接使用lis方法查找全部)

    4.8   工具类

     1 s H3Utils {
     2 
     3   
     4 
     5    // 会话工厂,整个程序只有一份。
     6 
     7    private static SessionFactory factory;
     8 
     9  
    10 
    11    static{
    12 
    13       //1 加载配置
    14 
    15       Configuration config = new Configuration().configure();
    16 
    17      
    18 
    19       //2 获得工厂
    20 
    21       factory = config.buildSessionFactory();
    22 
    23 //3 关闭虚拟机时,释放SessionFactory
    24 
    25          Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
    26 
    27         
    28 
    29          @Override
    30 
    31          public void run() {
    32 
    33             System.out.println("虚拟机关闭!释放资源");
    34 
    35             sf.close();
    36 
    37          }
    38 
    39       }));
    40 
    41    }
    42 
    43   
    44 
    45   
    46 
    47    /**
    48 
    49     * 获得一个新的session
    50 
    51     * @return
    52 
    53     */
    54 
    55    public static Session openSession(){
    56 
    57       return factory.openSession();
    58 
    59    }
    60 
    61   
    62 
    63    /**
    64 
    65     * 获得当前线程中绑定session
    66 
    67     * * 注意:必须配置
    68 
    69     * @return
    70 
    71     */
    72 
    73    public static Session getCurrentSession(){
    74 
    75       return factory.getCurrentSession();
    76 
    77    }
    78 
    79   
    80 
    81 }
    工具类

    5       核心配置文件详解

    5.1   详细配置

    <!-- SessionFactory,相当于之前学习连接池配置 -->

       <session-factory>

          <!-- 1 基本4项 -->

          <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>

          <property name="hibernate.connection.url">jdbc:mysql:///h_day01_db</property>

          <property name="hibernate.connection.username">root</property>

          <property name="hibernate.connection.password">1234</property>

      

          <!-- 2 与本地线程绑定 -->

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

     

          <!-- 3 方言:为不同的数据库,不同的版本,生成sql语句(DQL查询语句)提供依据

             * mysql 字符串 varchar

             * orcale 字符串 varchar2

          -->

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

         

          <!-- 4 sql语句 -->

          <!-- 显示sql语句 -->

          <property name="hibernate.show_sql">true</property>

          <property name="hibernate.format_sql">true</property>

      

          <!-- 5 自动创建表(了解) ,学习中使用,开发不使用的。

             * 开发中DBA 先创建表,之后根据表生产 PO类

             * 取值:

             update:【】

                如果表不存在,将创建表。

                如果表已经存在,通过hbm映射文件更新表(添加)。(映射文件必须是数据库对应)

                    表中的列可以多,不负责删除。

             create :如果表存在,先删除,再创建。程序结束时,之前创建的表不删除。【】

             create-drop:与create几乎一样。如果factory.close()执行,将在JVM关闭同时,将创建的表删除了。(测试)

             validate:校验 hbm映射文件 和 表的列是否对应,如果对应正常执行,如果不对应抛出异常。(测试)

          -->

          <property name="hibernate.hbm2ddl.auto">create</property>

         

          <!-- 6 java web 6.0 存放一个问题

             * BeanFactory 空指针异常

                异常提示:org.hibernate.HibernateException: Unable to get the default Bean Validation factory

             * 解决方案:取消bean校验

          -->

          <property name="javax.persistence.validation.mode">none</property>

      

          <!-- 添加映射文件

             <mapping >添加映射文件

                resource 设置 xml配置文件 (addResource(xml))

                class 配置类 (addClass(User.class)) 配置的是全限定类名

          -->

          <mapping  resource="com/itheima/a_hello/User.hbm.xml"/>

       </session-factory>

    6       Hibernate中持久化类

    6.1   编写规则

    • 提供一个无参数 public访问控制符的构造器
    • 提供一个标识属性,映射数据表主键字段
    • 所有属性提供public访问控制符的 set  get 方法(javaBean)
    • 标识属性应尽量使用基本数据类型的包装类型
    • 不要用final修饰实体 (将无法生成代理对象进行优化)

    6.2   持久化对象的唯一标识 OID

    l  Java按地址区分同一个类的不同对象.

    l  关系数据库用主键区分同一条记录

    l  Hibernate使用OID来建立内存中的对象和数据库中记录的对应关系

    结论: 对象的OID和数据库的表的主键对应。为保证OID的唯一性,应该让Hibernate来为OID付值

    6.3   区分自然主键和代理主键

    l  主键需要具备:    不为空/不能重复/不能改变

                  自然主键:      在业务中,某个属性符合主键的三个要求.那么该属性可以作为主键列.

                  代理主键:     在业务中,不存符合以上3个条件的属性,那么就增加一个没有意义的列.作为主键.

    6.4   基本数据与包装类型

    l  基本数据类型和包装类型对应hibernate的映射类型相同

    l  基本类型无法表达null、数字类型的默认值为0。

    l  包装类默认值是null。当对于默认值有业务意义的时候需要使用包装类。

    6.5   类型对应

    Java数据类型

    Hibernate数据类型

    标准SQL数据类型
    (PS:对于不同的DB可能有所差异)

    byte、java.lang.Byte

    byte

    TINYINT

    short、java.lang.Short

    short

    SMALLINT

    int、java.lang.Integer

    integer

    INGEGER

    long、java.lang.Long

    long

    BIGINT

    float、java.lang.Float

    float

    FLOAT

    double、java.lang.Double

    double

    DOUBLE

    java.math.BigDecimal

    big_decimal

    NUMERIC

    char、java.lang.Character

    character

    CHAR(1)

    boolean、java.lang.Boolean

    boolean

    BIT

    java.lang.String

    string

    VARCHAR

    boolean、java.lang.Boolean

    yes_no

    CHAR(1)('Y'或'N')

    boolean、java.lang.Boolean

    true_false

    CHAR(1)('Y'或'N')

    java.util.Date、java.sql.Date

    date

    DATE

    java.util.Date、java.sql.Time

    time

    TIME

    java.util.Date、java.sql.Timestamp

    timestamp

    TIMESTAMP

    java.util.Calendar

    calendar

    TIMESTAMP

    java.util.Calendar

    calendar_date

    DATE

    byte[]

    binary

    VARBINARY、BLOB

    java.lang.String

    text

    CLOB

    java.io.Serializable

    serializable

    VARBINARY、BLOB

    java.sql.Clob

    clob

    CLOB

    java.sql.Blob

    blob

    BLOB

    java.lang.Class

    class

    VARCHAR

    java.util.Locale

    locale

    VARCHAR

    java.util.TimeZone

    timezone

    VARCHAR

    java.util.Currency

    currency

    VARCHAR

    6.6   普通属性

    <hibernate-mapping>

             package 用于配置PO类所在包

                例如: package="com.itheima.d_hbm"

          <class> 配置 PO类 和 表 之间对应关系

             name:PO类全限定类名

                例如:name="com.itheima.d_hbm.Person"

                如果配置 package,name的取值可以是简单类名 name="Person"

             table : 数据库对应的表名

             dynamic-insert="false" 是否支持动态生成insert语句

             dynamic-update="false" 是否支持动态生成update语句

                如果设置true,hibernate底层将判断提供数据是否为null,如果为null,insert或update语句将没有此项。

          普通字段

             <property>

                name : PO类的属性

                column : 表中的列名,默认name的值相同

                type:表中列的类型。默认hibernate自己通过getter获得类型,一般情况不用设置

                    取值1: hibernate类型

                       string 字符串

                       integer 整形

                    取值2: java类型 (全限定类名)

                       java.lang.String 字符串

                    取值3:数据库类型

                       varchar(长度) 字符串

                       int 整形

                       <property name="birthday">

                          <column name="birthday" sql-type="datetime"></column>

                       </property>

                       javabean 一般使用类型 java.util.Date

                       jdbc规范提供3中

                          java类型           mysql类型

                          java.sql.Date      date

                          java.sql.time      time

                          java.sql.timestamp timestamp

                          null            datetime

                         

                          以上三个类型都是java.util.Date子类

                         

                length : 列的长度。默认值:255

                not-null : 是否为null

                unique : 是否唯一

                access:设置映射使用PO类属性或字段

                    property : 使用PO类属性,必须提供setter、getter方法

                    field : 使用PO类字段,一般很少使用。

                insert 生成insert语句时,是否使用当前字段。

                update 生成update语句时,是否使用当前字段。

                    默认情况:hibernate生成insert或update语句,使用配置文件所有项

          注意:配置文件如果使用关键字,列名必须使用重音符

    6.7   主键

    主键

             <id>配置主键

                name:属性名称

                access="" 设置使用属性还是字段

                column=""  表的列名

                length=""  长度

                type="" 类型

             <generator> class属性用于设置主键生成策略

                1.increment 由hibernate自己维护自动增长

                    底层通过先查询max值,再+1策略

                    不建议使用,存在线程并发问题

                2.identity hibernate底层采用数据库本身自动增长列

                    例如:mysql auto_increment

                3.sequence hibernate底层采用数据库序列

                    例如:oracle 提供序列

                4.hilo

                   

                    </generator>

                5.native 根据底层数据库的能力选择 identity、sequence 或者 hilo 中的一个。【】

                ##以上策略使用整形,long, short 或者 int 类型

                6.uuid 采用字符串唯一值【】

                ##以上策略 代理主键,有hibernate维护。

                7.assigned 自然主键,由程序自己维护。【】

  • 相关阅读:
    【深入理解JAVA虚拟机】第一部分.走进Java
    【设计模式最终总结】桥接模式 VS 外观模式
    【设计模式最终总结】组合模式:树形结构的处理
    【设计模式最终总结】桥接模式(接口模式):处理多维度变化
    【设计模式最终总结】适配器模式
    深入编解码:ASCII,UNICODE,UTF8等
    好妈妈【第四章】培养良好的学习习惯
    【设计模式最终总结】建造者模式:复杂对象的组装与创建
    上火流鼻血
    Spring Data Jpa 学习笔记
  • 原文地址:https://www.cnblogs.com/soficircle/p/7073891.html
Copyright © 2011-2022 走看看