3.hibernate

1. hibernate框架

框架的含义:

  • 1.框架是用来提高开发效率的
  • 2.封装了好了一些功能.我们需要使用这些功能时,调用即可.不需要再手动实现.
  • 3.所以框架可以理解成是一个半成品的项目.只要懂得如何驾驭这些功能即可.

javaEE三层开发框架及hibernate框架对应的位置如下:

Hibernate框架优点: 操作数据库的时候,可以以面向对象的方式来完成.不需要书写SQL语句

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

Hibernate是一个开放源代码的ORM(object relationship mapping,关系对象映射)框架,它对JDBC进行了轻量级的对象封装,使得Java开发人员可以使用面向对象的编程思想来操作数据库。

 

Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。

为什么学习Hibernate?

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

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

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

  • Hibernate对JDBC访问数据库的代码做了轻量级封装,大大简化了数据访问层繁琐的重复性代码,并且减少了内存消耗,加快了运行效率。
  • Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现,它很大程度的简化了DAO(Data Access Object,数据访问对象)层编码工作。
  • Hibernate的性能非常好,映射的灵活性很出色。它支持很多关系型数据库,从1对1到多对多的各种复杂关系。
  • 可扩展性强,由于源代码的开源以及API的开放,当本身功能不够用时,可以自行编码进行扩展。

orm分4级
hibernate属于4级:完全面向对象操作数据库
mybatis属于2级
dbutils属于1级

Hibernate5.0.7的目录介绍:

  • documentation文件夹:存放Hibernate的相关文档,包括参考文档的API文档。
  • lib文件夹:存放Hibernate编译和运行所依赖的JAR包。其中required子目录下包含了运行Hibernate5项目必须的JAR包。
  • project文件夹:存放Hibernate各种相关的源代码。

 

2. Hibernate入门

  框架搭建

  • 导包

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

驱动包

日志记录包

  • 创建实体(持久化类):创建数据库,准备表,实体

持久化类是应用程序中的业务实体类,这里的持久化是指类的对象能够被持久化保存到数据库中。

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

在项目src目录下,创建cn.eagle.domain包,并在保重创建类Customer(对应数据库表cst_customer),Customer类包含了与cst_customer数据表字段对应的属性,以及相应的getXxx()和setXxx()方法。

 1 package cn.eagle.domain;
 2 
 3 public class Customer {
 4 
 5     private Long cust_id;
 6     private String cust_name;
 7     private String cust_source;
 8     private String cust_industry;
 9     private String cust_level;
10     private String cust_phone;
11     private String cust_mobile;
12 
13     public Long getCust_id() {
14         return cust_id;
15     }
16 
17     public void setCust_id(Long cust_id) {
18         this.cust_id = cust_id;
19     }
20 
21     public String getCust_name() {
22         return cust_name;
23     }
24 
25     public void setCust_name(String cust_name) {
26         this.cust_name = cust_name;
27     }
28 
29     public String getCust_source() {
30         return cust_source;
31     }
32 
33     public void setCust_source(String cust_source) {
34         this.cust_source = cust_source;
35     }
36 
37     public String getCust_industry() {
38         return cust_industry;
39     }
40 
41     public void setCust_industry(String cust_industry) {
42         this.cust_industry = cust_industry;
43     }
44 
45     public String getCust_level() {
46         return cust_level;
47     }
48 
49     public void setCust_level(String cust_level) {
50         this.cust_level = cust_level;
51     }
52 
53     public String getCust_phone() {
54         return cust_phone;
55     }
56 
57     public void setCust_phone(String cust_phone) {
58         this.cust_phone = cust_phone;
59     }
60 
61     public String getCust_mobile() {
62         return cust_mobile;
63     }
64 
65     public void setCust_mobile(String cust_mobile) {
66         this.cust_mobile = cust_mobile;
67     }
68 
69     @Override
70     public String toString() {
71         return "Customer [cust_id=" + cust_id + ", cust_name=" + cust_name + ", cust_source=" + cust_source
72                 + ", cust_industry=" + cust_industry + ", cust_level=" + cust_level + ", cust_phone=" + cust_phone
73                 + ", cust_mobile=" + cust_mobile + "]";
74     }
75 
76 }
Customer
  • 创建映射文件

实体类Customer目前还不具备持久化操作的能力,而Hibernate需要知道实体类Customer映射到数据库Hibernate中的哪个表,以及类中的哪个属性对应数据库表中的哪个字段,这些都需要在映射文件中配置。

在实体类Customer所在的包中,创建一个名称为Customer.hbm.xml的映射文件,在该文件中定义了实体类Customer的属性是如何映射到cst_customer表的列上的。

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 3 <hibernate-mapping>
 4     <class name="cn.eagle.domain.Customer" table="cst_customer">
 5         <id name="cust_id" column="cust_id">
 6             <generator class="native"></generator>
 7         </id>    
 8         <property name="cust_name" column="cust_name"></property>
 9         <property name="cust_source" column="cust_source"></property>
10         <property name="cust_industry" column="cust_industry"></property>
11         <property name="cust_level" column="cust_level"></property>
12         <property name="cust_phone" column="cust_phone"></property>
13         <property name="cust_mobile" column="cust_mobile"></property>
14     </class>
15 </hibernate-mapping>
Customer.hbm.xml
  • 创建Hibernate的核心配置文件

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

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd" >
 3 <hibernate-configuration>
 4   <session-factory>
 5       <property name="hibernate.connection.dirver_class">com.mysql.jdbc.Driver</property>
 6       <property name="hibernate.connection.url">jdbc:mysql:///day24_db</property>
 7       <property name="hibernate.connection.username">root</property>
 8       <property name="hibernate.connection.password">toor</property>
 9       <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
10       <property name="hibernate.show_sql">true</property>
11       <property name="hibernate.format_sql">true</property>
12       <property name="hibernate.hbm2ddl.auto">update</property>
13       <mapping resource="cn/eagle/domain/Customer.hbm.xml"/>
14   </session-factory>
15 </hibernate-configuration>
hibernate.cfg.xml

 

3. Hibernate配置文件详解

在以上部分中,我们已经接触过Hibernate的映射文件和配置文件。接下来,将对这些文件进行详细的讲解。

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

<?xml version="1.0" encoding="UTF-8"?>

 

<!-- 映射文件的dtd信息 -->

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

 

 <-- class元素:配置实体与表的对应关系

        name:完整类名;

        table:数据库表名。(如果类名和表名是一致的,那么table属性可以省略) -->

<class name="cn.eagle.domain.Customer" table="cst_customer">

  

 <!-- id元素:配置主键映射的属性

        name:主键对应的属性名;

        column(可选):填写表中的主键列名。默认值:列名会默认使用属性名;

        type(可选):填写列(属性)的类型。Hibernate会自动检测实体的属性类型。

          每个类型有三种填法:java类型|hibernate类型(默认)|数据库类型;

        not-null(可选):配置该属性(列)是否不能为空。默认值:false

        length(可选):配置数据库中列的长度,默认值:使用数据库类型的最大长度

  -->    

 

<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_phone" column="cust_phone"></property>

<property name="cust_mobile" column="cust_mobile"></property>

</class>

</hibernate-mapping>

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

  • 核心配置文件hibernate.cfg.xml包含了连接持久层与映射文件所需的基本信息,其配置文件有两种格式,具体如下:
    • 一种是properties属性文件格式的配置文件,它使用键值对的形式存放信息,默认文件名称为Hibernate.properties;
    • 另一种是XML格式的配置文件,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>

 

  <!-- 5个必选连接数据库基本参数属性

    hibernate.connection.dirver_class 数据库驱动

    hibernate.connection.url    数据库url

    hibernate.connection.username  数据库连接用户名

    hibernate.connection.password  数据库连接密码

    hibernate.dialect    数据库方言,不同的数据库中,sql语法略有区别,

                指定方言可以让hibernate框架在生成sql语句时,针对数据库的方言生成;

        sql99标准:DDL 定义语言 库表的增删改查

              DCL 控制语言  事务、权限

              DML  操纵语言  增删改查

            注意: Mysql在选择方言时,请选择最短的方言

    hibernate.connection.autocommit  可选,事务是否自动提交

  -->

 

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

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

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

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

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

 

  <!-- 3个可选属性

     hibernate.show_sql 将hibernate生成的sql语句打印到控制台

     hibernate.format_sql  将hibernate生成的sql语句格式化(语法缩进)

     hibernate.hbm2ddl.auto (auto scheme export 自动导出表结构,自动建表)

       create: 自动建表.每次框架运行都会创建新的表,以前的表将会被覆盖,表数据会丢失。(开发环境中测试使用)

       create-drop: 自动建表。每次框架运行结束都会将所有表删除。(开发环境中测试使用)

       update: 推荐使用  自动生成表,如果已经存在不会再生成,如果表有变动,自动更新表(不会删除任何数据)

       validate: 校验 不自动生成表。每次启动会校验数据库中表是否正确,只会使用原有的表 -->

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

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

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

 

  <!-- 引入orm源数据

    路径书写:填写src下的路径   -->

<mapping resource="cn/eagle/domain/Customer.hbm.xml" />

</session-factory>

</hibernate-configuration>

 

4. Hibernate API详解

  • Configuration

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

Configuration实例用于启动、加载、管理hibernate的配置文件信息。在启动Hibernate的过程中,Configuration实例首先确定Hibernate配置文件的位置,然后读取相关配置,最后创建一个唯一的SessionFactory实例。Configuration对象只存在于系统的初始化阶段,它将SessionFactory创建完成后,就完成了自己的使命。

Configuration cfg = new Configuration().configure();

此种方式默认会去src下读取hibernate.cfg.xml配置文件。如果不想使用默认的hibernate.cfg.xml配置文件,而是使用指定目录下(或自定义)的配置文件,则需要向configuration()方法中传递一个文件路径的参数即可。

也可以使用该对象加载映射文件:

configuration.addResource("cn/eagle/domain/Customer.hbm.xml");

  • SessionFactory

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

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

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

SessionFactory sessionFactory = cfg.buildSessionFactory();

它的特点如下:

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

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

  3. 负责保存和使用所有配置信息,消耗内存资源非常大

  4. 保证在web项目中,值创建一个SessionFactory

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

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

<!-- 配置C3P0连接池  -->

<property name="connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>

<!-- 在连接池中可用的数据库连接的最少数目 -->

<property name="c3p0.min_size">5</property>

<!-- 在连接池中所有数据库连接的最大数目 -->

<property name="c3p0.max_size">20</property>

<!-- 设定数据库连接的过期时间,以秒为单位,如果连接池中的某个数据库连接处于

空闲状态的时间超过了timeout时间,就会从连接池中清除 -->

<property name="c3p0.timeout"></property>

<!-- 每3000秒检查所有连接池中的空闲连接,以秒为单位 -->

<property name="c3p0.idle_test_period">3000</property>

 

测试C3P0连接池

新建测试单元

 1 package cn.eagle.test;
 2 
 3 import static org.junit.Assert.*;
 4 
 5 import java.sql.Connection;
 6 import java.sql.SQLException;
 7 
 8 import org.hibernate.Session;
 9 import org.hibernate.SessionFactory;
10 import org.hibernate.Transaction;
11 import org.hibernate.cfg.Configuration;
12 import org.hibernate.jdbc.Work;
13 import org.junit.After;
14 import org.junit.Before;
15 import org.junit.Test;
16 
17 public class HibernateTestC3P0 {
18     private SessionFactory sessionFactory;
19     private Session session;
20     private Transaction transaction;
21     
22     @Before
23     public void init() {
24         Configuration configuration = new Configuration().configure();
25         sessionFactory = configuration.buildSessionFactory();
26         session = sessionFactory.openSession();
27         transaction = session.beginTransaction();
28     }
29     
30     @After
31     public void destroy() {
32         transaction.commit();
33         session.close();
34         sessionFactory.close();
35     }
36     
37     @Test
38     public void test() {
39         session.doWork(new Work() {
40 
41             @Override
42             public void execute(Connection conn) throws SQLException {
43                 System.out.println(conn);
44             }
45             
46         });
47     }
48 
49 }
HibernateTestC3P0

  • Session

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

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

创建SessionFactory实例后,就可以通过它获取Session实例。获取Session实例有两种方式,

一种是通过openSession()方法,另外一种是通过getCurrentSession()方法。两种方法获取session的代码如下所示:

Session session = sessionFactory.openSession();

Session session = sessionFactory.getCurrentSession();

以上两种获取session实例方式的主要区别是,采用openSession方法获取Session实例时,SessionFactory直接创建一个新的Session实例,并且在使用完成后需要调用close方法进行手动关闭。而getCurrentSession方法创建的Session实例会被绑定到当前线程中,它在提交或回滚操作时会自动关闭。

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

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

  1. save()、update()和saveOrUpdate()方法:用于增加和修改对象。

  2. delete()方法:用于删除对象。

  3. get()和load()方法:根据主键查询。

  4. createQuery()和createSQLQuery()方法:用于数据库操作对象。

  5. createCriteria()方法:条件查询。 

 

  • Transaction

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

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

Transaction tx = session.beginTransaction();

 

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

  1. commit()方法:提交相关联的session实例。

  2. rollback()方法: 撤销事务操作。

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

 

 

 

转载于:https://www.cnblogs.com/eaglesour/p/9481009.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值