JPA02

主键生成策略

 默认使用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

而不适用这样的方式,只会执行一次,但是把所以的结果都查询出来了

原文地址:https://www.cnblogs.com/xiaoruirui/p/11601416.html