ORM(Object-Relational Mapping) 表示对象关系映射。在面向对象的软件开发中,通过ORM,就可以把对象映射到关系型数据库中。只要有一套程序能够做到建立对象与数据库的关联,操作对象就可以直接操作数据库数据,就可以说这套程序实现了ORM对象关系映射
简单的说:ORM就是建立实体类和数据库表之间的关系,从而达到操作实体类就相当于操作数据库表的目的。
当实现一个应用程序时(不使用O/R Mapping),我们可能会写特别多数据访问层的代码,从数据库保存数据、修改数据、删除数据,而这些代码都是重复的。而使用ORM则会大大减少重复性代码。对象关系映射(Object Relational Mapping,简称ORM),主要实现程序对象到关系数据库数据的映射。
Mybatis、Mybatis-Plus、Hibernate、Jpa
JPA的全称是Java Persistence API, 即Java 持久化API,是SUN公司推出的一套基于ORM的规范,内部是由一系列的接口和抽象类构成。
JPA通过JDK 5.0注解描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
1. 标准化
JPA 是 JCP 组织发布的 Java EE 标准之一,因此任何声称符合 JPA 标准的框架都遵循同样的架构,提供相同的访问API,这保证了基于JPA开发的企业应用能够经过少量的修改就能够在不同的JPA框架下运行。
2. 容器级特性的支持
JPA框架中支持大数据集、事务、并发等容器级事务,这使得 JPA 超越了简单持久化框架的局限,在企业应用发挥更大的作用。
3. 简单方便
JPA的主要目标之一就是提供更加简单的编程模型:在JPA框架下创建实体和创建Java 类一样简单,没有任何的约束和限制,只需要使用 javax.persistence.Entity进行注释,JPA的框架和接口也都非常简单,没有太多特别的规则和设计模式的要求,开发者可以很容易的掌握。JPA基于非侵入式原则设计,因此可以很容易的和其它框架或者容器集成
4. 查询能力
JPA的查询语言是面向对象而非面向数据库的,它以面向对象的自然语法构造查询语句,可以看成是Hibernate HQL的等价物。JPA定义了独特的JPQL(Java Persistence Query Language),JPQL是EJB QL的一种扩展,它是针对实体的一种查询语言,操作对象是实体,而不是关系数据库的表,而且能够支持批量更新和修改、JOIN、GROUP BY、HAVING 等通常只有 SQL 才能够提供的高级查询特性,甚至还能够支持子查询。
5. 高级特性
JPA 中能够支持面向对象的高级特性,如类之间的继承、多态和类之间的复杂关系,这样的支持能够让开发者最大限度的使用面向对象的模型设计企业应用,而不需要自行处理这些特性在关系数据库的持久化。
JPA规范本质上就是一种ORM规范,注意不是ORM框架——因为JPA并未提供ORM实现,它只是制订了一些规范,提供了一些编程的API接口,但具体实现则由服务厂商来提供实现。
1. 创建maven项目,添加依赖
4.0.0
com.lzx.spring-jpa-hibernate
spring-jpa-hibernate
1.0-SNAPSHOT
junit
junit
4.12
test
org.hibernate
hibernate-entitymanager
5.0.7.Final
org.hibernate
hibernate-c3p0
5.0.7.Final
log4j
log4j
1.2.17
mysql
mysql-connector-java
5.1.6
org.apache.maven.plugins
maven-compiler-plugin
3.2
1.8
utf-8
2. 创建数据库表和实体类,编写映射关系
package pojo;
import javax.persistence.*;
import java.util.Date;
/**
* * 所有的注解都是使用JPA的规范提供的注解,
* * 所以在导入注解包的时候,一定要导入javax.persistence下的
*/
@Entity //声明实体类
@Table(name = "spider") //对应数据库表名
public class Article {
@Id //声明当前属性为主键
@GeneratedValue(strategy = GenerationType.IDENTITY) //主键策略
@Column(name = "id") //声明实体类属性和表字段关系
private Integer id;
@Column(name = "title")
private String title;
@Column(name = "content")
private String content;
@Column(name = "create_time")
private Date createTime;
@Column(name = "user")
private String user;
@Column(name = "read_count")
private Integer readCount;
@Override
public String toString() {
return "Article{" +
"id=" + id +
", title='" + title + '\'' +
", content='" + content + '\'' +
", createTime=" + createTime +
", user='" + user + '\'' +
", readCount=" + readCount +
'}';
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Integer getReadCount() {
return readCount;
}
public void setReadCount(Integer readCount) {
this.readCount = readCount;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
}
3. 配置JPA的核心配置文件
在java工程的src路径下创建一个名为META-INF的文件夹,在此文件夹下创建一个名为persistence.xml的配置文件
org.hibernate.jpa.HibernatePersistenceProvider
4. 测试JPA操作
import org.junit.Test;
import pojo.Article;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import java.util.Date;
/**
* JPA测试
*/
public class JPADemo {
@Test
public void test1(){
/**
* 创建实体管理类工厂,借助Persistence的静态方法获取
* 其中传递的参数为持久化单元名称,需要jpa配置文件中指定
*/
EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
//创建实体管理类
EntityManager em = factory.createEntityManager();
//获取事务对象
EntityTransaction tx = em.getTransaction();
//开启事物
tx.begin();
//-------------------------- 执行任务
Article article = new Article();
article.setContent("dadsadasda156151......");
article.setCreateTime(new Date());
article.setReadCount(0);
article.setTitle("1");
article.setUser("lzx");
em.persist(article);
//-------------------------- 结束任务
//提交事务
tx.commit();
//释放资源
em.close();
factory.close();
}
}
通过annotation(注解)来映射hibernate实体的,基于annotation的hibernate主键标识为@Id, 其生成规则由@GeneratedValue设定的.这里的@id和@GeneratedValue都是JPA的标准用法。
JPA提供的四种标准用法为TABLE,SEQUENCE,IDENTITY,AUTO。
具体说明如下:
IDENTITY:主键由数据库自动生成(主要是自动增长型)
SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列。
AUTO:主键由程序控制
TABLE:使用一个特定的数据库表格来保存主键
Persistence对象
Persistence对象主要作用是用于获取EntityManagerFactory对象的 。通过调用该类的createEntityManagerFactory静态方法,根据配置文件中持久化单元名称创建EntityManagerFactory。
EntityManagerFactory
EntityManagerFactory 接口主要用来创建 EntityManager 实例
由于EntityManagerFactory 是一个线程安全的对象(即多个线程访问同一个EntityManagerFactory 对象不会有线程安全问题),并且EntityManagerFactory 的创建极其浪费资源,所以在使用JPA编程时,我们可以对EntityManagerFactory 的创建进行优化,只需要做到一个工程只存在一个EntityManagerFactory 即可
EntityManager
在 JPA 规范中, EntityManager是完成持久化操作的核心对象。实体类作为普通 java对象,只有在调用 EntityManager将其持久化后才会变成持久化对象。EntityManager对象在一组实体类与底层数据源之间进行 O/R 映射的管理。它可以用来管理和更新 Entity Bean, 根椐主键查找 Entity Bean, 还可以通过JPQL语句查询实体。
我们可以通过调用EntityManager的方法完成获取事务,以及持久化数据库的操作
方法说明:
getTransaction : 获取事务对象
persist : 保存操作
merge : 更新操作
remove : 删除操作
find/getReference : 根据id查询
EntityTransaction
在 JPA 规范中, EntityTransaction是完成事务操作的核心对象,对于EntityTransaction在我们的java代码中承接的功能比较简单
方法:
begin:开启事务
commit:提交事务
rollback:回滚事务
增:em.persist(Object o);
删:em.remove(Object o);
改:
Articlec1 = em.find(Article.class, 6);
c1.settitle("XXXXX");
em.clear(); //把c1对象从缓存中清除出去
em.merge(c1);
查(根据ID查):em.find(Article.class, 1); //实体类class和主键
复杂查询(SQL语句查询):
查询全部:
// 创建query对象
String jpql = "from Article";
Query query = em.createQuery(jpql);
// 查询并得到返回结果
List list = query.getResultList(); // 得到集合返回类型
分页查询:
//创建query对象
String jpql = "from Article";
Query query = em.createQuery(jpql);
//起始索引
query.setFirstResult(0);
//每页显示条数
query.setMaxResults(2);
//查询并得到返回结果
List list = query.getResultList(); //得到集合返回类型
条件查询:
//创建query对象
String jpql = "from Article where title like ? ";
Query query = em.createQuery(jpql);
//对占位符赋值,从1开始
query.setParameter(1, "大三%");
//查询并得到返回结果
Object object = query.getSingleResult(); //得到唯一的结果集对象
排序查询:
// 创建query对象
String jpql = "from Article order by create_time desc";
Query query = em.createQuery(jpql);
// 查询并得到返回结果
List list = query.getResultList(); // 得到集合返回类型
统计查询:
// 1.创建query对象
String jpql = "select count(id) from Article";
Query query = em.createQuery(jpql);
// 2.查询并得到返回结果
Object count = query.getSingleResult(); // 得到集合返回类型