hibernate总结-持续更新

时间:2021-07-20 13:22:02

简介

hibernate官网:Hibernate

Hibernate 是一个开放源代码的对象关系映射框架,它对 JDBC 进行了非常轻量级的对象封装,使得 Java 程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate 可以应用在任何使用 JDBC 的场合, 既可以在Java的客户端程序使用, 也可以在Servlet/JSP的Web应用中使用, 最具革命意义的是, Hibernate 可以在应用 EJB 的 J2EE 架构中取代 CMP,完成数据持久化的重任。 ORM 框架,对象关系映射(Object/Relation Mapping)

Hibernate工具类:

01 package com.glorze.util;
02  
03 import org.hibernate.SessionFactory;
04 import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
05 import org.hibernate.cfg.Configuration;
06 import org.hibernate.service.ServiceRegistry;
07  
08 /**
10 *高老四博客:Hibernate工具类
11 */
12 public class HibernateUtil {
13 private static final SessionFactory sessionFactory = buildSessionFactory();
14  
15 public static SessionFactory buildSessionFactory() {
16 Configuration configuration = new Configuration().configure();// 实例化配置文件
17 ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
18 .applySettings(configuration.getProperties()).build();// 实例化服务登记
19 return configuration.buildSessionFactory(serviceRegistry);// 建立session工厂
20 }
21  
22 public static SessionFactory getSessionFactory() {
23 return sessionFactory;
24 }
25 }

xml与注解

01 <?xml version="1.0"?>
02 <!DOCTYPE hibernate-mapping PUBLIC
03 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
05  
06 <hibernate-mapping package="com.glorze.model">
07 <class name="Student" table="t_student">
08 <id name="id" column="stuId">
09 <generator class="native"></generator>
10 </id>
11 <property name="name"></property>
12 </class>
13 </hibernate-mapping>
01 package com.glorze.model;
02  
03 import javax.persistence.Entity;
04 import javax.persistence.GeneratedValue;
05 import javax.persistence.Id;
06 import javax.persistence.Table;
07  
08 import org.hibernate.annotations.GenericGenerator;
09  
10 @Entity
11 @Table(name="t_teacher")
12 public class Teacher {
13 private long id;
14 private String name;
15  
16 @Id
17 @GeneratedValue(generator="_native")
18 @GenericGenerator(name="_native",strategy="native")
19 public long getId() {
20 return id;
21 }
22 public void setId(long id) {
23 this.id = id;
24 }
25 public String getName() {
26 return name;
27 }
28 public void setName(String name) {
29 this.name = name;
30 }
31 @Override
32 public String toString() {
33 return "Teacher [id=" + id + ", name=" + name + "]";
34 }
35 }

映射对象标识符(OID)

1.Hibernate 用对象标识符(OID)

hibernate总结-持续更新

1 Student s1 = (Student) session.get(Student.class, Long.valueOf(4));
2 Student s2 = (Student) session.get(Student.class, Long.valueOf(5));
3 Student s3 = (Student) session.get(Student.class, Long.valueOf(4));

2.Hibernate 对象标识符生成策略

主键的分类 业务主键 VS 代理主键 代理主键是不具有业务性的;

increment 由 Hibernate 自动以递增的方式生成标识符,适用代理主键;
i层数据库的序列来生成标识符;适用代理主键; (不支持mysql,支持oracle和db2)
hilo Hdentity 由底层数据库生成标识符;适用代理主键;
sequcence 由 Hibernate 根据底ibernate 根据 high/low 算法来生成标识符。适用代理主键
native 根据底层数据库对自动生成标识符的支持能力, 来选择 identity,sequence 或 hilo;适用代理主键;

3.JUnit setUpBeforeClass() 类初始化前调用; tearDownAfterClass() 类初始化后调用; setUp() 在测试方法前调用; tearDown() 在测试方法后调用;

级联保存更新

hibernate总结-持续更新

在<many-to-one>这端,cascade 默认是”none”,假如我们希望在持久化多的一端的时候,自动级 联保存和更新一的一端,我们可以把 cascade 设置成”save-update”;

inverse属性:

01 <?xml version="1.0"?>
02 <!DOCTYPE hibernate-mapping PUBLIC
03 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
05  
06 <hibernate-mapping package="com.glorze.model">
07 <class name="Class" table="t_class">
08 <id name="id" column="classId">
09 <generator class="native"></generator>
10 </id>
11 <property name="name" column="className"></property>
12  
13 <set name="students" cascade="delete" inverse="true">
14 <key column="classId"></key>
15 <one-to-many class="com.glorze.model.Student"/>
16 </set>
17 </class>
18 </hibernate-mapping>
1 @Test
2 public void testInverse(){
3 Class c=(Class) session.get(Class.class, Long.valueOf(1));
4 Student s=(Student) session.get(Student.class, Long.valueOf(1));
5  
6 c.getStudents().add(s);
7 s.setC(c);
8 }

一对多双向自身关联关系映射

01 package com.glorze.model;
02  
03 import java.util.HashSet;
04 import java.util.Set;
05  
06 public class Node {
07 private long id;
08 private String name;
09  
10 private Node parentNode;//多对一,父节点
11  
12 private Set<Node> childrenNode=new HashSet<Node>();//一对多,相当于父节点
13  
14 public long getId() {
15 return id;
16 }
17  
18 public void setId(long id) {
19 this.id = id;
20 }
21  
22 public String getName() {
23 return name;
24 }
25  
26 public void setName(String name) {
27 this.name = name;
28 }
29  
30 public Node getParentNode() {
31 return parentNode;
32 }
33  
34 public void setParentNode(Node parentNode) {
35 this.parentNode = parentNode;
36 }
37  
38 public Set<Node> getChildrenNode() {
39 return childrenNode;
40 }
41  
42 public void setChildrenNode(Set<Node> childrenNode) {
43 this.childrenNode = childrenNode;
44 }
45 }
01 <?xml version="1.0"?>
02 <!DOCTYPE hibernate-mapping PUBLIC
03 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
05  
06 <hibernate-mapping package="com.glorze.model">
07 <class name="Node" table="t_node">
08 <id name="id" column="nodeId">
09 <generator class="native"></generator>
10 </id>
11 <property name="name" column="nodeName"></property>
12  
13 <many-to-one name="parentNode" column="parentId" class="com.java1234.model.Node" cascade="save-update"></many-to-one>
14  
15 <set name="childrenNode" inverse="true">
16 <key column="parentId"></key>
17 <one-to-many class="com.glorze.model.Node"/>
18 </set>
19 </class>
20 </hibernate-mapping>
01 package com.glorze.service;
02  
03 import static org.junit.Assert.*;
04  
05 import java.util.Iterator;
06 import java.util.Set;
07  
08 import org.hibernate.Session;
09 import org.hibernate.SessionFactory;
10 import org.junit.After;
11 import org.junit.Before;
12 import org.junit.Test;
13  
14 import com.glorze.model.Class;
15 import com.glorze.model.Node;
16 import com.glorze.model.Student;
17 import com.glorze.util.HibernateUtil;
18  
19 public class NodeTest {
20  
21 private SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
22 private Session session;
23  
24 @Before
25 public void setUp() throws Exception {
26  
27 session = sessionFactory.openSession();// 生成一个新的session
28 session.beginTransaction();// 开启事务
29 }
30  
31 @After
32 public void tearDown() throws Exception {
33 session.getTransaction().commit();// 提交事务
34 session.close();// 关闭session
35 }
36  
37 @Test
38 public void testSave() {
39 Node node=new Node();
40 node.setName("根节点");
41  
42 Node subNode1=new Node();
43 subNode1.setName("子节点1");
44  
45 Node subNode2=new Node();
46 subNode2.setName("子节点2");
47  
48 subNode1.setParentNode(node);
49 subNode2.setParentNode(node);
50  
51 /**
52 * invers属性 在多的一段进行数据操作
53 */
54 session.save(subNode1);
55 session.save(subNode2);
56 }
57  
58 }

Hibernate中四种对象状态

临时状态(transient):刚用 new 语句创建,还没有被持久化,并且不处于 Sesssion 的缓存中。处于临时状态 的 Java 对象被称为临时对象。

持久化状态(persistent):已经被持久化,并且加入到 Session 的缓存中。处于持久化状态的 Java 对象被称为 持久化对象。

删除状态(removed):不再处于 Session 的缓存中,并且 Session 已经计划将其从数据库中删除。处于删除状 态的 Java 对象被称为删除对象。

游离状态(detached):已经被持久化,但不再处于 Session 的缓存中。处于游离状态的 Java 对象被称为游离对象。

hibernate总结-持续更新

hibernate总结-持续更新

01 package com.glorze.service;
02  
03 import org.hibernate.Session;
04 import org.hibernate.SessionFactory;
05  
06 import com.glorze.model.Class;
07 import com.glorze.model.Student;
08 import com.glorze.util.HibernateUtil;
09  
10 public class StudentTest {
11  
12 public static void main(String[] args) {
13 SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
14 Session session = sessionFactory.openSession();// 生成一个新的session
15 session.beginTransaction();// 开启事务
16  
17 /**
18 * c1 c2为临时对象
19 */
20 Class c1=new Class();
21 c1.setName("1205211软件工程");
22  
23 Class c2=new Class();
24 c2.setName("1205212软件工程");
25  
26 /**
27 * c1 c2为持久化对象,存在session中
28 */
29 session.save(c1);
30 session.save(c2);
31  
32 session.delete(c2);//删除对象
33  
34 /**
35 * 提交之后就插入到了数据库
36 */
37 session.getTransaction().commit();// 提交事务
38 session.close();// 关闭session
39  
40 System.out.println(c1.getName());//此时的c1为游离对象,但是可以获取属性值
41 System.out.println(c2.getName());//删除状态
42 }
43 }

session常用方法

1,save()方法 将一个临时对象转变成持久化对象;

2,load()方法 VS get()方法

都是根据 OID 从数据库中加载一个持久化对象。
区别 1:假如数据库中不存在与 OID 对应的记录,Load()方法会抛出异常,而 get()方法返回 null;
区别 2:load 方法默认采用延迟加载策略,get 方法采用立即检索策略;

3,update()方法 将一个游离对象转变为持久化对象;

4,saveOrUpdate()方法 包含了 save()和 update()方法;

5,merge()方法,合并对象;

6,delete()方法,删除对象;

基本类型映射

hibernate总结-持续更新

一、集合类型映射

1,Set 无序 元素不可重复

2,List 有序 元素可重复

3,Bag 无序 元素可重复

4,Map 键值对

二、检索策略

检索策略属性 Lazy

Lazy:true (默认) 延迟检索 ;set 端 一对多
Lazy:false 立即检索;set 端 一对多
Lazy:extra 增强延迟检索; set 端 一对多
Lazy:proxy(默认) 延迟检索;many-to-one 多对一
Lazy:no-proxy 无代理延迟检索;many-to-one 多对一 (需要编译时字节码增强)

检索策略属性 batch-size

1,批量延迟检索;
2,批量立即检索;

检索策略属性 Fetch

1,Fetch:select(默认) 查询方式;
2,Fetch:subselect 子查询方式;
3,Fetch:join 迫切左外连接查询方式;

三、Hibernate 查询方式

1,导航对象图查询方式;(级联)

2,OID 查询方式; (get load)

3,本地 SQL 查询方式; (数据库的语法)

4,HQL 查询方式; (面向对象)

HQL(Hibernate Query Language)是面向对象的查询语言;是使用最广的一种查询方式;
1,普通查询;
2,带条件查询;
3,使用别名;
4,对结果排序;
5,分页查询;
6,查询单个对象;
7,链式写法;

5,QBC 查询方式;(Query By Criteria)

QBC 查询方式(Query By Criteria)是用一套接口来实现的查询方式;
1,普通查询;
2,带条件查询;
3,对结果排序;
4,分页查询;
5,查询单个对象;
6,链式写法;

四、配置数据库连接池

访问数据库,需要不断的创建和释放连接,假如访问量大的话,效率比较低级,服务器消耗大;

使用数据库连接池,我们可以根据实际项目的情况,定义连接池的连接个数,从而可以实现从连接池获取连 接,用户放回到连接池。从而有效的提高的系统的执行效率;

Hibernate 自带的连接池不是很好,有 bug; 推荐使用 C3P0,proxool 等;

配置日志框架 Log4J:

Log4J 作为一个开源的优秀日志框架,被广泛使用,Hibernate4 必须包中直接支持 Log4J 日志框架;我们只需
要引入 Log4j jar 包,即可使用;

配置 Hibernate缓存

1.缓存的概念

缓存是介于物理数据源与应用程序之间,是对数据库中的数据复制一份临时放在内存或者硬盘中的容 器,其作用是为了减少应用程序对物理数据源访问的次数,从而提高了应用程序的运行性能。Hibernate 在进 行读取数据的时候,根据缓存机制在相应的缓存中查询,如果在缓存中找到了需要的数据(我们把这称做“缓 存命 中"),则就直接把命中的数据作为结果加以利用,避免了大量发送 SQL 语句到数据库查询的性能损耗。

2.Hibernate 缓存的分类

一、Session 缓存(又称作事务缓存):Hibernate 内置的,不能卸除。 缓存范围:缓存只能被当前 Session 对象访问。缓存的生命周期依赖于 Session 的生命周期,当 Session 被关闭 后,缓存也就结束生命周期。 一级缓存只适用于同一事物中

二、SessionFactory 缓存(又称作应用缓存):使用第三方插件,可插拔。 缓存范围:缓存被应用范围内的所有 session 共享,不同的 Session 可以共享。这些 session 有可能是并发访问缓 存,因此必须对缓存进行更新。缓存的生命周期依赖于应用的生命周期,应用结束时,缓存也就结束了生命 周期,二级缓存存在于应用程序范围。

3.二级缓存策略提供商

提供了 HashTable 缓存,EHCache,OSCache,SwarmCache,jBoss Cathe2,这些缓存机制,其中 EHCache, OSCache 是不能用于集群环境(Cluster Safe)的,而 SwarmCache,jBoss Cathe2 是可以的。

HashTable 缓存主 要是用来测试的,只能把对象放在内存中,EHCache,OSCache 可以把对象放在内存(memory)中,也可以 把对象放在硬盘(disk)上(为什么放到硬盘上?上面解释了)。

4.什么数据适合放二级缓存中

经常被访问
改动不大
数量有限
不是很重要的数据,允许出现偶尔并发的数据。

比如组织机构代码,列表信息等;

5.配置 EHCache 二级缓存

01 <ehcache>
02  
03 <!-- 指定一个文件目录,当EHCache把数据写到硬盘上时,将把数据写到这个目录下 -->
04 <diskStore path="c:\\ehcache"/>
05  
06 <!--
07 设置缓存的默认数据过期策略
08 -->
09 <defaultCache
10 maxElementsInMemory="10000"
11 eternal="false"
12 timeToIdleSeconds="120"
13 timeToLiveSeconds="120"
14 overflowToDisk="true"
15 />
16  
17 <!--
18 name 设置缓存的名字,他的取值为类的完整名字或者类的集合的名字;
19 maxElementsInMemory 设置基于内存的缓存可存放的对象的最大数目
20 eternal 如果为true,表示对象永远不会过期,此时会忽略timeToIdleSeconds和timeToLiveSeconds,默认为false;
21 timeToIdleSeconds 设定允许对象处于空闲状态的最长时间,以秒为单位;
22 timeToLiveSeconds 设定对象允许存在于缓存中的最长时间,以秒为单位;
23 overflowToDisk 如果为true,表示当基于内存的缓存中的对象数目达到maxElementsInMemory界限,会把溢出的对象写到基于硬盘的缓存中;
24 -->
25  
26  
27 <!-- 设定具体的第二级缓存的数据过期策略 -->
28 <cache name="com.java1234.model.Class"
29 maxElementsInMemory="1"
30 eternal="false"
31 timeToIdleSeconds="300"
32 timeToLiveSeconds="600"
33 overflowToDisk="true"
34 />
35  
36  
37 </ehcache>