主键生成策略
JPA中的主键生成策略由 @GeneratedValue的strategy 属性指定:
strategy的取值有4种:
- GenerationType.IDENTITY:自增、底层数据库必须支持自动增长方式(MySQL)
- GenerationType.SEQUENCE:序列、底层数据库必须支持序列(Oracle)
- GenerationType.TABLE:JPA提供的一种机制,通过一张数据库表的形式帮助我们完成主键自增
- GenerationType.AUTO:由程序自动控制、程序自动帮我们选择主键生成策略
GenerationType.IDENTITY
package pers.zhang.domain;
import javax.persistence.*;
@Entity
@Table(name = "cst_customer")
public class Customer {
/*
@Id:配置主键
@GeneratedValue:配置主键的生成策略
strrategy:
GenerationType.IDENTITY:自增、底层数据库必须支持自动增长方式(MySQL)
GenerationType.SEQUENCE:序列、底层数据库必须支持序列(Oracle)
GenerationType.TABLE:JPA提供的一种机制,通过一张数据库表的形式帮助我们完成主键自增
GenerationType.AUTO:由程序自动控制、程序自动帮我们选择主键生成策略
@Column:配置属性和字段的映射关系
name:表中字段名
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "cust_id")
private Long custId;//客户主键
@Column(name = "cust_name")
private String custName;//客户名称
@Column(name = "cust_source")
private String custSource;//客户来源
@Column(name = "cust_industry")
private String custIndustry;//客户所属行业
@Column(name = "cust_level")
private String custLevel;//客户级别
@Column(name = "cust_address")
private String custAddress;//客户地址
@Column(name = "cust_phone")
private String custPhone;//客户电话
public Long getCustId() {
return custId;
}
public void setCustId(Long custId) {
this.custId = custId;
}
public String getCustName() {
return custName;
}
public void setCustName(String custName) {
this.custName = custName;
}
public String getCustSource() {
return custSource;
}
public void setCustSource(String custSource) {
this.custSource = custSource;
}
public String getCustIndustry() {
return custIndustry;
}
public void setCustIndustry(String custIndustry) {
this.custIndustry = custIndustry;
}
public String getCustLevel() {
return custLevel;
}
public void setCustLevel(String custLevel) {
this.custLevel = custLevel;
}
public String getCustAddress() {
return custAddress;
}
public void setCustAddress(String custAddress) {
this.custAddress = custAddress;
}
public String getCustPhone() {
return custPhone;
}
public void setCustPhone(String custPhone) {
this.custPhone = custPhone;
}
@Override
public String toString() {
return "Customer{" +
"custId=" + custId +
", custName='" + custName + '\'' +
", custSource='" + custSource + '\'' +
", custIndustry='" + custIndustry + '\'' +
", custLevel='" + custLevel + '\'' +
", custAddress='" + custAddress + '\'' +
", custPhone='" + custPhone + '\'' +
'}';
}
}
测试:
@Test
public void saveTest(){
//1.加载配置文件创建工厂对象(实体管理类工厂)
EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
//2.通过实体管理类工厂获取实体管理器
EntityManager entityManager = factory.createEntityManager();
//3.获取事务对象,开启事务
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
//4.进行CRUD
Customer customer = new Customer();
customer.setCustName("阿里巴巴");
customer.setCustIndustry("电商");
//保存
entityManager.persist(customer);
//5.提交事务或回滚事务
transaction.commit();
//6.释放资源
entityManager.close();
factory.close();
}
运行JUnit测试,控制台打印:
Hibernate: drop table if exists cst_customer
Hibernate: create table cst_customer (cust_id bigint not null auto_increment, cust_address varchar(255), cust_industry varchar(255), cust_level varchar(255), cust_name varchar(255), cust_phone varchar(255), cust_source varchar(255), primary key (cust_id))
Hibernate: insert into cst_customer (cust_address, cust_industry, cust_level, cust_name, cust_phone, cust_source) values (?, ?, ?, ?, ?, ?)
JPA为我们自动生成了表并插入了数据:
GenerationType.TABLE
修改strategy的值为GenerationType.TABLE
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@Column(name = "cust_id")
private Long custId;//客户主键
运行测试方法,控制台打印:
Hibernate: drop table if exists cst_customer
Hibernate: drop table if exists hibernate_sequences
Hibernate: create table cst_customer (cust_id bigint not null, cust_address varchar(255), cust_industry varchar(255), cust_level varchar(255), cust_name varchar(255), cust_phone varchar(255), cust_source varchar(255), primary key (cust_id))
Hibernate: create table hibernate_sequences (sequence_name varchar(255) not null, next_val bigint, primary key (sequence_name))
Hibernate: select tbl.next_val from hibernate_sequences tbl where tbl.sequence_name=? for update
Hibernate: insert into hibernate_sequences (sequence_name, next_val) values (?,?)
Hibernate: update hibernate_sequences set next_val=? where next_val=? and sequence_name=?
Hibernate: insert into cst_customer (cust_address, cust_industry, cust_level, cust_name, cust_phone, cust_source, cust_id) values (?, ?, ?, ?, ?, ?, ?)
生成了cst_customer表,并插入了数据:
于GenerationType.IDENTITY不同的是,JPA同时由生成了另一张表hibernate_sequences用与生成主键。(保存了下一次插入数据时,主键的值)
GenerationType.SEQUENCE
应用于Oracle,根据Oracle提供的序列生成主键。
GenerationType.AUTO
与使用GenerationType.TABLE一致,生成一张表用来生成主键。