一、pom 依赖
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.18.Final</version>
<!-- <version>5.6.10.Final</version> -->
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.27</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
<scope>provided</scope>
</dependency>
二、java
1.配置文件
新建配置文件 resources/META-INF/persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="myjpa">
<!-- jpa的实现产品 -->
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<!-- 数据库连接配置 -->
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://127.0.0.1:5432/postgres"/>
<property name="javax.persistence.jdbc.user" value="postgres"/>
<property name="javax.persistence.jdbc.password" value="123456"/>
<!-- hibernate的配置 -->
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
2.实体类
1) @Entity:标注在实体类名上。标识为jpa实体类
2) @Table:标注在实体类名上。把该实体类映射到实际的表名,这个其实是非必需的,但一般实体类的名字和表名都不一样,所以认为就是必需的
@Setter
@Getter
@Entity
@Table(name = "t_student")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
// @GeneratedValue(strategy = GenerationType.SEQUENCE)
// @GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
}
3.测试类
@Test
public void testPersist() {
/**
* 通过 Persistence 获取 EntityManagerFactory, 传入参数对应配置文件中持久化单元 persistence-unit 的 name
* 通过 EntityManagerFactory 创建 EntityManager 获取 EntityTransaction 开启事务
*/
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myjpa");
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
Student stu = new Student();
stu.setId(null);
stu.setName("stu1");
// 转换为托管状态
entityManager.persist(stu);
/**
* 提交事务 关闭 entityManager 关闭 entityManagerFactory
*/
transaction.commit();
entityManager.close();
entityManagerFactory.close();
}
三、结论
1.无 @GeneratedValue 注解时
@Setter
@Getter
@Entity
@Table(name = "t_student")
public class Student {
@Id
// @GeneratedValue(strategy = GenerationType.IDENTITY)
// @GeneratedValue(strategy = GenerationType.SEQUENCE)
// @GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
}
生成创建表 sql
create table t_student (
id int4 not null,
name varchar(255),
primary key (id)
)
保存实体时,需要设置 id ,因为 id 是主键,设置 null,会报错
1.执行 Student stu = new Student(null, "stu1"); entityManager.persist(stu)
1) 报错
2.执行 Student stu = new Student(null, "stu1"); entityManager.merge(stu)
1) 报错
3.执行 Student stu = new Student(10, "stu1"); entityManager.persist(stu);
1) 若数据库不存在数据(10),则生成 sql,
insert into t_student(name, id) values (?, ?);
2) 数据库存在数据(10, "stu1"),则报错
3) 数据库存在数据(10, "stu0"),则报错
4.执行 Student stu = new Student(10, "stu1"); entityManager.merge(stu);
1) 若数据库不存在数据(10),则生成 sql,
select student0_.id as id1_0_0_, student0_.name as name2_0_0_ from t_student student0_ where student0_.id=?;
insert into t_student(name, id) values (?, ?);
2) 数据库存在数据(10, "stu1"),则生成 sql,
select student0_.id as id1_0_0_, student0_.name as name2_0_0_ from t_student student0_ where student0_.id=?;
3) 数据库存在数据(10, "stu0"),则生成 sql,
select student0_.id as id1_0_0_, student0_.name as name2_0_0_ from t_student student0_ where student0_.id=?;
update t_student set name=? where id=?;
2.@GeneratedValue(strategy = GenerationType.IDENTITY)
@Setter
@Getter
@Entity
@Table(name = "t_student")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
// @GeneratedValue(strategy = GenerationType.SEQUENCE)
// @GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
}
生成创建表 sql
-- org.hibernate:hibernate-core:5.2.18.Final 版本生成为
create table t_student (
id serial not null,
name varchar(255),
primary key (id)
)
-- org.hibernate:hibernate-core:5.6.10.Final 版本生成为
create table t_student (
id int4 generated by default as identity,
name varchar(255),
primary key (id)
)
1.执行 Student stu = new Student(null, "stu1"); entityManager.persist(stu)
1) 则生成 sql,
insert into t_student(name) values (?);
2.执行 Student stu = new Student(null, "stu1"); entityManager.merge(stu)
1) 则生成 sql,
insert into t_student(name) values (?);
3.执行 Student stu = new Student(10, "stu1"); entityManager.persist(stu);
1) 若数据库不存在数据(10),则报错
2) 数据库存在数据(10, "stu1"),则报错
3) 数据库存在数据(10, "stu0"),则报错
4.执行 Student stu = new Student(10, "stu1"); entityManager.merge(stu);
1) 若数据库不存在数据(10),则生成sql,
select student0_.id as id1_0_0_, student0_.name as name2_0_0_ from t_student student0_ where student0_.id=?;
insert into t_student(name) values (?);
2) 数据库存在数据(10, "stu1"),则生成sql,
select student0_.id as id1_0_0_, student0_.name as name2_0_0_ from t_student student0_ where student0_.id=?;
3) 数据库存在数据(10, "stu0"),则生成sql,
select student0_.id as id1_0_0_, student0_.name as name2_0_0_ from t_student student0_ where student0_.id=?;
update t_student set name=? where id=?;
注:当数据库不存在数据(10)时,new Student(10, "stu1") 相当于 new Student(null, "stu1"),id 由数据库生成。
3.@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Setter
@Getter
@Entity
@Table(name = "t_student")
public class Student {
@Id
// @GeneratedValue(strategy = GenerationType.IDENTITY)
@GeneratedValue(strategy = GenerationType.SEQUENCE)
// @GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
}
生成创建表 sql
create table t_student (
id int4 not null,
name varchar(255),
primary key (id)
)
保存实体时,需要设置 id ,因为 id 是主键,设置 null,会报错
1.执行 Student stu = new Student(null, "stu1"); entityManager.persist(stu)
1) 则生成 sql,
select nextval ('hibernate_sequence');
insert into t_student(name, id) values (?, ?);
2.执行 Student stu = new Student(null, "stu1"); entityManager.merge(stu)
1) 则生成 sql,
select nextval ('hibernate_sequence');
insert into t_student(name, id) values (?, ?);
3.执行 Student stu = new Student(10, "stu1"); entityManager.persist(stu);
1) 若数据库不存在数据(10),则报错
2) 数据库存在数据(10, "stu1"),则报错
3) 数据库存在数据(10, "stu0"),则报错
4.执行 Student stu = new Student(10, "stu1"); entityManager.merge(stu);
1) 若数据库不存在数据(10),则生成sql,
select student0_.id as id1_0_0_, student0_.name as name2_0_0_ from t_student student0_ where student0_.id=?;
select nextval ('hibernate_sequence');
insert into t_student(name, id) values (?, ?);
2) 数据库存在数据(10, "stu1"),则生成sql,
select student0_.id as id1_0_0_, student0_.name as name2_0_0_ from t_student student0_ where student0_.id=?;
3) 数据库存在数据(10, "stu0"),则生成sql,
select student0_.id as id1_0_0_, student0_.name as name2_0_0_ from t_student student0_ where student0_.id=?;
update t_student set name=? where id=?;
注:当数据库不存在数据(10)时,new Student(10, "stu1") 相当于 new Student(null, "stu1"),id 由有查询的序列生成。
4.@GeneratedValue 或 @GeneratedValue(strategy = GenerationType.AUTO)
对于 pg,等同于 GenerationType.SEQUENCE