主键生成策略
默认使用auto的:自动匹配数据库
JPA持久对象的状态
临时态:new的时候
持久态:当发生关系的时候如persist,merge,find等方法的时候就变为持久态了
游离态:事务提交或者commit的时候
删除态:使用remove方法过后
@Test public void test01() throws Exception{ Student student = new Student(); student.setName("杰大大");//临时态 EntityManager manager = JPAJunit.getEntityManager(); manager.getTransaction().begin(); manager.persist(student);//持久态 manager.getTransaction().commit();//游离态 manager.close(); }View Code
脏数据跟新
因为我们查出来的数据放在一级缓存中,而在我们提交事务的时候会和快照中的作比较,如果不同就自动跟新(不用使用任何方法)
@Test public void testZhang() throws Exception{ //脏数据更新 //先把数据存入缓存 EntityManager manager = JPAJunit.getEntityManager(); manager.getTransaction().begin(); Student student = manager.find(Student.class, 1l);//持久态 student.setName("杰帅"); /* 这里不适用manager.merge(student);也会在数据库中更新 这就是脏数据跟新 * */ System.out.println(student); manager.getTransaction().commit();//游离态 manager.close(); }View Code
我们不能该OID这样的话,会报错,不能修改OID的错误
单向多对一
在从表的私有对象字段上面加入@ManyToOne注解
代码优化,
当我们先持久化从从表的时候会出现下面的问题,
// 先保存多方(产品) entityManager.persist(product); entityManager.persist(product2); // 保存一方(产品类型) entityManager.persist(dir); Hibernate: insert into Product (dir_id, name) values (?, ?) Hibernate: insert into Product (dir_id, name) values (?, ?) Hibernate: insert into ProductDir (name) values (?) Hibernate: update Product set dir_id=?, name=? where id=? Hibernate: update Product set dir_id=?, name=? where id=?View Code
所以我们选择先添加主表
// 保存一方(产品类型) entityManager.persist(dir); // 先保存多方(产品) entityManager.persist(product); entityManager.persist(product2); Hibernate: insert into Product (dir_id, name) values (?, ?) Hibernate: insert into Product (dir_id, name) values (?, ?) Hibernate: insert into ProductDir (name) values (?)View Code
这样在数据库中查找的时候会少一半的查询量
fetch抓取策略
获取持久状态对象之后,还需要获取关联对象,此时才会真正发出sql,获取值,在我们需要的时候抓取
public class Implyee { @Id @GeneratedValue private long id; private String name; @ManyToOne(fetch = FetchType.LAZY) private Product pro;
在我们再次调用的时候会抓取出来,执行两次select
@Test public void testLazy() throws Exception{ EntityManager manager = JPAJunit.getEntityManager(); Implyee implyee = manager.find(Implyee.class, 1L); System.out.println(implyee); System.out.println(implyee.getPro()); manager.close(); }View Code
Hibernate: select implyee0_.id as id1_0_0_, implyee0_.name as name2_0_0_, implyee0_.pro_id as pro_id3_0_0_ from t_implyee implyee0_ where implyee0_.id=? Hibernate: select product0_.id as id1_1_0_, product0_.name as name2_1_0_ from t_product product0_ where product0_.id=? Implyee{id=1, name='杰大大', pro=Product{id=1, name='老板'}} Product{id=1, name='老板'}View Code
而不适用这样的方式,只会执行一次,但是把所以的结果都查询出来了