主键生成策略
一、Hibernate标识生成策略
关于映射文件的问题下次再介绍,这次主要总结hibernate常用主键生成策略。
(1)increment
-
对主键值采取自动顺序增长的方式生成新的主键,值默认从1开始。
-
原理:在当前应用实例中维持一个变量,以保存当前最大值,之后每次需要生成主键值的时候将此值加1作为主键.不依赖于底层的数据库,因此所有的数据库都可以使用
-
缺点:通过increment的生成主键的原理可推断,此种主键生成策略不适用于集群、同一时段大量用户并发访问的系统,既当大量用户同一时间段同时进行插入操作的时候,可能存在取得相同的最大值然后再同时+1的情况,这个时候就会造成主键冲突。因此,如果同一数据库有多个实例访问,此方式必须避免使用。
(2)identity
- a)根据底层数据库,来支持自动增长,不同的数据库用不同的主键增长方式。
- b)特点: 与底层数据库有关,要求数据库支持Identity,如MySQl中是auto_increment, SQL Server
中是Identity。支持的数据库有MySql、SQL Server、DB2、Sybase和HypersonicSQL。 - c)好处:在建表的时候指定了id为自动增长,实际开发中就不需要自己定义插入数据库的主键值,系统会自动顺序递增一个值
。Identity无需Hibernate和用户的干涉,使用较为方便,但由于依赖于数据库,所以不便于在不同的数据库之间移植程序。
(3)assigned
- a)作用:用于手工分配主键生成器,一旦指定为这个了,Hibernate就不在自动为程序做主键生成器了。没有指定标签时,默认就是assigned主键的生成方式
- b)使用方法:在程序中session.save();之前,由程序员自己指定主键值为多少。
- 例如:user.setId(1);这就是在程序中程序员手动为用户表指定主键值为1。
项目显示:
二、代码
util帮助包
SessionFactoryUtils
package com.DZY.two.util;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/**
* 本工具类的作用
* 1.简化代码的书写
* 2.检测hibernate相关的配置是否正确
* @author Aromanic150
*
*/
public class SessionFactoryUtils {
private static SessionFactory sessionFactory;
static {
Configuration cfg = new Configuration().configure("hibernate.cfg.xml");
sessionFactory = cfg.buildSessionFactory();
}
public static Session openSession() {
Session session = sessionFactory.getCurrentSession();
if(session == null) {
session = sessionFactory.openSession();
}
return session;
}
public static void closeSession() {
Session session = sessionFactory.getCurrentSession();
if(session != null && session.isOpen()) {
session.close();
}
}
public static void main(String[] args) {
Session session = SessionFactoryUtils.openSession();
session.beginTransaction();
System.out.println(session.isConnected());
SessionFactoryUtils.closeSession();
System.out.println(session.isConnected());
}
}
entity实体类
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.DZY.two.entity.Student" table="t_hibernate_student">
<id name="sid" type="java.lang.Integer" column="sid">
<!-- <generator class="assigned" /> -->
<!-- <generator class="increment" /> -->
<generator class="identity" />
<!-- <generator class="sequence" /> -->
<!-- <generator class="sequence" > <param name="sequence_name">aaa</param>
</generator> -->
<!-- <generator class="com.DZY.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.DZY.two.entity.Worker" table="t_hibernate_worker">
<id name="wid" type="java.lang.String" column="wid">
<generator class="assigned" />
<!-- <generator class="sequence" /> -->
<!-- <generator class="sequence" > <param name="sequence_name">aaa</param>
</generator> -->
<!-- <generator class="com.DZY.two.id.Myts" /> -->
</id>
<property name="wname" type="java.lang.String" column="wname">
</property>
</class>
</hibernate-mapping>
Student
package com.DZY.two.entity;
public class Student {
private Integer sid;
private String sname;
public Integer getSid() {
return sid;
}
public void setSid(Integer 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.DZY.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 + "]";
}
}
dao包
DemoDao
package com.DZY.two.dao;
import java.io.Serializable;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.DZY.two.entity.Student;
import com.DZY.two.entity.Worker;
import com.DZY.two.util.SessionFactoryUtils;
public class DemoDao {
/**
* 添加学生
* @param stu
* @return
*/
public Serializable addStu(Student stu) {
Session session=SessionFactoryUtils.openSession();
Transaction transaction=session.beginTransaction();
Serializable save=session.save(stu);
transaction.commit();
SessionFactoryUtils.closeSession();
return save;
}
/**
* 添加工人
* @param worker
* @return
*/
public Serializable addWorker(Worker worker) {
Session session=SessionFactoryUtils.openSession();
Transaction transaction=session.beginTransaction();
Serializable save=session.save(worker);
transaction.commit();
SessionFactoryUtils.closeSession();
return save;
}
}
下面这个类是通过一下步骤:
1、将上面类拷好。
2 点击类名。
3、然后按ctrl+n。
选择New JUnit 4 test.
然后确定。显示这个类
DemoDaoTest
package com.DZY.two.dao;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.DZY.two.entity.Student;
public class DemoDaoTest {
private DemoDao demoDao=new DemoDao();
@Before
public void setup() throws Exception{
// System.out.println("测试所有要测试的方法都会执行的内容(一般用来初始化数据所用)");
}
@After
public void tearDown() throws Exception{
// System.out.println("测试所有要测试的方法之后都会执行的内容(一般用来释放资源所用)");
}
@Test
public void testAddStu() {
// System.out.println("要测试的方法一");
Student stu=new Student();
stu.setSname("kin");
stu.setSid(83);
demoDao.addStu(stu);
}
@Test
public void testAddWorker() {
@Test
public void testAddWorker() {
Worker worker=new Worker();
worker.setWname("asd");
worker.setWid("121315");
demoDao.addWorker(worker);
}
}
}
第一个操作
Student.hbm.xml的操作。
<generator class="increment" />
public void testAddStu() {
// System.out.println("要测试的方法一");
Student stu=new Student();
stu.setSname("鸡你太美");
demoDao.addStu(stu);
}
第二种
Student.hbm.xml的操作。
<generator class="assigned" />
@Test
public void testAddStu() {
// System.out.println("要测试的方法一");
Student stu=new Student();
stu.setSname("鸡你太美");
stu.setSid(80);
demoDao.addStu(stu);
}
第三种
Student.hbm.xml的操作。要设置自动增长
<generator class="identity" />
@Test
public void testAddStu() {
// System.out.println("要测试的方法一");
Student stu=new Student();
stu.setSname("kin");
stu.setSid(83);
demoDao.addStu(stu);
}
第四种
@Test
public void testAddWorker() {
Worker worker=new Worker();
worker.setWname("asd");
worker.setWid("121315");
demoDao.addWorker(worker);
}
Myts
package com.DZY.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 "book_category_"+sdf.format(new Date());
}
}
@Test
public void testAddWorker() {
Worker worker=new Worker();
worker.setWname("asdwwdd");
demoDao.addWorker(worker);
}