JPA持久化API,针对数据库的增删改查(一):对象/关系数据库映射;JPA映射规则;JPA规范;开发简单实例

Java持久化API (JPA)

作用:针对于数据库的增删改查操作/与SSM框架的MyBatis比较类似

在J2EE时代,J2EE规范制定了实体Bean(Entity Bean)规范来解决应用程序的持久化问题,
	但由于Entity Bean设计的过于复杂。而且功能上也没有特别值得称道的地方,
	因此Entity Bean一直都是EJB规范中饱受诟病的部分,随后,大量开源ORM框架(如:Hibernate)出现,
	这些框架不仅简单,易用,而且也可以面向对象的方式来操作关系数据库,并提供强大的数据查询功能。
	慢慢的,这些ORM框架不断地蚕食原本属于Entity Bean的份额,因为使用Entity Bean的开发者越来越少

当Sun公司制定Java EE 5规范时,Sun公司彻底抛弃了原来的Entity Bean(也有人说Entity就是原来Entity Bean的升级)
	而是推出了新的JPA规范。Sun公司的JPA以Entity为核心,他将实体映射到底层数据库,
	然后通过在应用程序中使用的JPA的EntityManager来操作Entity,而JPA实现则会将这种操作转换为对底层数据表的操作

从起因上来看,Sun公司制定JPA规范肯定是受到众多ORM框架的影响,但JPA规范并不是任何具体的ORM框架,
	他只是一种规范,可以把它理解成一个ORM规范,因此当在程序中使用JPA进行持久化时,
	底层一定需要具体的ORM框架作为实现。通常来说,应用服务器会负责为JPA规范提供ORM实现;
	如果开发者希望在JavaSE应用程序中使用JPA,这也是允许的,只要开发者资行为JPA选择合适的ORM实现即可
1.实体简介
EJB3的实体(Entity)是充分吸收ORM(Object/Relation Mapping)思想之后的产物,
	他并是不由EJB2的Entity EJB发展而来,而是更像由Hibernate,TopLink等ORM框架发展而来,因此介绍实体之前,先向读者介绍ORM的相关知识
1.1对象/关系数据库映射
ORM的全称是Object/Relation Mapping,对象/关系数据库映射。ORM可理解成一种规范,他概述了这类框架的基本特征:
	完成面向对象的编程语言到关系数据库的映射。当ORM框架完成映射后,即可利用面向对象程序设计语言的简单易用性,
	又可利用关系数据库的技术优势,因此,我们可把ORM框架当成应用程序和数据库的桥梁
	
当我们使用一种面向对象的程序设计语言来进行应用开发时,从项目开始起一直采用的是面向对象分析,
	面向对象设计面向对象编程,但到了持久层数据库访问时,又必须重返关系数据库的访问方式,
	这是一种非常糟糕的感觉,于是我们需要一种工具,它可以把关系数据库包装成面向对象的模型,这个工具就是ORM框架
	
ORM框架是面向对象程序设计语言与关系数据库发展不同时的中间解决方案。笔者认为,随着面向对象数据库的发展,
	理论逐步完善,最终会取代关系数据库。只是这个过程不可一蹴而就,ORM框架在此期间内会蓬勃发展。
	但随着面向对象数据库的出现,ORM工具会自动消亡
	
对实现所有流行的编程语言而言,面向对象的程序设计语言代表了目前程序设计语言的主流和趋势,具备非常多的优势。比如:
	1.面向对象的建模,操作
	2.多态,继承
	3.摒弃难以理解的过程
	4.简单易用,易理解
	
但数据库的发展并未与程序设计语言同步,而且关系数据库系统的某些优势也是面向对象语言目前无法比拟的,比如:
	1.大量数据库查找,排序
	2.集合数据连接操作,映射
	3.数据库访问的并发,事务
	4.数据库的约束,隔离
	
面对这种面向对象语言的关系数据库系统并存的局面,采用ORM就变成一种必然。只要我们还是采用面向对象程序设计语言,
	底层依然采用关系数据库,中间就少不了ORM工具。当采用ORM框架之后,应用程序不再直接访问底层数据库,
	而是以面向对象的方式来操作实体(Hibernate框架就将实体称为持久化对象),
	例如创建,修改,删除等,ORM框架则将这些面向对象的操作转换成底层的SQL操作
	
JPA实现的作用就是;把对实体的操作,转换成对数据库的操作。这样应用程序就能以面向对象的方式操作实体,
	而JPA实现则负责转换成对应SQL(结构化查询语言)操作
	
JPA规范本质上就是一种ORM规范,注意:不是ORM框架——因为JPA并未提供ORM实现,他只是制定了一些规范,
	提供了一些编程的API接口,但具体实现则由应用服务器厂商来提供实现,JBoss应用服务器底层就以Hibernate作为JPA实现

既然JPA作为一种规范——也就是说,JPA规范中提供的只是一些接口,显然接口不能直接拿来使用,
	虽然应用程序可以面向接口编程,但JPA底层一定需要某种JPA实现,否则JPA依然无法使用
	
从笔者的视角来看,Sun之所以提出JPA规范,其目的是以官方的身份来统一各种ORM框架的规范,
	包括著名的Hibernate,TopLink等。不过JPA规范给开发者带来了福音——开发者面向JPA规范的接口,
	但底层的的JPA实现可以任意切换;觉得Hibernate好的,可以选择Hibernate JPA实现;觉得TopLink好的,
	可以选择TopLink JPA实现……这样开发者可以避免为使用Hibernate学习一套ORM框架,为使用TopLink又要在学习一套ORM框架
	
则只需要考虑 
	1.对ORM的增删改查操作 
	2.和ORM对数据库种类的配置(地址 驱动 用户 密码)数据库变更只需要修改数据库配置即可
1.2.JPA映射规则
JPA提供了实体与数据表之间的映射关系,通过这种映射关系的过度,我们可以很方便的通过对实体的操作来实现对数据表的操作,JPA规范大致上遵循以下几条映射准则。

1.数据表映射实体类:
	实体类被映射到一个数据表。当我们使用这个实体类来创建实例,修改属性,删除实例时,
		系统自动会转换为对这个表进行CRUD操作。受JPA管理的实体类对应一个数据表,只要对这个实体类进行操作,
		系统就可以转换成对对应数据表的操作
		
2.数据表的行映射实体对象(即实例):
	实体类会产生很多实体,每个实体就对应数据表中的一行记录。当我们在应用程序中修改某个实体对象时,
		JPA将会转换成对指定数据表中特定行的操作。每个实体对象对应数据表的一行记录
	eg:Dept d1 = new Dept();d1 就相当于一条记录表示一行

3.数据表的列(字段)映射实体属性;
	当我们在应用中修改某个实体对象的指定属性时(实体对象映射到数据行),JPA将会转换成对数据表中指定数据行,
		指定数据列的修改。数据表的列被映射到对象属性
	eg:d1.getDeptno();
   	    d2.getDeptna();getDeptno和getDeptna 就是实体属性

基于这种基本的映射方式,JPAde规范就完成对对象模型和关系模型之间的相互映射。由此可见,在JPA规范中,实体只是一种中间媒介,应用程序只需要操作实体对象,ORM框架则负责将这种操作转换为对底层数据的操作——这种转换对开发者透明,无需开发者关心,从而将开发者从关系数据库模型中释放出来,使得开发者能以面向对象的思维操作关系数据库
1.3.JPA规范
虽然JPA规范与EJB3规范一同出现。而且在很多场合中JPA被作为EJB2中Entity Bean的替代产品,
	但实际上JPA规范并不属于EJB3规范,它是一套完全独立的规范,JPA不仅可以在基于EJB的JavaEE应用程序中使用,
	而且完全可以在普通JavaSE应用程序中使用
	
在JPA操作过程中,最常用的3中组件如下:
1.实体
	实体其实就是一个普通的POJO,只是为了它增加了orm.xml映射文件或Annotation(注解),
		通过使用这种orm.xml映射文件或Annotation即可建立实体和底层数据表之间的对应关系
	不再需要继承某个类
	
2.实体管理器EntityManager 持久化,进行永久化保存 实体向数据库保存
	实体只是和底层数据表具有映射关系的POJO,它本身并没有任何持久化能力,
		只有使用EntityManager来对实体进行操作时,JPA规范才可将这种操作转换为对底层数据库的操作。
		从这个意义上来看,JPA规范的EntityManager 类似于 Hibernate框架的Session
	与Hibernate中Session类似的是,当程序需要使用JPA添加,删除,更新实体时,
		应用程序都需要使用EntityManager这个接口完成。除此之外,如果应用程序需要检索实体,则通过EntityManager根据JPQL创建Query对象来实现
		
3.JPQL查询
	类似于HIbernate提供HQL查询语言,这种查询语言非常简单,易用,可以非常方便的检索已保存的实体。
		JPA提供了一个Query接口来执行查询,EntityManager根据已有的JPQL来创建Query对象,然后Query对象来执行查询
2.开发实体
JPA彻底简化了Java持久化解决方案,JPA管理的实体类不再需要继承某个基类,或实现某个接口,
	实体类就是一个普通的POJO类,只是为这个POJO类增加了一些额外的Annotation即可,
	这些Annotation定义了POJO类和底层数据表之间的映射关系.

eg:新建JPALession项目
1.导入jar包

antlr-2.7.7.jar
dom4j-1.6.1.jar
hibernate-commons-annotations-5.0.1.Final.jar
hibernate-core-5.0.6.Final.jar
hibernate-entitymanager-5.0.6.Final.jar
hibernate-jpa-2.1-api-1.0.0.Final.jar
jandex-2.0.0.Final.jar
javassist-3.18.1-GA.jar
jboss-logging-3.3.0.Final.jar
jta-1.1.jar
mysql-connector-java-5.1.7-bin.jar

2.新建Emp类并进行改造

//注解 作用:注解下面的对象赋予另外的功能
@Entity//javax//声明成JPA实体
@Table(name = "emp")//javax//直接对应一张表(映射成emp 实际表名 保持一致)
public class Emp {
	
	@Id//主键
	//@GeneratedValue(strategy = GenerationType.IDENTITY)//自增
	private int empno;
	@Column(name = "ename",length = 255,nullable = false)//字段,nullable是否为空
	private String ename;
	@Column(name = "job",length = 255,nullable = true)//字段
	private String job;
	
	@Transient//不向数据库保存 不进行持久化 普通属性
	private boolean flag;
	
	@Temporal(TemporalType.DATE)//日期类型
	private Date hiredate;
	
	public Emp() {
		
	}
	
	public Date getHiredate() {
		return hiredate;
	}

	public void setHiredate(Date hiredate) {
		this.hiredate = hiredate;
	}
	
	public boolean isFlag() {
		return flag;
	}

	public void setFlag(boolean flag) {
		this.flag = flag;
	}
	
	public int getEmpno() {
		return empno;
	}
	public void setEmpno(int empno) {
		this.empno = empno;
	}
	public String getEname() {
		return ename;
	}
	public void setEname(String ename) {
		this.ename = ename;
	}
	public String getJob() {
		return job;
	}
	public void setJob(String job) {
		this.job = job;
	}
}
可以看出实体类其实非常简单,他只是为传统的POJO增加Annotation即可
POJO+Annotation=Entity

3.在进行实际的数据库访问之前JPA需要使用persistence.xml来管理数据库的连接,连接池信息,JPA将这些信息称为持久化单元,

也就是说,persistence.xml文件用于管理JPA的持久化单元信息

JPA本身只是一种规范,他必须依赖于一种具体的实现才可完成实际的持久化操作。正当应用服务器中使用JPA时,
	JPA实现则依赖于底层应用服务器的实现;当在JavaSE环境下使用JPA时,开发者则可以自由的使用合适的JPA实现
	
不同的JPA实现主要通过persistence.xml文件的配置信息来区分,该文件放在类路径下的META-INF文件夹下,官方提供进行修改:
<!--
  ~ Hibernate, Relational Persistence for Idiomatic Java
  ~
  ~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
  ~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  -->
<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">
	<!-- 持久化单元数据类型 RESOURCE_LOCAL局部事务 JTA全局事务-->
	<persistence-unit name = "emp" transaction-type = "RESOURCE_LOCAL">
		
		<description>
            Persistence unit for the Envers tutorial of the Hibernate Getting Started Guide
        </description>
		
		<!-- 提供者 -->
		<provider>org.hibernate.ejb.HibernatePersistence</provider>
		
		<!-- 指定类 -->
		<class>com.demo.entity.Emp</class>
		
		<properties>
			<property name = "hibernate.connection.driver_class" value ="com.mysql.jdbc.Driver" />
			<property name = "hibernate.connection.url" value ="jdbc:mysql://localhost:3306/hp_memcached" />
			<property name = "hibernate.connection.username" value ="root" />
			<property name = "hibernate.connection.password" value ="zzj6660534" />
				
			<!-- 数据库方言 翻译语言 -->
			<property name = "hibernate.dialect" value ="org.hibernate.dialect.MySQLInnoDBDialect" />
			
			<!-- 显示真正执行的SQL语句 -->
			<property name = "hibernate.show_sql" value ="true" />
			<!-- 更新的时候重新创建一张表 -->
			<property name = "hibernate.hbm2ddl.auto" value ="update" />
			<!-- hbm2ddl hbm映射到ddl -->
		</properties>	
		
	</persistence-unit>
	
</persistence>

4.测试类

public class MainTest {
	
	//创建与数据库连接工厂 输入刚刚创建的持久化单元emp
	private static final EntityManagerFactory emf = Persistence.createEntityManagerFactory("emp");
	
	
	@Test
	public void test1() {
		//用于对数据的简单保存
		
		//相当于Session对象 实体管理器
		final EntityManager em = emf.createEntityManager();
		
		//创建一个普通的POJO对象 并赋值
		try {
			Emp emp = new Emp();
			emp.setEmpno(4);
			emp.setEname("d1");
			emp.setJob("l1");
			//数据库里保存信息
			//开启事务
			em.getTransaction().begin();
			//保存事务
			em.persist(emp);//相当于sql的Insert语句
			
			em.getTransaction().commit();
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			em.getTransaction().rollback();
		}
		
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值