对JPA的理解与回顾总结(一)

本文深入探讨了JPA(Java Persistence API)作为持久化规范的重要性,阐述了其与传统数据库操作方式的区别,重点讲解了对象关系映射(ORM)、持久化API和JPQL查询语言的应用。同时,介绍了JPA应用开发的两种思路,详细解释了事务类型(本地、全局、集群),并以客户和订单关系为例,展示了如何使用JPA的持久化API进行数据库操作。此外,文章还讨论了实体bean与数据库表之间的映射关系,如多对一关系的维护与配置,并通过代码实例演示了如何实现延迟加载,以及如何利用JPA进行增删改查操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是JPA?
即Java Persistence API;java持久化api;
JPA是一套规范:类似于jdbc;
在没有jdbc之前,我们对数据库的操作是直接面向数据库厂商提供的api进行编程的
我们的程序和数据库api紧密的耦合在一起,而出现jdbc了,
我们可以直接面向jdbc编程,从而和个数据库厂商提供的api解耦;
类似的,在持久化产品中,有Hibernate,Toplink,等,我们使用这些产品进行持久化操作时,
自身程序和持久化产品严密耦合;基于这样的考虑。出现了JPA
这只是一个规范,而不是一个产品,因此使用的时候需要有实现类的支持;
类似于我们使用jdbc时要有相关数据库的驱动类;
这是面向接口编程的体现;
JPA:提供了三个技术
1 对象关系映射,ORM映射元数据;

2 持久化api

3 JPQL查询语言;
JPA的配置文件:固定写法,persistence.xml;
我们开发一个JPA应用有两种思路;
也就是说在数据库表和实体bean以及配置文件的编写先后顺序上来分
 1 :先建数据库表,根据数据库表的结构编写配置文件和实体bean-这是一中传统的数据库建模思


2 :先创建好实体bean,根据实体bean编写配置文件和数据库表;即领域建模思想--这是一个面向

对象编程的思想,根据实体对象的形态,来编写配置文件和数据库表;;

事务类型:本地事务,全局事务,集群事务;

全局事务:有一个二次提交协议;
即每个事务完成后提交,但是不是真正的提交,交给一个全局事务处理器;

全局事务处理器根据每个事务的提交情况,如果全部成功提交,则全局事务处理器就将
事务真正的提交;如果有一个事务没有提交成功则撤销,即回滚该事务;

开发一个JPA应用的步骤:
1 导入开发jar包
2 准备配置文件;在类路径下的META-INF目录下,名称为persistence.xml;
3 创建实体bean,使用注解对这些实体bean及属性进行标识;一般将注解放到get方法上

关于bean的属性值和数据库表中字段的设置;
我们可以用注解在bean上进行指定,比如指定某个字段的长度,列名,不得为空,以及其他一些属性

;一句话只要在数据库中能设置的几乎都可以在bean中通过注解进行给定;
当我们的bean中有一个属性不需要跟数据库中的表有任何关系;可以指定Transient;
也就说我们的bean属性,默认是跟数据库中的表是相关联的,即使是没有带上注解;

Basic(fetch=FetchType.LAZY)设置延时加载!!!

当某个对象数据库中没有时,而且我对他进行获取时,只有当使用到这个延迟初始化对象时才会发生

异常;
增删改查跟Hibernate差不多。。。

针对对象和数据库表中的映射:我会举例子说明。

它分为如下几种情况:

多对一(或者说一对多):一对多:多的一方为关系维护端,所谓关系的维护端是指负责外键记录的更新。

比如说:订单和客户的关系,一个客户可以有多个订单,一个订单只能属于一个客户;
我们可以根据一个订单号来获取该订单所属的客户,知道这个客户后,我们可以查询到
这个客户有多少个订单,这应该算是一个典型的例子吧。

客户表中没有订单项这个字段,因此多的一方为关系的维护端,因为订单表中有客户的id号;
现在终于明白了。。。


因此在定义Orders类和Customer类时;
Orders:orderno,money,customer
Customer:orders,id,name;
多的一方是维护端,即Orders为维护端,他应该加入一个字段custom_id,表示客户的id;
作为一个JoinColumn;维护端的关联字段要加一个joincolumn;作为一个外键;

关系的被维护段是没有权利更新外键字段的;

不多说,来一个例子,顺便将JPA的持久化api也说明一下;客户和订单的关系:

 


package cn.itcast.domain;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
@Entity
public class Customer {
 private String id;
 private String name;
 private Set orders = new HashSet();
 public Customer() {
  super();
  // TODO Auto-generated constructor stub
 }
 @Id
 public String getId() {
  return id;
 }
 public void setId(String id) {
  this.id = id;
 }
 // 表示 射到数据库中表的字段名称为NAME,长度为10,不得为空;
 @Column(name = "NAME", length = 10)
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 
 @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE,
   CascadeType.REFRESH, CascadeType.REMOVE },
   fetch = FetchType.LAZY, mappedBy = "customer")
 public Set getOrders() {
  return orders;
 }
 public void setOrders(Set orders) {
  this.orders = orders;
 }
}




package cn.itcast.domain;
import java.util.Set;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.EntityTransaction;
public class TestManyToOne {
 
 public static void main(String[] args) {
  update();
 }
 public static void persist() {
  //获取实体管理器工厂
  EntityManagerFactory factory = Persistence
    .createEntityManagerFactory("itcast");
  //通过实体管理器工厂获取实体管理器
  EntityManager entityManager = factory.createEntityManager();
  //获取实体管理器事务;
  EntityTransaction transaction = entityManager.getTransaction();
  //开启事务;
  transaction.begin();
  Customer customer = new Customer();
  customer.setId("24");
  customer.setName("荣强");
  Orders order1 = new Orders();
  order1.setOrderno("1011");
  order1.setMoney(100f);
  Orders order2 = new Orders();
  order2.setOrderno("1012");
  order2.setMoney(1000f);
  //获取订单这个集合,并向该集合中 入订单;
  Set orders = customer.getOrders();
  orders.add(order1);
  orders.add(order2);
  //订单 好后,将这个集合存回客户表中;但是客户表中没有订单字段; 此订单表负责关系的维护;
  customer.setOrders(orders);
  order1.setCustomer(customer);
  order2.setCustomer(customer);
  //将客户对象进行持久化,记得要用persist而不是save;虽然两者内部代 相同,但是既然是持久化规范
  //为了更 符合命名 惯,jpa推荐使用persist方法;
  entityManager.persist(customer);
  //提交事务;只有涉及到增 改操作才需要开启事务;
  transaction.commit();
  //关闭实体管理器;
  entityManager.close();
  //关闭实体管理器工厂;
  factory.close();
 }

 public static void update() {
  EntityManagerFactory factory = Persistence
    .createEntityManagerFactory("itcast");
  EntityManager entityManager = factory.createEntityManager();
  EntityTransaction transaction = entityManager.getTransaction();
  transaction.begin();
  //提供的id类型要和字段属性的类型一致;
  Customer customer=entityManager.getReference(Customer.class, "24");
  customer.setName("荣强");
  Set orders=customer.getOrders();
  Orders order1=new Orders();
  order1.setOrderno("1014");
  order1.setMoney(1250f);
  orders.add(order1);
  order1.setCustomer(customer);
  //调用持久化api进行更新操作;
  entityManager.merge(customer);
  transaction.commit();
  entityManager.close();
  factory.close();
 }

}

具体情况请参看注释,这个应该比较详细;
EntityManager关闭时,使用延迟 载方法会抛出异常的;
当对应的是many时,默认为延迟 载;
比如OneToMany,ManyToMany;等,默认就是延迟 载;
mappedBy:是指定关系被维护端;类似于hibernate的inverse属性为true;
接下文

 
package cn.itcast.domain;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
@Entity
public class Orders {
 private String orderno;
 private Float money;
 private Customer customer;
 public Orders() {
  super();
  // TODO Auto-generated constructor stub
 }
 @Id
 public String getOrderno() {
  return orderno;
 }
 public void setOrderno(String orderno) {
  this.orderno = orderno;
 }
 @Column(name = "MONEY", nullable = false)
 public Float getMoney() {
  return money;
 }
 public void setMoney(Float money) {
  this.money = money;
 }
 
 @ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST,
   CascadeType.REFRESH },fetch=FetchType.EAGER,optional=false)
 @JoinColumn(name="customer_id")
 public Customer getCustomer() {
  return customer;
 }
 public void setCustomer(Customer customer) {
  this.customer = customer;
 }
}


对JPA的理解与回顾总结(一) 转发至微博
 
对JPA的理解与回顾总结(一) 转发至微博
阅读(9) | 评论(0)
|
       
对JPA的理解与回顾总结(一)

用微信  “扫一扫”

将文章分享到朋友圈。

 
对JPA的理解与回顾总结(一)

用易信  “扫一扫”

将文章分享到朋友圈。

 
喜欢 推荐 0人   转载
 
历史上的今天
最近读者
热度
在LOFTER的更多文章
关闭
玩LOFTER,免费冲印20张照片,人人有奖!          我要抢>
评论
\r\n
\r\n
\r\n
\r\n
\r\n\r\n
\r\n

--------android培训java培训期待与您交流------

\r\n
什么是JPA?
即Java Persistence API;java持久化api;
JPA是一套规范:类似于jdbc;
在没有jdbc之前,我们对数据库的操作是直接面向数据库厂商提供的api进行编程的
我们的程序和数据库api紧密的耦合在一起,而出现jdbc了,
我们可以直接面向jdbc编程,从而和个数据库厂商提供的api解耦;
类似的,在持久化产品中,有Hibernate,Toplink,等,我们使用这些产品进行持久化操作时,
自身程序和持久化产品严密耦合;基于这样的考虑。出现了JPA
这只是一个规范,而不是一个产品,因此使用的时候需要有实现类的支持;
类似于我们使用jdbc时要有相关数据库的驱动类;
这是面向接口编程的体现;
JPA:提供了三个技术
1 对象关系映射,ORM映射元数据;
', blogTag:'', blogUrl:'blog/static/21727620920134601028575', isPublished:1, istop:false, type:0, modifyTime:1400160336681, publishTime:1367770647793, permalink:'blog/static/21727620920134601028575', commentCount:0, mainCommentCount:0, recommendCount:0, bsrk:-100, publisherId:0, recomBlogHome:false, currentRecomBlog:false, attachmentsFileIds:[], vote:{}, groupInfo:{}, friendstatus:'none', followstatus:'unFollow', pubSucc:'', visitorProvince:'', visitorCity:'', visitorNewUser:false, postAddInfo:{}, mset:'000', mcon:'', srk:-100, remindgoodnightblog:false, isBlackVisitor:false, isShowYodaoAd:false, hostIntro:'JAVA软件工程师,有扎实的Java基础,熟悉JavaEE技术,对框架的底层原理熟悉,学习能力强。', hmcon:'0', selfRecomBlogCount:'0', lofter_single:'' }
{if x.visitorName==visitor.userName} ${x.visitorNickname|escape} {else} ${x.visitorNickname|escape} {/if}
{if x.moveFrom=='wap'}   {elseif x.moveFrom=='iphone'}   {elseif x.moveFrom=='android'}   {elseif x.moveFrom=='mobile'}   {/if} ${fn(x.visitorNickname,8)|escape}
{/if} {/list}
${a.selfIntro|escape}{if great260}${suplement}{/if}
 
{/if}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值