hibernate的主键生成器:
generator元素:表示了一个主键生成器,它用来为持久化类实例生成唯一的标识 。
首先我们引入一个工具类SessionFactoryUtils
package com.liuwenwu.two.util; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; /** * 这个类是在学习hibernate 的过程中所用(整合SSH框架之前用) * 作用: * 可以用来检测所写的映射文件是否正确 90% * @author ASUS * */ public class SessionFactoryUtils { private static SessionFactory sessionFactory; // 存放当前会话 private static ThreadLocal<Session> threadLocal = new ThreadLocal<Session>(); static { Configuration cfg = new Configuration(); Configuration configure = cfg.configure("/hibernate.cfg.xml"); sessionFactory = configure.buildSessionFactory(); } public static Session openSession() { //获取本地线程中的会话 Session session = threadLocal.get(); if (null == session) { session = sessionFactory.openSession(); threadLocal.set(session); } return session; } public static void closeSession() { Session session = threadLocal.get(); if (null != session) { if (session.isOpen()) { session.close(); } threadLocal.set(null); } } public static void main(String[] args) { Session session = openSession(); System.out.println(session.isConnected()); closeSession(); } }
这个类可以用来检测所写的映射文件是否出错 如果有错则如下图:
要实现hibernate的主键生成 我们先创两个实体类
Student:
package com.liuwenwu.two.entity; import java.io.Serializable; public class Student implements Serializable{ /** * */ private static final long serialVersionUID = 374274097567290896L; private int sid; private String sname; public int getSid() { return sid; } public void setSid(int sid) { this.sid = sid; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } @Override public String toString() { return "Student [sid=" + sid + ", sname=" + sname + "]"; } }
Worker:
package com.liuwenwu.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 + "]"; } }
然后对实体类进行配置:
Student.hbm.xml:
<?xml version="1.0" encoding="UTF-8"?> <!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="com.liuwenwu.two.entity.Student" table="t_hibernate_student"> <id name="sid" type="java.lang.Integer" column="sid"> <!-- 程序员自己控制 --> <!-- <generator class="assigned" /> --> <!-- hibernate控制 --> <generator class="increment" /> <!-- 数据库控制 --> <!-- <generator class="identity" /> --> <!-- 数据库控制 --> <!-- <generator class="sequence" /> --> <!-- <generator class="sequence" > <param name="sequence_name">aaa</param> </generator> --> <!-- <generator class="com.javaxl.two.id.Myts" /> --> </id> <property name="sname" type="java.lang.String" column="sname"> </property> </class> </hibernate-mapping>
Worker.hbm.xml:
<?xml version="1.0" encoding="UTF-8"?> <!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="com.liuwenwu.two.entity.Worker" table="t_hibernate_worker"> <id name="wid" type="java.lang.String" column="wid"> <!-- 程序员自己控制 --> <!-- <generator class="assigned" /> --> <!-- 由容器自动生成的一个32位的字符串 --> <!-- <generator class="uuid" /> --> <!-- <generator class="sequence" > <param name="sequence_name">aaa</param> </generator> --> <!-- 自定义主键生成器 --> <generator class="com.liuwenwu.two.id.Myts" /> </id> <property name="wname" type="java.lang.String" column="wname"> </property> </class> </hibernate-mapping>
主配置文件 hibernate.cfg.xml:
<?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> <!-- 1. 数据库相关 --> <property name="connection.username">root</property> <property name="connection.password">123</property> <property name="connection.url">jdbc:mysql://localhost:3306/t224?useUnicode=true&characterEncoding=UTF-8 </property> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- <property name="dialect">org.hibernate.dialect.OracleDialect</property> --> <!-- 配置本地事务(No CurrentSessionContext configured!) --> <property name="hibernate.current_session_context_class">thread</property> <!-- 2. 调试相关 --> <property name="show_sql">true</property> <property name="format_sql">true</property> <!-- 3. 添加实体映射文件 --> <mapping resource="com/liuwenwu/one/entity/User.hbm.xml" /> <!--主键生成策略 --> <mapping resource="com/liuwenwu/two/entity/Student.hbm.xml" /> <mapping resource="com/liuwenwu/two/entity/Worker.hbm.xml" /> </session-factory> </hibernate-configuration>
编写dao方法来进行测试
DemoDao:
package com.liuwenwu.two.dao; import java.io.Serializable; import org.hibernate.Session; import org.hibernate.Transaction; import com.liuwenwu.two.entity.Student; import com.liuwenwu.two.entity.Worker; import com.liuwenwu.two.util.SessionFactoryUtils; public class DemoDao { /** * 添加学生 * @param stu * @return */ public Serializable addStudent(Student stu) { Session session = SessionFactoryUtils.openSession(); Transaction transaction = session.beginTransaction(); Serializable save = session.save(stu); transaction.commit(); session.close(); return save; } /** * 添加工人 * @param wor * @return */ public Serializable addWorker(Worker wor) { Session session = SessionFactoryUtils.openSession(); Transaction transaction = session.beginTransaction(); Serializable save = session.save(wor); transaction.commit(); session.close(); return save; } public static void testStudent(String[] args) { DemoDao demoDao=new DemoDao(); Student stu=new Student(); // stu.setSid(8); stu.setSname("毛三"); System.out.println(demoDao.addStudent(stu));; } public static void main(String[] args) { DemoDao demoDao=new DemoDao(); Worker worker=new Worker(); worker.setWname("毛三"); System.out.println(demoDao.addWorker(worker));; } }
几种不同的主键生成方式:
1.程序员自己控制:assigned 完全由程序员自己控制,不管数据库表怎么建,必须由程序员自己提供ID
2.数据库控制: identity (根据数据库设置的标识列来实现自定增长自动增长)
2.1sequence : 使用hibernate中的默认序列 所有表共用一个序列 会出现跳号现象 不建议使用
使用时可以指定序列 <param name="sequence_name">aaa</param>
无缝跨平台:在主配置文件中修改数据库方言 可实现跨平台生成主键
Mysql语句:
Oracle语句:
3 .hibernate控制:increment 跟数据库没关系 ID必须是数字的
4 .uuid/uuid.hex (是由容器自动生成的一个32位的字符串,.hex代表的是十六进制)
32位的字符串,无需赋值
5.自定义主键生成器:创建主键生成器类
实现org.hibernate.id.IdentifierGenerator接口即可,并还可以实现org.hibernate.id.Configurable接口来读取一些配置信息
自己定义主键规则 Myts:
package com.liuwenwu.two.id; import java.io.Serializable; import java.text.SimpleDateFormat; import java.util.Date; import org.hibernate.HibernateException; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.id.IdentifierGenerator; public class Myts implements IdentifierGenerator{ @Override public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException { SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return "zking_shop_bood"+sdf.format(new Date()); } }
效果:自己定义前缀+主键生成时间