hibernate主键生成策略

本文介绍了Hibernate的三种主键生成策略:increment、identity和assigned。increment策略在多实例访问时可能导致主键冲突,identity策略依赖数据库的自动增长功能,而assigned策略则需要程序员手动指定主键值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主键生成策略

一、Hibernate标识生成策略

在这里插入图片描述
关于映射文件的问题下次再介绍,这次主要总结hibernate常用主键生成策略。

(1)increment

  1. 对主键值采取自动顺序增长的方式生成新的主键,值默认从1开始。

  2. 原理:在当前应用实例中维持一个变量,以保存当前最大值,之后每次需要生成主键值的时候将此值加1作为主键.不依赖于底层的数据库,因此所有的数据库都可以使用

  3. 缺点:通过increment的生成主键的原理可推断,此种主键生成策略不适用于集群、同一时段大量用户并发访问的系统,既当大量用户同一时间段同时进行插入操作的时候,可能存在取得相同的最大值然后再同时+1的情况,这个时候就会造成主键冲突。因此,如果同一数据库有多个实例访问,此方式必须避免使用。

(2)identity

  1. a)根据底层数据库,来支持自动增长,不同的数据库用不同的主键增长方式。
  2. b)特点: 与底层数据库有关,要求数据库支持Identity,如MySQl中是auto_increment, SQL Server
    中是Identity。支持的数据库有MySql、SQL Server、DB2、Sybase和HypersonicSQL。
  3. c)好处:在建表的时候指定了id为自动增长,实际开发中就不需要自己定义插入数据库的主键值,系统会自动顺序递增一个值
    。Identity无需Hibernate和用户的干涉,使用较为方便,但由于依赖于数据库,所以不便于在不同的数据库之间移植程序。

(3)assigned

  1. a)作用:用于手工分配主键生成器,一旦指定为这个了,Hibernate就不在自动为程序做主键生成器了。没有指定标签时,默认就是assigned主键的生成方式
  2. b)使用方法:在程序中session.save();之前,由程序员自己指定主键值为多少。
  3. 例如: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);
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值