[ SSH框架 ] Hibernate框架学习之一

一、CRM概述

1.什么是CRM

 CRM(Customer Realationship Management)客户关系管理,是利用相应的技术信息以及互联网技术来协调企业与顾客间在销售、营销和服务上的交互,向客户提供创新式的个性化的客户交互和服务的过程。其最终目标是将面向客户的各项信息和活动集成起来,组建一个以客户为中心的企业,实现对面向客户的活动的全面管理。

2.CRM功能模块

CRM系统实现了对企业销售、营销、服务等各阶段的客户信息、客户活动进行统一管理。

  CRM系统功能涵盖企业销售、营销、用户服务等各各业务流程,业务流程中与客户相关活动都会在CRM系统统一管理,下边列出一些基本的功能模块,包括:客户信息管理、联系人管理、商机管理、统计分析等 ,CRM系统表如下:

  • 客户信息管理:对客户信息统一维护,客户是指存量客户或拟营销的客户,通过员工录入形成公司的“客户库”,是公司最重要的数据资源。
  • 联系人管理:对客户的联系人信息统一管理,联系人是指客户企业的联系人,即企业的业务人员和客户的哪些人在打交道。
  • 客户拜访管理:业务员(用户)要开发客户需要去拜访客户,客户拜访信息记录了业务员与客户沟通交流方面的不足、采取的策略不当、有待改进的地方或值得分享的沟通技巧等方面的信息。
  • 综合查询:客户相关信息查询,包括:客户信息查询、联系人信息查询、商机信息查询等。
  • 统计分析:按分类统计客户信息,包括:客户信息来源统计、按行业统计客户、客户发展数量统计等。
  • 系统管理:系统管理属于crm系统基础功能模块,包括:数据字典、账户管理、角色管理、权限管理、操作日志管理等。

3.JavaEE开发三层结构和三大框架的对应关系:

Struts2框架 -> 表现层   web层(MVC是表现层的设计模型)

业务层   service层

Hibernate框架 -> 持久层   dao层

Spring框架 ->综合类框架

二、Hibernate概述

1.什么是Hibernate

Hibernate框架是当今主流的Java持久层框架之一,由于它具有简单易学、灵活性强、扩展性强等特点,能够大大地简化程序的代码量,提高工作效率,因此受到广大开发人员的喜爱。          

  Hibernate是一个开放源代码的ORM( Object Relational Mapping,对象关系映射)框架,它对JDBC进行了轻量级的对象封装,使得Java开发人员可以使用面向对象的编程思想来操作数据库。它是一个轻量级、企业级、开源的持久层框架(通常情况下,软件工程的持久层解决方案,一个为主一个为辅(写SQL语句(JDBC和DBUtils)和不写SQL语句(Hibernate))),可以操作数据库的框架(框架:一个架构)。

Tips:ORM (Object Relational Mapping):对象关系映射,建立实体类和数据库表的对应关系,实现操作类对象就相当于操作数据库。

       操作方式:建立对象关系映射,实现操作实体类就相当于操作数据库表

Tips:轻量级:使用时依赖资源很少(目前使用阶段,只依赖log4j,c3p0连接池)

       企业级:指的是在企业级应用中使用的较多

     开源的:开放源代码

2.为什么要学习Hibernate

使用传统的JDBC开发应用系统时,如果是小型应用系统,并不觉得有什么麻烦,但是对于大型应用系统的开发,使用用JDBC就会显得力不从心。例例如对几十、几百张包含几十个字段的表进行插入操作时,编写的SQL语句不但很长,而且繁琐,容易出错;在读取数据时,需要写多条 getXxx 语句从结果集中取出各个字段的信息,不但枯燥重复,并且工作量非常大。为了提高数据访问层的编程效, Gavin King开发出了一个当今最流行的的ORM框架,它就是 Hibernate 框架。

  所谓的ORM就是利用描述对象和数据库表之间映射的元数据,自动把Java应用程序中的对象,持久化到关系型数据库的表中。通过操作Java对象,就可以完成对数据库表的操作。可以把ORM理解为关系型数据和对象的一个纽带,开发人员只需要关注纽带一端映射的对象即可。ORM原理如下图所示:

与其它操作数据库的技术相比, Hibernate具有以下几点优势

    ● Hibernate对JDBC访问数据库的代码做了轻量级封装,大大简化了数据访问层繁琐的重复性代码,并且减少了内存消耗,加快了运行效率;

    ● Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现,它很大程度的简化了DAO( Data Access Object,数据访问对象)层编码工作;

    ● Hibernate的性能非常好,映射的灵活性很出色。它支持很多关系型数据库,从一对一到多对多的各种复杂关系;

    ● 可扩展性强,由于源代码的开源以及API的开放,当本身功能不够用时,可以自行编码进行扩展。

3.常用的持久层技术有哪些:

JDBC:操作数据库最底层的方式

    优势:底层、效率高

    弊端:编写代码时比较繁琐,尤其是封装结果集

DBUtils:基于JDBC进行了简单封装

    优势:封装结果集操作变得简单,并且仍然是自己编写SQL语句,相对效率没有太大影响

    弊端:要求实体类中属性名和数据库表的字段名必须一致

       要求记忆东西较多

  共同点:都要求自己书写SQL语句

  使用JDBC和DBUtils操作产品表的时遇到的问题:

      JDBC:查询封装结果时繁琐

      DBUtils:保存或更新时繁琐 

三、Hibernate入门

1.下载Hibernate5

百度网盘下载链接:https://pan.baidu.com/s/1wbkfaO4wN9c2lMPgb5H40g     密码:d28q

  Hibernate下载完成解压后的文件目录结构如下:

从图可以看出, hibernate5.0.7 的解压s目录中包含一系列的子目录,这些子目录分别用于存放不同功能的文件,接下来针对这些子目录进行简单介绍,具体如下:

  ● documentation文件夹:存放 Hibernate的相关文档,包括括参考文档的API文档。

  ● lib文件夹:存放 Hibernate编译和运行所依赖的JAR包。其中 required子目录下包含了运行 Hibernate5项目必须的JAR包。

  ● project文件夹:存放 Hibernate各种相关的源代码。

在 lib/required子目录中,包含的JAR包:

2.创建数据库和表

3.引入Hibernate的开发包

数据库驱动包

Hibernate/lib/required/*.jar

记录日志的包

4.创建实体(持久化类)

持久化类是应用程序中的业务实体类,这里的持久化是指类的对象能够被持久化保存到数据库中。Hibernate使用普通Java对象( Plain Old Java Object),即POJO 的编程模式来进行持久化。POJO 类中包含的是与数据库表相对应的各个属性,这些属性通过 getter 和 setter 方法来访问,对对外部隐藏了内部的实现细节。下面就来编写 Customer持久化类。

  在项目src目录下创建com.Kevin.domain包,并在包中创建实体类 Customer(对应数据库表 cst_customer),Customer 类包含与 cst_customer数据据表字段对应的属性,以及相应的 getxxx( ) 和setxxx ( ) 方法。

package com.Kevin.domain;
/**
 * 客户的实体类
 * @author Kevin
 *
 */
public class Customer {

    private Long cust_id;    
    private String cust_name;
    private String cust_source;
    private String cust_industry;
    private String cust_level;
    private String cust_linkman;
    private String cust_phone;
    private String cust_mobile;
    public Long getCust_id() {
        return cust_id;
    }
    public void setCust_id(Long cust_id) {
        this.cust_id = cust_id;
    }
    public String getCust_name() {
        return cust_name;
    }
    public void setCust_name(String cust_name) {
        this.cust_name = cust_name;
    }
    public String getCust_source() {
        return cust_source;
    }
    public void setCust_source(String cust_source) {
        this.cust_source = cust_source;
    }
    public String getCust_industry() {
        return cust_industry;
    }
    public void setCust_industry(String cust_industry) {
        this.cust_industry = cust_industry;
    }
    public String getCust_level() {
        return cust_level;
    }
    public void setCust_level(String cust_level) {
        this.cust_level = cust_level;
    }
    public String getCust_linkman() {
        return cust_linkman;
    }
    public void setCust_linkman(String cust_linkman) {
        this.cust_linkman = cust_linkman;
    }
    public String getCust_phone() {
        return cust_phone;
    }
    public void setCust_phone(String cust_phone) {
        this.cust_phone = cust_phone;
    }
    public String getCust_mobile() {
        return cust_mobile;
    }
    public void setCust_mobile(String cust_mobile) {
        this.cust_mobile = cust_mobile;
    }
    @Override
    public String toString() {
        return "Customer [cust_id=" + cust_id + ", cust_name=" + cust_name + ", cust_source=" + cust_source
                + ", cust_industry=" + cust_industry + ", cust_level=" + cust_level + ", cust_linkman=" + cust_linkman
                + ", cust_phone=" + cust_phone + ", cust_mobile=" + cust_mobile + "]";
    }
}

5.创建映射文件

实体类 Customer 目前还不具备持久化操作的能力,而 Hibernate 需要知道实体类 Customer 映射到数据库 Hibernate 中的哪个表,以及类中的哪个属性对应数据库表中的哪个字段,这些都需要在映射文件中配置。在实体类 Customer 所在的包中,创建一个名称为 Customer.hbm.xml 的映射文件,在该文件中定义了实体类 Customer 的属性是如何映射到 cst_customer 表的列上的。

<?xml version="1.0" encoding="UTF-8"?>
<!--  
在实体类坐在包下创建一个xml文件,建议文件名称为:实体类名称+hbm.xml
导入约束:dtd约束
-->

    <!-- generator:是指定主键的生成方式,取值是固定的几个之中选一个
            native是使用本地数据库的自动增长能力
         -->

<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
<hibernate-mapping package="com.Kevin.domain">
    <class name="Customer" table="cus1_customer">
        <id name="cust_id">
            <generator class="native"></generator>
        </id>
        <property name="cust_name" column="cust_name"></property>
        <property name="cust_source" column="cust_source"></property>
        <property name="cust_industry" column="cust_industry"></property>
        <property name="cust_level" column="cust_level"></property>
        <property name="cust_linkman" column="cust_linkman"></property>
        <property name="cust_phone" column="cust_phone"></property>
        <property name="cust_mobile" column="cust_mobile"></property>
    </class>
</hibernate-mapping>

6.创建Hibernate的核心配置文件

Hibernate 的映射文件反映了持久化类和数据库表的映射信息,而 Hibernate 的配置文件则主要用来配置数据库连接以及 Hibernate 运行时所需要的各个属性的值。在项目的src下创建一个名称为hibernate.cfg.xml 的文件。

<?xml version="1.0" encoding="UTF-8"?>
<!-- 
    在类的跟路径下创建名称为hibernate.cfg.xml的配置文件
    导入约束:dtd约束
 -->
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!-- 配置SessionFactory
        SessionFactory的作用就是用于创建Session对象的
        Session对象就是hibernate中操作数据库的核心对象
    此处配置可不记忆,但要创建SessionFactory必要的三部分信息
    第一部分:
        连接数据库的信息
    第二部分:
        hibernate的可选配置
    第三部分:
        映射文件的位置
 -->
    <session-factory>
        <!--  第一部分:连接数据库的信息
        #hibernate.connection.driver_class com.mysql.jdbc.Driver
        #hibernate.connection.url jdbc:mysql:///test
        #hibernate.connection.username gavin
        #hibernate.connection.password
        #hibernate.dialect org.hibernate.dialect.MySQLDialect
        -->

        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">admin</property>  
 
        <!-- 第二部分:hibernate的可选配置 
        #hibernate.show_sql true
        #hibernate.format_sql true
        #hibernate.hbm2ddl.auto update
        -->

        <property name="hibernate.show_sql">true</property>   <!-- 是否显示hibernate生成的sql语句 -->
        <property name="hibernate.format_sql">true</property>   <!-- 是否使用格式化输出sql语句到控制台 -->

        <!-- 配置hibernate采用何种方式生成DDL语句
            update表示检测实体类的映射配置和数据库的表结构是否一致,如果不一致更新表结构
         -->
         <!-- SQL结构化查询语言:一共分为6个部分
             DDL:Data Definition Language 数据定义语言(建库、建表、修改表结构)
             DML:Data Manipulation Language
             DQL:Data Query Language
             DCL:Data Control Language    数据控制语言(授权)
             CCL:Cursor Control Language    游标控制语言(游标操作)
             TPL:Transaction Processing Language    事务处理语言(开启、提交、回滚事务)
          -->
        <property name="hibernate.hbm2ddl.auto">update</property>    

        <!-- 第三部分:映射配置文件的位置 --> 
        <mapping resource="com/Kevin/domain/Customer.hbm.xml"/>

    </session-factory>

该配置文件设置了数据库连接的相关属性以及其它的一些常用属性,并且通过 mapping 的 resource 属性将对象的映射信息加入到了 Hibernate的配置文件中。

Tips:    SQL结构化查询语言:一共分为6个部分

      DDL:Data Definition Language  数据定义语言(建库、建表、修改表结构)

      DML:Data Manipulation Language  数据库操作语言

      DQL:Data Query Language  数据库查询语言

      DCL:Data Control Language  数据控制语言(授权)

      CCL:Cursor Control Language  游标控制语言(游标操作)

      TPL:Transaction Processing Language  事务处理语言(开启、提交、回滚事务)

7.编写测试代码

在项目中新建一个名为com.Kevin.test 的包,在包中建立一个名为 HibernateDemo1.java 文件,用来测试类。

import com.Kevin.domain.Customer;

/**
 * hibernate入门案例
 * @author Kevin
 *需求:
 *    实现保存一个客户到数据库
 */

public class HibernateDemo1 {
    /**
     * 步骤分析:
     * 1.解析主配置文件
     * 2.根据配置文件SessionFactory
     * 3.根据SessionFactory创建Session
     * 4.开启事务
     * 5.执行操作(保存)
     * 6.提交事务
     * 7.释放资源
     */
    @Test
    public void test1(){
        Customer c=new Customer();
        c.setCust_name("Kevin");
        c.setCust_level("CET-6");
        c.setCust_mobile("666");
        c.setCust_source("China");
        Configuration cfg=new Configuration();
        cfg.configure();
        SessionFactory factory=cfg.buildSessionFactory();
        Session session=factory.openSession();
        Transaction tx=session.beginTransaction();
        session.save(c);
        tx.commit();
        session.close();
        factory.close();        
    }
}

首先创建 Configuration 类的实例,并通过它来读取并解析配置文件 hibernate.cfg.xml ,然后创建 Sessionfactory 读取解析映射文件信息,并将 Configuration 对对象中的所有配置信息拷贝到Sessionfactory 内存中。接下来打开 Session,让 SessionFactory 提供连接,并开启一个Transaction 事务,之后创建对象,向对象中添加数据,通过 session. save( ) 方法完成向数据库中保存数据的操作。最后提交事务,并关闭资源。

四、Hibernate的常见配置

1. 映射文件的配置

 该文件用于向Hibernate 提供持久化类到关系型数据库的映射,每个映射文件的基本结构都是相同的,其普遍的代码形式如下:

<?xml version="1.0" encoding="UTF-8"?>
<!--  
在实体类坐在包下创建一个xml文件,建议文件名称为:实体类名称+hbm.xml
导入约束:映射文件dtd约束信息
-->

    <!-- generator:是指定主键的生成方式,取值是固定的几个之中选一个
            native是使用本地数据库的自动增长能力
         -->

<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
<hibernate-mapping package="com.Kevin.domain">
    <!-- name代表实体类名,table代表数据库中的表名 -->
    <class name="Customer" table="cus1_customer">
        <!-- name表示实体类中的属性名称,column表示数据库中标的字段 -->
        <id name="cust_id" column="cust_id">
            <!-- 主键生成策略 -->
            <generator class="native"></generator>
        </id>
        <!-- 其他使用property标签来映射 -->
        <property name="cust_name" column="cust_name"></property>
        <property name="cust_source" column="cust_source"></property>
        <property name="cust_industry" column="cust_industry"></property>
        <property name="cust_level" column="cust_level"></property>
        <property name="cust_linkman" column="cust_linkman"></property>
        <property name="cust_phone" column="cust_phone"></property>
        <property name="cust_mobile" column="cust_mobile"></property>
    </class>
</hibernate-mapping>

映射文件通常是一个xml 文件即可,但一般命名为 类名.hbm.xml 

class 标签

id 标签

property 标签

2.核心配置

  Hibernate的配置文件,包含了连接持久层与映射文件所需的基本信息,其配置文件有两种格式,具体如下:

  • 一种是 properties 属性文件格式的配置文件,它使用键值对的形式存放信息,默认文件名称为 hibernate. properties
  • 另一种是XIML格式的配置文件,XML配置置文件的默认名称为 hibernate.cfg.xml

   上述两种格式的配置文件是等价的,具体使用哪个可以自由选择。XML格式的的配置文件更易于修改,配置能力更强,当改变底层应用配置时,不需要改变和重新编译代码,只修改配置文件的相应属性即可,而 properties 格式的文件则不具有此优势。因此在实实际开发项目中,大多数情况会使用XML格式的配置文件。下面将对XML格式的配置文件进行详细介绍。

  hibernate.cfg.xml 配置文件一般在开发时会放置在src的源文件夹下,发布后,该文件会在项目的 WEB-INF/ classes 路径下。配置文件的常用配置信息如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<!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>
        <!--  必要的配置信息:连接数据库的基本参数
        #hibernate.dialect org.hibernate.dialect.MySQLDialect
        #hibernate.connection.driver_class com.mysql.jdbc.Driver
        #hibernate.connection.url jdbc:mysql:///test
        #hibernate.connection.username gavin
        #hibernate.connection.password
        #hibernate.show_sql true 
        #hibernate.format_sql true
        hibernate.hbm2ddl.auto
         -->
        <!-- Hibernate的属性 -->
        <!-- Hibernate的方言:作用:根据配置的方言生成相应的SQL语句 -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql:///hibernateday1</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">admin</property>
        <!-- Hibernate显示SQL语句 -->
        <property name="hibernate.show_sql">true</property>
        <!-- Hibernate格式化SQL语句 -->
        <property name="hibernate.format_sql">true</property>
        <!-- Hibernate的hbm2ddl(数据定义语言:create drop alter ...)属性 -->
        <!-- 
            hbm2ddl.auto的取值:
                none:不用Hibernate自动生成表
                create:每次都会创建一个新的表
                create-drop:每次都会创建一个新的表,执行程序结束后删除这个表
                update:如果数据库中没有表,使用原来的表,如果没有表,创建一个新表,可以更新表结构
                validate:只会使用原有的表,对映射关系进行校验
         -->
        <property name="hibernate.hbm2ddl.auto">update</property>
        <!-- 设置hibernate的连接池提供商 
        #hibernate.connection.provider_class org.hibernate.connection.C3P0ConnectionProvider
        -->
        <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
        <!-- Hibernate 加载映射 -->
        <mapping resource="com/Kevin/domain/Customer.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

在上述代码中,首先进行了xml 声明,然后是配置文件的 dtd 信息,该信息同样可以在核心包 hibernate-core-5.0.7.Final.jar下的 org.hibernate 包中的 hibernate-configuration-3.0.dtd 文件中找到,读者只需要复制过来用即可,不需要刻意记忆。

  Hibernate 配置文件的根元素是 hibernate-configuration ,该元素包含子元素 session-factory,在session-factory 元素中又包含多个 property 元素,这些 property 元素用来对 Hibernate 连接数据库的些重要信息进行配置。例如上面的配置文件中,使用了 property元素配置了数据库的方言、驱动URL、用户名、密码等信息。最后通过 mapping 元素的配置,加载出映射文件的信息。

  Hibernate 配置文件的一些常用属性名称及用途,如表所示:

五、Hibernate的相关API

1.Configuration 配置对象(需要熟练掌握)

  Configuration 主要用于Hibernate 框架加载映射文件。

  Configuration 类的作用是对 Hibemate 进行配置,以及对它进行启动。在 Hibernate 的启动过程中,Configuration 类的实例首先定位映射文档的位置,读取这些配置,然后创建一个 Sessionfactory 对象。虽然 Configuration 类在整个 Hibernate 项目中只扮演着一个很小的角色,但它是启动 hibemate 时所遇到的第一个对象。

【加载核心配置文件】

  在使用 Hibernate 时,首先要创建 Configuration 实例,Configuration 实例主要用于启动、加载、管理 hibernate 的配置文件信息。在启动 Hibernate 的过程中,Configuration 实例首先确定 Hibernate

配置文件的位置,然后读取相关配置,最后创建一个唯一的 Sessionfactory 实例。 Configuration 对象只存在于系统的初始化阶段,它将 Sessionfactory 创建完成后,就完成了自己的使命。

  Hibernate 通常使用 Configuration cfg= new Configuration( ).configure( ) ; 的方式创建实例,此种方式默认会去 src下读取 hibernate.cfg.xml 配置文件。如果不想使用默认目录下的配置文件,而是使用指定目录下(或自定义)的配置文件,则需要向 configure 方法中传递一个文件路径的参数,其代码写法如下:

Configuration cfg = new Configuration().configure("xml文件位置”);

此种写法法 hibernate 会去指定位置查找配置文件,例如,想要使用 src 下 config 包中的hibernate.cfg.xml文件,只需将文件位置加入 configure 中即可,其代码如下所示:

Configuration cfg=new Configuration(). configure("/config/hibernate.cfg.xml");

【加载映射文件】

  Hibernate除了可以使用 Configuration 对象加载核心配置文件以外,还可以利用该对象加载映射文件。因为如果使用 properties 文件作为 Hibernate 的核心配置文件,其他的属性可以使用 key=value 的格式来设置,但是映射没有办法加载。这时这个对象就有了用武之地。可以在手动编写代码的时候去加载映射文件。

Configuration configuration= new Configuration(). configure("xm1文件位置");
configuration. addresource(cn/itcast/domain/Customer.hbm.xml");

2.SessionFactory:Session工厂对象(important 重点掌握)

  SessionFactory 接口负责初始化 Hibernate。它充当数据存储源的代理,并负责创建 Session 对象。这里用到了工厂模式,需要注意的是 SessionFactory 并不是轻量级的,因为一般情况下一个项目道常只需要一个 SessionFactory 就够,当需要操作多个数据库时,可以为每个数据库指定一个 SessionFactory 。

  Sessionfactory 接口负责 Hibernate 的初始化和建立 Session 对象。它在 Hibernate 中起到一个缓冲区作用,,Hibernate可以将自动生成的SQL语句、映射数据以及某些可重复利用的的数据放在这个缓冲区中。同时它还保存了对数据库配置的所有映射关系,维护了当前的二级缓存。

  SessionFactory 实例是通过 Configuration 对对象获取的,其获取方法如下所示:

SessionFactory factory=configure.buildSessionFactory();

SessionFactory 具有以下特点:

  ● 它是线程安全的,它的同一个实例能够供多个线程共享。

  ● 它是重量级的,不能随意的创建和销毁它的实例。

  由于 Sessionfactory 的这些特点,一般情况下,一个项目中只需要一个 Sessionfactory ,只有当应用中存在多个数据源时,才为每个数据源建立一个 Sessionfactory实例。因此,在实际项目使用中,通常会抽取出一个 HibernateUtil 的工具类,用来提供 Session对象。

Hibernate 的工具类

package com.Kevin.utils;/**
 * 抽取hibernate的工具类
 * @author Kevin
 */
public class HibernateUtil {
    private static SessionFactory factory;
    //hibernate把可以预见的异常都转成了运行时异常
    static{
        try{
            Configuration cfg=new Configuration();
            cfg.configure();
            factory=cfg.buildSessionFactory();
        }catch(ExceptionInInitializerError e){
            throw new ExceptionInInitializerError("初始化SessionFactory失败,请检查配置文件!");
        }        
    }
    /**
     * 获取一个新的 Session对象
     * @return
     */
    public static Session openSession(){
        return factory.openSession();
    }
}

 SessionFactory 内部还维护了一个连接池,如果我们需要第三方的连接池 如C3P0,那么需要我们自己动手配置。配置内容如下:

首先引入相关的 jar 包,文件所在目录:hibernate-release-5.0.7.Final\lib\optional\c3p0

      <!-- 设置hibernate的连接池提供商 
        #hibernate.connection.provider_class org.hibernate.connection.C3P0ConnectionProvider
        -->
        <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
        <!-- 在连接池中可用的数据库连接的最少数目 -->
        <property name="c3p0.min_sieze">5</property>
        <!-- 在连接池中所有数据库连接的最大数目 -->
        <property name="c3p0.max_size">20</property>
        <!-- 设定数据库连接的过期时间,以秒为单位 -->
        <!-- 如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
        <property name="c3p0.timeout">120</property>
        <!-- 每3000秒检查所有连接池中的空闲连接,以秒为单位 -->
        <property name="c3p0.ide_test_period">3000</property>

3.Session(very important 重点掌握)

session 接口负责执行被持久化对象的 CRUD 操作(CRUD的任务是完成与数据库的交流,包含了很多常见的SQL语句)。但需要主意的是 Session 对象是非线程安全的。同时,Hibernate 的 session 不同于JSP 应用中的 HttpSession 这里当使用 session 这个术语时,其实指的是 Hibernate 中的 session,而以后会将 HttpSession 对象称为用户 session 。

  Session 是应用程序与数据库之间交互操作的一个单线程对象,是 Hibernate运作的中心,它的主要功能是为持久化对象提供创建、读取和删除除的能力,所有持久化对象必须在 session 的管理下才可以进行持久化操作。

  创建 SessionFactory 实例例后,就可以通过它获取 Session 实例。获取 Session 实例有两种方式,种是通过 openSession( ) 方法,另一种是通过getCurrentSession( ) 方法。两种方法获取 session 的代码如下所示:

//采用openSession()方法创建session
Session session=factory.openSession();
//采用getCurrentSession()方法创建session
session session=factory.getCurrentSession();

以上两种获取 session 实例方式的主要区别是:采用 openSession( ) 方法获取 Session 实例时,SessionFactory 直接创建一个新的 Session实例,并且在使用完成后需要调用 close ( ) 方法进行手动关闭。

而 getCurrentSession ( ) 方法创建的 Session 实例会被绑定到当前线程中,它在提交或回滚操作时会自动关闭。

  Session 是线程不安全的,多个并发线程同时操作一个 Session 实例时,就可能导致 Session 数据存取的混乱(方法内部定义和使用 Session 时,不会出现线程问题)。因此设计软件架构时,应避免多个线程共享一个 Session实例。同时它也是轻量级的,实例的创建和销毁不需要消耗太多的资源。它还有一个缓存,即 Hibernate的一级缓存存,这个缓存主要用于存放当前工作单元加载的对象。

  在 Session 中提供了大量的常用方法,具体如下:

● save( ):保存一个实体到数据库;

● update( ):更新一个实体;

● delete( ):删除一个实体;

● get(Class class,Serializable id)和 load(Class class,Serializable id):根据id查询一个实体;

● createQuery和createSQLQuery:用于数据库操作对象

     ● createCriteria():条件查询

     ● beginTransaction( ):开启事务,并返回事物对象。

4.Transaction(熟练使用)

 Transaction 接口是一个可选的API,可以选择不使用这个接口,取而代之的是 Hibernate 的设计者自己写的底层事旁处理代码。 Transaction 接口是对实际事务实现的一个抽象,这些实现包括JDBC的事务、JTA中的 UserTransaction、甚至可以是 CORBA事务。之所以这样设计是能让开发者能够使用一个统一事务的操作界面,使得自己的项目可以在不同的环境和容器之间方便地移植。

  Transaction 接口主要用于管理事务,它是 Hibernate 的数据库事务接口,且对底层的事务接口进行了封装。 Transaction 接口的事务对象是通过 Session 对象开启的,其开启方式如下所示:

Transaction transaction = session.beginTransaction();

  在 Transaction接口中,提供了事务管理的常用方法,具体如下:

● commit( ):提交相关联的session实例;

 ● rollback( ):撤销事务操作。

  Session 执行完数据库操作后,要使用 Transaction 接口的 commit ( ) 方法进行事务提交,才能真正的将数据操作同步到数据库中。发生异常时,需要使用 rollback( ) 方法进行事务回滚,以避免数据发生错误。因此,在持久化操作后,必须调用 Transaction 接口的 commit ( )方法和rollback( ) 方法。如果没有开启事务,那么每个 Session 的操作,都相相当于一个独立的操作。

六、Hibernate中查询一个实体的方法:(面试考点)

  ● get方法:get(Class class,Serializable id);

  ● load方法:load(class class,Serializable id);(load方法默认情况下是延迟,可以通过配置的方式改为立即加载)

  共同点:都是根据id查找一个实体

  二者的区别:

1.查询的时机不一样:

      1.)get方法的查询时机:每次调用get方法时,马上查询 立即加载;

      2.)  load方法的查询时机:每次真正使用的时候,发起查询 延迟加载(懒加载/惰性加载)。

    2.返回结果不一样:

      1.)  get方法返回的对象是实体类类型;

      2.)  load方法返回的对象是实体类类型的代理对象。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏后端技术探索

Restful 接口设计最佳事件

本小编这一年是在一家移动互联网公司做App后端接口设计开发工作,最近组内做了一次很大的重构,就是把接口完全根据restful规范进行设计重写。这么做的目的首先是...

1123
来自专栏微服务生态

深入浅出Netflix Conductor使用

Netflix Conductor框架是典型的服务编排框架,通过Conductor还可以实现工作流和分布式调度,性能非常卓越。

8073
来自专栏*坤的Blog

redis性能测试

9892
来自专栏企鹅号快讯

JDBC编程

前面我们已经讨论了数据库的安装和简单的使用,还没完成的可以先去Mysql的安装和Mysql数据库的简单操作回顾一下哦!今天我们来简单学习JDBC编程的准备和链...

3378
来自专栏Kevin-ZhangCG

[ SSH框架 ] Hibernate框架学习之一

2508
来自专栏静晴轩

Gulp探究折腾之路(I)

前言: gulp是前端开发过程中对代码进行构建的工具,是自动化项目的构建利器;她不仅能对网站资源进行优化,而且在开发过程中很多重复的任务能够使用正确的工具自动完...

3728
来自专栏Elasticsearch实验室

Elasticsearch调优实践

本文基于ES 5.6.4,从性能和稳定性两方面,从linux参数调优、ES节点配置和ES使用方式三个角度入手,介绍ES调优的基本方案。当然,ES的调优绝不能一概...

4.9K16
来自专栏zhisheng

0Day技术分析-1-基础知识

1 基础知识 本章介绍一些与0Day相关的基本概念及基础知识。 1.1. Bug与漏洞 有一个比较有趣的事件,话说某个软件中存在99个Bug,某一天研发人员心血...

3184
来自专栏美团技术团队

分布式系统互斥性与幂等性问题的分析与解决

前言 随着互联网信息技术的飞速发展,数据量不断增大,业务逻辑也日趋复杂,对系统的高并发访问、海量数据处理的场景也越来越多。如何用较低成本实现系统的高可用、易伸缩...

5414
来自专栏美团技术团队

MTDDL——美团点评分布式数据访问层中间件

背景 2016年Q3季度初,在美团外卖上单2.0项目上线后,商家和商品数量急速增长,预估商品库的容量和写峰值QPS会很快遇到巨大压力。随之而来也会影响线上服务的...

5435

扫码关注云+社区

领取腾讯云代金券