hibernate的主键生成策略
hibernate的主键生成器
generator元素:表示了一个主键生成器,它用来为持久化类实例生成唯一的标识 。
1.不同的控制类型
1.1 assigned: 程序员自己控制,与数据库自增无关
1.2 identity(标识列/自动增长) sequence 数据库控制自增,与程序员赋值无关
1.4 increment: hibernate控制,与程序员赋值无关,与数据库自增也无关,但值是根据数据库最后一位自增
uuid/uuid.hex: hibernate控制,生成String类型的id
2.实例代码
2.1 新建实体类
Student
1 package com.yuan.two.entity; 2 3 public class Student { 4 5 private Integer sid; 6 private String sname; 7 public Integer getSid() { 8 return sid; 9 } 10 public void setSid(Integer sid) { 11 this.sid = sid; 12 } 13 public String getSname() { 14 return sname; 15 } 16 public void setSname(String sname) { 17 this.sname = sname; 18 } 19 @Override 20 public String toString() { 21 return "Student [sid=" + sid + ", sname=" + sname + "]"; 22 } 23 public Student(Integer sid, String sname) { 24 super(); 25 this.sid = sid; 26 this.sname = sname; 27 } 28 public Student() { 29 super(); 30 // TODO Auto-generated constructor stub 31 } 32 33 34 }
Worker
package com.yuan.two.entity; public class Worker { private String wid; private String wname; public String getWid() { return wid; } public void setWid(String wid) { this.wid = wid; } public String getWname() { return wname; } public void setWname(String wname) { this.wname = wname; } @Override public String toString() { return "Worker [wid=" + wid + ", wname=" + wname + "]"; } public Worker(String wid, String wname) { super(); this.wid = wid; this.wname = wname; } public Worker() { super(); // TODO Auto-generated constructor stub } }
2.2 配置实体类对应的映射文件
Student.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 <class name="com.yuan.two.entity.Student" table="t_hibernate_student"> 7 <id name="sid" type="java.lang.Integer" column="sid"> 8 <!-- <generator class="assigned" /> --> 9 <!-- <generator class="identity" /> --> 10 <!-- <generator class="increment" /> --> 11 <generator class="sequence" /> 12 <!-- <generator class="sequence" > <param name="sequence_name">aaa</param> 13 </generator> --> 14 <!-- <generator class="com.javaxl.two.id.Myts" /> --> 15 </id> 16 <property name="sname" type="java.lang.String" column="sname"> 17 </property> 18 </class> 19 </hibernate-mapping>
Worker.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 <class name="com.yuan.two.entity.Worker" table="t_hibernate_worker"> 7 <id name="wid" type="java.lang.String" column="wid"> 8 <!-- <generator class="assigned" /> --> 9 <generator class="uuid" /> 10 <!-- <generator class="com.yuan.two.id.MyTsGenerator" /> --> 11 <!-- <generator class="sequence" > <param name="sequence_name">aaa</param> 12 </generator> --> 13 <!-- <generator class="com.javaxl.two.id.Myts" /> --> 14 </id> 15 16 <property name="wname" type="java.lang.String" column="wname"> 17 </property> 18 </class> 19 </hibernate-mapping>
2.3 将实体映射文件配置到核心配置文件中 - - 主键生成策略
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 <property name="connection.username">root</property> 9 <property name="connection.password">123</property> 10 <property name="connection.url">jdbc:mysql://localhost:3306/xm_sc?useUnicode=true&characterEncoding=UTF-8 11 </property> 12 <property name="connection.driver_class">com.mysql.jdbc.Driver</property> 13 <property name="dialect">org.hibernate.dialect.MySQLDialect</property> 14 15 <!-- 配置本地事务(No CurrentSessionContext configured!) --> 16 <property name="hibernate.current_session_context_class">thread</property> 17 18 <!-- 2. 调试相关 --> 19 <property name="show_sql">true</property> 20 <property name="format_sql">true</property> 21 22 <!-- 3. 添加实体映射文件 --> 23 <mapping resource="com/yuan/one/entity/User.hbm.xml" /> 24 <!-- 主键生成策略 --> 25 <mapping resource="com/yuan/two/Student.hbm.xml" /> 26 <mapping resource="com/yuan/two/Worker.hbm.xml"/> 27 </session-factory> 28 </hibernate-configuration>
2.4编写dao层测试类
DemoDao
1 package com.yuan.two.dao; 2 3 import org.hibernate.Session; 4 import org.hibernate.Transaction; 5 6 import com.yuan.two.entity.Student; 7 import com.yuan.two.entity.Worker; 8 import com.yuan.two.util.SessionFactoryUtils; 9 10 /** 11 * hibernate中的主键生成策略 12 * 1、人工控制 13 * 2、数据库控制 14 * 3、hibernate控制 15 * 4、自定义主键生成策略 16 * @author ly 17 * 18 */ 19 public class DemoDao { 20 21 /** 22 * 新增学生 23 * @param stu 24 */ 25 public void addStudent(Student stu) { 26 //调用工厂助手类获取session会话 27 Session session = SessionFactoryUtils.openSession(); 28 //获取事务对象 29 Transaction transaction = session.beginTransaction(); 30 //操作数据库 31 session.save(stu); 32 //提交事务 33 transaction.commit(); 34 //关闭session 35 SessionFactoryUtils.closeSession(); 36 } 37 38 /** 39 * 新增工人 40 * @param worker 41 */ 42 public void addWorker(Worker worker) { 43 Session session = SessionFactoryUtils.openSession(); 44 Transaction transaction = session.beginTransaction(); 45 session.save(worker); 46 transaction.commit(); 47 SessionFactoryUtils.closeSession(); 48 } 49 50 //测试代码 51 public static void testStudent() { 52 DemoDao dao = new DemoDao(); 53 Student stu = new Student(); 54 stu.setSname("源 2"); 55 stu.setSid(76); 56 dao.addStudent(stu); 57 } 58 public static void main(String[] args) { 59 DemoDao dao = new DemoDao(); 60 Worker worker = new Worker(); 61 worker.setWname("小源儿ya"); 62 dao.addWorker(worker); 63 } 64 65 66 }
工厂辅助类
1 package com.yuan.two.util; 2 3 import org.hibernate.Session; 4 import org.hibernate.SessionFactory; 5 import org.hibernate.cfg.Configuration; 6 7 8 /** 9 * 仅在学习hibernate的工程中使用,当进入spring的学习后就没用了,后面会有ssh来替代它 10 * 作用: 11 * 用来检测hibernate中的配置文件的准确性,(hibernate.cfg.xml和*.hbm.xml) 12 * 13 * 14 * @author 刘源 15 * 16 */ 17 public class SessionFactoryUtils { 18 private static SessionFactory sessionFactory; 19 static { 20 Configuration cfg = new Configuration().configure("/hibernate.cfg.xml"); 21 sessionFactory = cfg.buildSessionFactory(); 22 } 23 24 public static Session openSession() { 25 //从本地的线程中获取session会话,第一次肯定是获取不到的,那么需要重新让sessionfactory创建一个session出来 26 //第二次就能够对第一次创建的session反复利用,节约性能 27 Session session = sessionFactory.getCurrentSession(); 28 if(session == null) { 29 session = sessionFactory.openSession(); 30 } 31 return session; 32 } 33 34 public static void closeSession() { 35 Session session = sessionFactory.getCurrentSession(); 36 if(session != null && session.isOpen()) { 37 session.close(); 38 } 39 } 40 41 public static void main(String[] args) { 42 Session session = SessionFactoryUtils.openSession(); 43 session.beginTransaction(); 44 System.out.println(session.isConnected()); 45 SessionFactoryUtils.closeSession(); 46 System.out.println(session.isConnected()); 47 } 48 }
2.5 测试
assigned: 程序员自己控制,与数据库自增无关
映射文件内容
<id name="sid" type="java.lang.Integer" column="sid">
<generator class="assigned" />
</id>
测试内容
public static void main(String[] args) { DemoDao dao = new DemoDao(); Student stu = new Student(); stu.setSname("源"); stu.setSid(70); dao.addStudent(stu); }
测试结果
identity(标识列/自动增长) sequence (二选一)可自行测试不同,
-- 数据库控制自增,与程序员赋值无关
identity 实体映射文件
<id name="sid" type="java.lang.Integer" column="sid">
<generator class="identity" />
</id>
测试内容
public static void main(String[] args) { DemoDao dao = new DemoDao(); Student stu = new Student(); stu.setSname("源 2"); stu.setSid(76); dao.addStudent(stu); }
测试结果 因误删数据导致数据多了一位
increment hibernate控制,与程序员赋值无关,
与数据库自增也无关,但值是根据数据库最后一位自增
实体映射文件
<id name="sid" type="java.lang.Integer" column="sid">
<generator class="increment" />
</id>
测试内容
public static void main(String[] args) { DemoDao dao = new DemoDao(); Student stu = new Student(); stu.setSname("xiao源"); stu.setSid(76); dao.addStudent(stu); }
测试结果
uuid/uuid.hex: hibernate控制,生成String类型的id
实体映射文件
<id name="sid" type="java.lang.Integer" column="sid">
<generator class="uuid" />
</id>
测试内容
public static void main(String[] args) { DemoDao dao = new DemoDao(); Worker worker = new Worker(); worker.setWname("小源儿ya2"); dao.addWorker(worker); }
测试结果
3.自定义主键生成器
新建 MyTsGenerator.java 并实现org.hibernate.id.IdentifierGenerator接口即可
1 package com.yuan.two.id; 2 3 import java.io.Serializable; 4 import java.text.SimpleDateFormat; 5 import java.util.Date; 6 7 import org.hibernate.HibernateException; 8 import org.hibernate.engine.spi.SharedSessionContractImplementor; 9 import org.hibernate.id.IdentifierGenerator; 10 11 public class MyTsGenerator implements IdentifierGenerator { 12 13 @Override 14 public Serializable generate(SharedSessionContractImplementor arg0, Object arg1) throws HibernateException { 15 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 16 17 return "book_order_"+sdf.format(new Date()); 18 } 19 20 }
实体映射文件填入类的全路径
<id name="sid" type="java.lang.Integer" column="sid">
<generator class="com.yuan.two.id.MyTsGenerator" />
</id>
测试内容
public static void main(String[] args) { DemoDao dao = new DemoDao(); Worker worker = new Worker(); worker.setWname("小源儿ya3"); dao.addWorker(worker); }
测试结果
谢谢观看!!!