Hibernate

Posted Ivyvivid

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate相关的知识,希望对你有一定的参考价值。

1.对象关系映射框架
2.封装JDBC(持久化机制),提供对象关系型数据库的持久化服务

1.数据库操作
2.DAO层(持久化层)

==============================持久化(机制)===============================
    将程序中的数据在瞬时状态与持久化状态之间的转换的机制(即,内存与数据库之间的转换)
    通常,将程序数据保存在数据库中或从数据库中读取数据
    
============================ORM(Object Relational Mapping)(机制)======================
    对象-关系映射机制
    1.编写程序时,以面向对象的方式处理数据
    2.保存数据时,以关系型数据的形式存储到数据库中
    
ORM解决:
    1.在持久化对象执行基本的增删改查操作
    2.对持久化对象提供一种查询语言或者API
    3.对象关系映射工具
    4.提供与事务对象交互、执行检查、延迟加载及其他优化功能
    
步骤:
    1.下载并部署jar包(官网www.bibernate.org)
        a.hibernate3.jar| required 目录下的jar 包 | jpa 目录下的jar 包;
        b.mysql 数据库驱动jar包
    2.编写配置文件(插件)
        a.用于配置数据库连接
        b.运行时所需的各种属性
        c.默认文件名为"hibernate.cfg.xml"
        范例:
        //引用映射文件--向hibernate.cfg.xml文件中配置映射文件    

 1 <session-factory>
 2             <!--省略其他配置-->
 3             <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
 4             <property name="connection.url">jdbc:mysql:localhost/数据库名称</property>
 5             <property name="connection.username">root</property>
 6             <property name="connection.password">root</property>
 7             <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
 8             <!--注意配置文件名必须包含其相对于classpath 的全路径-->
 9             <mapping resource="cn/jbit/hibernatedemo/entit/Dept.hbm.xml" />
10 </session-factory>


    3.创建持久化类和映射文件
        a.创建持久化类--定义持久化类(也称实体类),实现java.io.Serializable 接口,添加默认构造方法
        范例:   

1 public class Dept implements Serializable {
2             private Byte deptNo;
3             private String deptName;
4             private String location;
5             public Dept() {
6             }
7             //省略getter&setter 方法
8 }

        b.创建映射文件--配置映射文件(*.hbm.xml)
        范例:    

1 <hibernate-mapping>
2             <class name="cn.jbit.hibernatedemo.entity.Dept" table="dept">
3                 <id name="deptNo" column="deptno" type="java.lang.Byte">
4                     <generator class="assigned"/>
5                 </id>
6                 <property name="deptName" type="java.lang.String" column="dname"/></property>
7                 <property name="location" type="java.lang.String" column="loc"></property>
8             </class>
9 </hibernate-mapping>

通过持久化类Class对象和ID 加载数据
    1.Object get(Class clazz, Serializable id): 若数据不存在,返回NULL对象
    2.Object load(Class theClass, Serializable id): 若数据不存在,系统就会抛出异常
        
范例:
1.创建hibernate.cfg.xml        

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-configuration PUBLIC
 3     "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
 5 <hibernate-configuration>
 6     <session-factory>
 7         <!-- 1.连接数据库 -->
 8         <!-- 连接数据库名 -->
 9         <property name="connection.url">jdbc:mysql://localhost:3306/hibernatedb</property>
10         
11         <!-- 连接数据库的用户名 -->
12         <property name="connection.username">root</property>
13         
14         <!-- 连接数据库的密码 -->
15         <property name="connection.password">root</property>
16         
17         <!-- 数据库驱动类 -->
18         <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
19         
20         <!-- 2.数据库方言(不同的数据库) -->
21         <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
22         
23         <!-- 3.其他属性 -->
24         <!-- 是否显示sql语句 -->
25         <property name="show_sql">true</property>
26         <!-- 是否显示格式化sql语句,如果要显示,★★★一定要先显示show_sql语句★★★ -->
27         <property name="format_sql">true</property>
28         
29         <!-- 4.数据库对应的实体类的映射文件路径 -->
30         <mapping resource="com/Elastic/HibernateDemo/ivy/entity/Dept.hbm.xml"></mapping>
31     </session-factory>
32 </hibernate-configuration>

2.创建数据库

1 hibernatedb.dept
2 deptid int(11) primary key auto increment not null;
3 deptname VARCHAR(45) not null;
4 location VARCHAR(45) not null;

3.创建实体类Dept

 1 package com.Elastic.HibernateDemo.ivy.entity;
 2 import java.io.Serializable;
 3 public class Dept implements Serializable{
 4     private Integer deptId;
 5     private String deptName;
 6     private String location;
 7     public Integer getDeptId() {
 8         return deptId;
 9     }
10     public void setDeptId(Integer deptId) {
11         this.deptId = deptId;
12     }
13     public String getDeptName() {
14         return deptName;
15     }
16     public void setDeptName(String deptName) {
17         this.deptName = deptName;
18     }
19     public String getLocation() {
20         return location;
21     }
22     public void setLocation(String location) {
23         this.location = location;
24     }
25 }

4.创建Dept.hbm.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC
 3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 <hibernate-mapping>
 6     <!-- 实体类路径:数据库表名-->
 7     <class name="com.Elastic.HibernateDemo.ivy.entity.Dept" table="dept">
 8         <!-- 主键UID(唯一标识) -->
 9         <id name="deptId" column="deptid"><!-- column单独一行,属性更全 -->
10             <!-- 主键生成策略:increment,assigned,native等 -->
11             <generator class="increment"></generator>
12         </id>
13         
14         <!-- 属性名(★★setDeptName★★):数据库表字段(如果是关键字,用``标志) -->
15         <property name="deptName" column="deptname"></property>
16         <property name="location" column="location"></property>
17     </class>
18 </hibernate-mapping>

5.测试Test类
除了新增,其他删、改、重复查询都要先进行查询操作

 1 package com.Elastic.HibernateDemo.ivy.test;
 2 import org.hibernate.HibernateException;
 3 import org.hibernate.SessionFactory;
 4 import org.hibernate.Transaction;
 5 import org.hibernate.cfg.Configuration;
 6 import org.hibernate.classic.Session;
 7 import com.Elastic.HibernateDemo.ivy.entity.Dept;
 8 public class Test {
 9     public static void main(String[] args) {
10         /*
11          * 使用hibernate框架,一定要用到的四个对象
12          * 配置文件Configuration,
13          * 会话工厂SessionFactory,
14          * 会话Session,
15          * 事务Transaction
16          */
17         Configuration cfg = null;
18         SessionFactory sessionFactory = null;
19         Session session = null;
20         Transaction tx = null;
21         
22         try {
23             //1.读取配置文件
24             cfg = new Configuration().configure();
25             //2.创建会话工厂
26             sessionFactory = cfg.buildSessionFactory();
27             //3.通过会话工厂打开会话
28             session = sessionFactory.openSession();
29             //4.开启事务
30             tx = session.beginTransaction();
31             //5.创建业务数据
32             Dept dept = new Dept();
33 //            dept.setDeptId(1);
34             dept.setDeptName("开发部");
35             dept.setLocation("4楼");
36             //6.执行具体的数据库
37             
38             //新增
39             session.save(dept);
40             
41             /*//根据主键查询
42             Dept dept = (Dept) session.get(Dept.class, 1);
43             if (null != dept) {
44                 System.out.println(dept.getDeptName());
45             } else {
46                 System.out.println("没有找到!");
47             }*/
48             
49             /*//修改主键为2 部门名称为财务部
50             Dept dept = (Dept) session.get(Dept.class, 2);
51             if (null != dept) {
52                 dept.setDeptName("财务部");
53             } else {
54                 System.out.println("没有修改成功!");
55             }*/
56             
57             /*//删除主键为2的数据
58             Object dept = session.get(Dept.class, 2);
59             if (null != dept) {
60                 session.delete(dept);
61             } else {
62                 System.out.println("没有删除成功!");
63             }*/
64             
65             //重复查询,如果重复查询同一个语句,就不会在查询。因为下一个查询先从之前查询的轮一遍,再查询
66             /*Dept dept = (Dept) session.get(Dept.class, 2);
67             System.out.println(dept.getDeptName());
68             
69             Dept dept1 = (Dept) session.get(Dept.class, 1);
70             System.out.println(dept1.getDeptName());*/
71             
72             //7.提交事务
73             tx.commit();
74         } catch (HibernateException e) {
75             e.printStackTrace();
76             //业务回滚
77             tx.rollback();
78         } finally {
79             //关闭资源
80             session.close();
81         }
82         System.out.println("执行结束!");
83     }
84 }        

数据库连接池
    1.数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;
      释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。
      
    2.连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库时,并非建立一个新的连接,
      而是从连接池中取出一个已建立的空闲连接对象。使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用。
      而连接的建立、断开都由连接池自身来管理。同时,还可以通过设置连接池的参数来控制连接池中的初始连接数、连接的上下限数以及每个连接的最大使用次数、  最大空闲时间等等。也可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。
      
    3.Java连接池
        1、C3P0:是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate[2]  一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象。
        2、Proxool:是一个Java SQL Driver驱动程序,提供了对选择的其它类型的驱动程序的连接池封装。可以非常简单的移植到现存的代码中,完全可配置,快速、成熟、健壮。可以透明地为现存的JDBC驱动程序增加连接池功能。
        3、Jakarta DBCP:DBCP是一个依赖Jakartacommons-pool对象池机制的数据库连接池。DBCP可以直接的在应用程序中使用。
        4、DDConnectionBroker:是一个简单、轻量级的数据库连接池。
        5、DBPool:是一个高效、易配置的数据库连接池。它除了支持连接池应有的功能之外,还包括了一个对象池,使用户能够开发一个满足自己需求的数据库连接池。
        6、XAPool:是一个XA数据库连接池。它实现了javax.sql.XADataSource并提供了连接池工具。
        7、Primrose:是一个Java开发的数据库连接池。当前支持的容器包括Tomcat4&5、Resin3与JBoss3。它同样也有一个独立的版本,可以在应用程序中使用而不必运行在容器中。Primrose通过一个WEB接口来控制SQL处理的追踪、配置,以及动态池管理。在重负荷的情况下可进行连接请求队列处理。
        8、SmartPool:是一个连接池组件,它模仿应用服务器对象池的特性。SmartPool能够解决一些临界问题如连接泄漏(connection leaks)、连接阻塞、打开的JDBC对象(如Statements、PreparedStatements)等。SmartPool的特性包括:
            支持多个pool
            自动关闭相关联的JDBC对象
            在所设定time-outs之后察觉连接泄漏
            追踪连接使用情况
            强制启用最近最少用到的连接
            把SmartPool“包装”成现存的一个pool
        9、MiniConnectionPoolManager:是一个轻量级JDBC数据库连接池。它只需要Java1.5(或更高)并且没有依赖第三方包。
        10、BoneCP:是一个快速、开源的数据库连接池。帮用户管理数据连接,让应用程序能更快速地访问数据库。比C3P0/DBCP连接池速度快25倍。
        11、Druid:Druid不仅是一个数据库连接池,还包含一个ProxyDriver、一系列内置的JDBC组件库、一个SQL Parser。
            支持所有JDBC兼容的数据库,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等。
            Druid针对Oracle和MySql做了特别优化,比如:
                Oracle的PS Cache内存占用优化
                MySql的ping检测优化
                Druid提供了MySql、Oracle、Postgresql、SQL-92的SQL的完整支持,这是一个手写的高性能SQL Parser,支持Visitor模式,使得分析SQL的抽象语法树很方便。
                简单SQL语句用时10微秒以内,复杂SQL用时30微秒。
                通过Druid提供的SQL Parser可以在JDBC层拦截SQL做相应处理,比如说分库分表、审计等。Druid防御SQL注入攻击的WallFilter,就是通过Druid的SQL Parser分析语义实现的

Java对象中的三种状态
    瞬时(临时)状态:新的对象(new出来的),与数据库的数据不一样,资源回收
    持久状态:执行过,保存过
    游离状态:与数据库的数据一模一样(被数据库执行删除工作),资源回收
    


以上是关于Hibernate的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate的HQL多表查询

使用反射在外部JAR / CLASS上调用包含Hibernate事务的方法(Java EE)

Hibernate CriteriaQuery where - ManyToOne 字段

Hibernate + MySQL:如何为数据库和表设置编码 utf-8

hibernate在使用getCurrentSession时提示no session found for current thread

Java类型相互转换byte[]类型,blob类型