一 .持久化对象的oid 映射为数据库表的主键,唯一不重复
当数据库表中的主键为代理主键时,持久化对象的oid 要交给hibernate来维护(避免重复)
当数据库中表的主键为自然主键时,持久化对象的oid 要由程序本身来维护
主键生成策略(生成持久化oid的方式):
1. increment 带走+1
由hibernate来维护oid的值,
优点:与底层数据库类型无关
缺点:只适用于单线程对数据库的访问
2. identity +1带走
优点:适合多用户访问
缺点:由于+1操作由数据库完成,所以数据库必须支持自增Mysql,sql server,db2
3. sequence
由数据库来维护oid的值
数据库要支持序列 Oracle,db2
4. native
根据底层数据库的能力选择 identity、sequence 或者 hilo 中的一个。
持久化对象的oid类型必须为 long,short 或者 int 类型的,不能使用byte
5. uuid
数据库表中数据量非常大,但不会经常进行查询操作,就可以使用字符串作为表单主键。
6. assigned 手动分配id
适用于自然主键
比如:loginName作为主键
三. 定义持久化对象属性时,如果属性为基本数据类型,最好使用对应的包装类型
int score;//0
Integer score;//null
四. 快照
session的一级缓存 存在快照区域
只有在查询操作时,会产生快照区域
快照区域保存查询对象的原始状态
当session执行flush方法时,会用缓存中的对象和快照中的原始数据进行比较
如果两组数据不同,则自动发送update来更新数据库
数据库中,自己手动创建序列
对应Customer.hbm.xml做的修改:
<generator class="native"> <param name="sequence">cus_id_seq</param> </generator>
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 5 <hibernate-mapping> 6 <class name="com.edu.oid.Customer" table="tab_customer"> 7 <id name="id" column="id" type="integer"> 8 <!-- 主键生成策略 9 <generator class="native"> 10 <param name="sequence">cus_id_seq</param> 11 </generator> 12 --> 13 <generator class="assigned"/> 14 </id> 15 16 <!-- 配置普通属性 --> 17 <property name="name" column="name" type="string"/> 18 <property name="age" column="age" type="integer"/> 19 <property name="des"/> 20 </class> 21 22 </hibernate-mapping>
序列跟主键号才能一一对应
二 .持久化对象生命周期的4种状态:
1. 临时状态(瞬时状态)
2. 持久化状态
3. 游离状态
4. 删除状态
session对象一级缓存 线程级别的缓存 内置的必须使用
sessionFactory对象 二级缓存 进程级别的缓存 可配置(插拔)
1 package com.edu.cache; 2 3 import org.hibernate.SessionFactory; 4 import org.hibernate.Transaction; 5 import org.hibernate.cfg.Configuration; 6 import org.hibernate.classic.Session; 7 import org.junit.Test; 8 9 /** 10 * 使用单元测试工具,测试hibernate 的增删改查(CRUD)操作 11 * 12 * @author Administrator 13 * 14 */ 15 public class TestHibernate { 16 17 private static SessionFactory sf; 18 static { 19 // 1. 加载配置文件 20 Configuration cfg = new Configuration(); 21 cfg.configure("com/edu/cache/hibernate.cfg.xml"); 22 23 // 2. 获得SessionFactory 24 sf = cfg.buildSessionFactory(); 25 } 26 27 28 @Test 29 public void find() { 30 31 32 Session session = sf.openSession(); 33 Transaction tran = session.beginTransaction(); 34 35 Customer c1 = (Customer) session.get(Customer.class, 1);//发生sql 36 Customer c3 = (Customer) session.get(Customer.class, 2);//发生sql 37 Customer c2 = (Customer) session.get(Customer.class, 1);//不发生sql 38 39 tran.commit(); 40 session.close(); 41 } 42 43 @Test 44 public void flush() { 45 46 47 Session session = sf.openSession(); 48 Transaction tran = session.beginTransaction(); 49 50 //临时状态 新建对象 不被session缓存管理,oid的值为null 51 Customer c = new Customer(); 52 c.setName("张三"); 53 54 /* 55 * 纳入到session缓存管理,并为其分配了oid的值,由临时状态转变为持久化状态 56 * 数据库中没有与之关联的记录 57 */ 58 session.save(c);//不发送insert 59 60 //刷新缓存,被生产sql语句发送给数据库,并准备执行 61 session.flush();//发送 62 63 /* 64 * 执行sql语句,影响数据库中的记录 65 * 如果程序中没有手动调用flush方法, 66 * commit提交事务前,会自动调用flush. 67 */ 68 tran.commit(); 69 //session关闭,缓存释放,由持久化状态转换为游离状态。处于游离状态的对象生命周期并没有结束 70 session.close(); 71 System.out.println(c.getName()); 72 c = null;//对象c的生命周期结束 73 } 74 75 //清空缓存 76 @Test 77 public void clear() { 78 79 80 Session session = sf.openSession(); 81 Transaction tran = session.beginTransaction(); 82 83 Customer c1 = (Customer) session.get(Customer.class, 1);//发生sql 84 session.clear(); 85 Customer c2 = (Customer) session.get(Customer.class, 1);//发生sql 86 87 tran.commit(); 88 session.close(); 89 } 90 //清除 91 @Test 92 public void evict() { 93 94 95 Session session = sf.openSession(); 96 Transaction tran = session.beginTransaction(); 97 98 Customer c1 = (Customer) session.get(Customer.class, 1);//发生sql 99 Customer c2 = (Customer) session.get(Customer.class, 2);//发生sql 100 session.evict(c1); 101 102 Customer c3 = (Customer) session.get(Customer.class, 1);//发生sql 103 //Customer c4 = (Customer) session.get(Customer.class, 2);//不发生sql 104 session.update(c1);//c1从游离状态转为持久化状态 105 106 tran.commit(); 107 session.close(); 108 } 109 110 //批量插入50万条记录 111 /*@Test 112 public void batchSave() { 113 114 115 Session session = sf.openSession(); 116 Transaction tran = session.beginTransaction(); 117 118 for(int i=0;i<500001;i++) { 119 Customer c = new Customer(); 120 c.setName("tom"+i); 121 session.save(c); 122 123 if(i%10000==0) { 124 session.flush();//向数据库发送了10000条insert语句 125 session.clear();//清空缓存 126 } 127 } 128 129 tran.commit(); 130 session.close(); 131 }*/ 132 133 //快照 134 @Test 135 public void kuaiZhao() { 136 137 138 Session session = sf.openSession(); 139 Transaction tran = session.beginTransaction(); 140 141 Customer c = (Customer) session.get(Customer.class, 1); 142 c.setName("tom"); 143 System.out.println(c.getId()); 144 145 146 //更新前查询,避免由此操作改名了持久化对象的状态,二影响数据库中的记录。 147 // session.refresh(c); 148 // session.update(c); 149 150 tran.commit(); 151 session.close(); 152 } 153 154 }