所有的注解都是定义在getter方法的类名上的。
最好不要把类名或者字段名定义为数据库中的关键字相同!!!!!
JPA的配置文件persistence.xml是在META-INF文件夹下的
EntityManager,在对数据库做查询操作的时候,不需要开始事务,也就是说:
EntityManagerFactory factory=Persistence.createEntityManagerFactory();
EntityManager em=factory.createEntityManager();
em.getTransaction.begin();//开始事务
Person person=em.find(Person.class,1);
System.out.println(person.getName());
em.getTransaction.commit();
em.close();
factory.close();
上面代码中的
em.getTransaction.begin();//开始事务
em.getTransaction.commit();
这两行代码是不需要的(在查询数据库的时候)
只有在修改的时候,需要事务。(增、删、改操作)
获取数据的em.find(Person.class,1);相当于hibernate中的get(Person.class,1);方法,如果没有数据,会返回null值。
JPA还有一个方法em.getReference(Person.class,1);
相当于hibernate中的load()方法,执行em.getReference(Person.class,1);的时候并不会去数据库中拿数据,
而是在person.getName();的时候才会去数据库中查询,name的值。如果没有相应数据,会报异常。
EntityNotFoundException
实体的三个状态:
new :新创建的对象
managered 托管(非脱管,以前老记为脱管)
事务之内,是托管态。在托管态的对象是和数据库关联的。
EntityManagerFactory factory=Persistence.createEntityManagerFactory();
EntityManager em=factory.createEntityManager();
em.getTransaction.begin();//开始事务
Person person=em.find(Person.class,1);//托管
System.out.println(person.getName());
em.getTransaction.commit();
em.close();
factory.close();
游离(脱管)状态
EntityManagerFactory factory=Persistence.createEntityManagerFactory();
EntityManager em=factory.createEntityManager();
em.getTransaction.begin();//开始事务
Person person=em.find(Person.class,1);
em.clear();//清空缓存
System.out.println(person.getName());//这时候的person是游离态。也就是没有和数据库联系,对它修改不会同步到数据库
em.getTransaction.commit();
em.close();
factory.close();
有一个方法可以把游离态的实体对象,和数据库关联起来(前提是必须是游离态的对象)
EntityManagerFactory factory=Persistence.createEntityManagerFactory();
EntityManager em=factory.createEntityManager();
em.getTransaction.begin();//开始事务
Person person=em.find(Person.class,1);
em.clear();//清空缓存,这个时候,person是游离态的。
person.setName("tom");
em.merge(person);
em.getTransaction.commit();
em.close();
factory.close();
这里的merge会把游离态的person联系到数据库,所做修改会先保存到session中。在commit之后
会保存到数据库中。merge的目的就是把游离态的数据和数据库联系起来。
删除状态
EntityManagerFactory factory=Persistence.createEntityManagerFactory();
EntityManager em=factory.createEntityManager();
em.getTransaction.begin();//开始事务
Person person=em.find(Person.class,1);
em.remove(person);
em.getTransaction.commit();
em.close();
factory.close();
多的一方为关系维护端,关系维护端负责外键记录的更新,关系被维护端是没有权利
oneToMany是在一端配置的
@oneToMany(cascade=(CascadeType.PERSIST,CascadeType.REFRESH,CascadeType.REMOVE))
级联的几种方式:ALL,MERGE,PERSIST,REFRESH,REMOVE
PERSIST:级联持久化(或者可以理解为级联保存??),one端数据持久化的时候,many端数据也会持久化
MERGE:级联更新(可以认识是修改数据的时候级联?也就是做update的时候?)
REFRESH:级联刷新:也就是如果其他用户修改了一条数据的话,我再用这个数据之前要重新获取一次,以防止要操作的数据是错误的。感觉像是防止脏读的。
REMOVE:就是级联删除啦,如果one端数据被删除,那么many端与与之对应的数据也会被删除。
EntityManagerFactory factory=Persistence.createEntityManagerFactory();
EntityManager em=factory.createEntityManager();
em.getTransaction.begin();//开始事务
Person person=em.find(Person.class,1);
em.refreash(person);//重新从数据库中获取一次数据。可能在你操作的过程中别人对它进行了修改操作。
em.getTransaction.commit();
em.close();
factory.close();
JPA延迟加载(相当于hibernate中的lazy=true,lazy=false)
@oneToMany(cascade=(CascadeType.REFREASH),fetch=FetchType.EAGER)
fetchType有两种:EAGER,LAZY
EAGER就是立即加载。LAZY是延迟加载
如果要使用LAZY的话,也就是延迟加载的话,那么再获取one端数据的时候,不会去查询many端的数据。
而且,要从one端对象获取many端数据的时候是再次从数据库中查询得到的。这个时候必须保证EntityManager是打开状态。
只要是级联获取many端数据的时候,默认是LAZY。也就是说@oneToMany,@ManyToMany默认都是延迟加载的。
关系维护的控制权(相当于hibernate中的inverse)
@oneToMany(fetch=FetchType.EAGER,mapperBy="order")//这里的order要看many端类里定义的属性名是什么,比如:
One端类为Order.java
many端为OrderItem.java,在OrderItem.java中定义了一个private Order order;
那在One端中的@oneToMany()中就要定义这样一个mapperBy="order",表示他们两个的外键关系由many端的order来维护。
好像是mapperBy只定义在关系被维护端。就是有外键的一端来维护外键关系。
@ManyToOne(),默认是立即加载。
optional
@ManyToOne(optional=true)
public Order getOrder()
{
return order;
}
@ManyToMany()中还有一个属性optional,它有两个值true,false
true代表many端的Order属性可以为Null,false表示不能为null.
@JoinColumn(name="order_id")
public Order getOrder()上还要定义一个外键关系字段是哪个。
@ManyToMany双向关联关系
例子:teachers,students,
老师做关系的被维护段,学生做关系的维护段。
那么在老师和学生的关系没解除的情况下,不可以直接通过EntityManager的remove方法删除teacher对象。
必须在学生端先解除关系,才可以对老师进行remove.
删除学生的时候
联合主键
例如:飞机的:startCity,endCity.这两个属性做为联合主键。
要求:
1. 必须实现Serializable接口
2. 必须有一个无参数的构造方法
3. 重写hashCode()和equals(),重写这两个方法必须要联合主键的属性endCity,startCity.
(直接右键,override就可以了。)
例子:
联合主键类:
@Embeddable //这个注解表明要使用AirLinePK中的两个字段做其他实体类的联合主键。
AirLinePK.java
两个属性,private String startCity,endCity,然后是setter/getter方法
实现Serializable接口,重写hashCode(),equals()方法。有一个无参的构造方法。
Airline.java
private AirLinePK id;
private String name;
//getter/setter方法
@EmbeddedId // 表明它是做为联合主键的
public AirLinePK getId()
{
return id;
}
<div
相关推荐
java jee技术,jpa的使用接受学习笔记。
JPA学习笔记
JPA学习笔记-EJB-04JPA关联映射总结 JPA JPA关联映射JPA学习笔记-EJB-04JPA关联映射总结 JPA JPA关联映射
传智播客——JPA学习笔记 网络上有一份pdf格式的《JPA学习笔记》,但是内容排版有点乱,而且有缺失的部分,小弟从原来的blog处拷贝出来,并加以排版,制作成了chm格式的,大家应该知道chm格式比较适合作为参考资料或...
这里面的太贵了,来个免费的. 这是一个很不错的笔记哦
在学习JPA的过程中将JPA的核心的内容整理了一下做成一份JPA学习笔记希望能够帮助到其他正在学习或者将要学习JPA的朋友。
jpa 详解 学习笔记 传智播客 内容经典
JPA学习笔记-EJB-06JPA+Spring使用经验。
本文是学习 JPA 笔记,可能会根据自己的学习进度逐渐完善。...随着笔者的学习笔记,大家一起学习吧,还是那句话,有什么问题 大家一起探讨。有什么错误希望指证!谢谢。 http://blog.csdn.net/suhuanzheng7784877
总结一下关于JPA的主键生成策略,JPA是用@GeneratedValue标记来注释的。一般的我把主键生成分成两大类。第一个就是简单的单字段主键类型,一个就是复杂的复合主键类型。我们分2种情况分别讨论。 第一种单字段主键...
初学jpa,有一些体会和大家分享一下,主要是介绍了jpa中state的概念和应用
上次简单介绍了JPA的基本部署和操作过程,算是认识JPA了,下面我们继续学习JPA吧,我们从JPA的注解标记@Table和@Column开始逐渐介绍。
jpa常用方法,适合新手下载学习 其中包括select/upate/delete/insert 以及in、notin、等等
网上整理的学习笔记,对于初学者认识,文档归集还是有好处的
JPA入门学习笔记,包含实体表的关联映射
虽然持久化实体的状态在ORM中是一个老生常谈的问题,但是说实在的,我们在开发过程中真的不太在意实体的状态。在Web一般情况下也都是交给Spring去管理实体管理器(EntityManager),所以我们还是有必要啰嗦一下,...
jpa 全面学习资料 入门 实战 示例 jpa开发手册 JPA_全面讲解 JPA使用入门_基础 JPA学习笔记 JPA注解 JPA简介