ORM概述
ORM(Object-Relational Mapping) 表示对象关系映射。在面向对象的软件开发中,通过ORM,就可以把对象映射到关系型数据库中。只要有一套程序能够做到建立对象与数据库的关联,操作对象就可以直接操作数据库数据,就可以说这套程序实现了ORM对象关系映射
简单的说:ORM就是建立实体类和数据库表之间的关系,从而达到操作实体类就相当于操作数据库表的目的。
为什么使用ORM:当实现一个应用程序时(不使用O/R Mapping),我们可能会写特别多数据访问层的代码,从数据库保存数据、修改数据、删除数据,而这些代码都是重复的。而使用ORM则会大大减少重复性代码。对象关系映射(Object Relational Mapping,简称ORM),主要实现程序对象到关系数据库数据的映射。
常见的orm框架:Mybatis(ibatis)、Hibernate、Jpa
Jpa概述
概述:JPA的全称是Java Persistence API, 即Java 持久化API,是SUN公司推出的一套基于ORM的规范,内部是由一系列的接口和抽象类构成。JPA通过JDK 5.0注解描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
Jpa的优势:
Jpa与Hibernate的关系
JPA规范本质上就是一种ORM规范,注意不是ORM框架——因为JPA并未提供ORM实现,它只是制订了一些规范,提供了一些编程的API接口,但具体实现则由服务厂商来提供实现。
JPA和Hibernate的关系就像JDBC和JDBC驱动的关系,JPA是规范,Hibernate除了作为ORM框架之外,它也是一种JPA实现。
Jpa的快速入门
UTF-8
5.0.7.Final
junit
junit
4.12
test
org.hibernate
hibernate-entitymanager
${project.hibernate.version}
org.hibernate
hibernate-c3p0
${project.hibernate.version}
log4j
log4j
1.2.17
mysql
mysql-connector-java
5.1.6
org.hibernate.jpa.HibernatePersistenceProvider
@Entity//标明是一个实体对象
@Table(name = "cst_customer")//设置对应表名
public class Customer implements Serializable {
@Id//标明是主键
@Column(name = "cust_id")//设置属性与表中字段的映射
@GeneratedValue(strategy = GenerationType.IDENTITY)//设置主键生成策略
//使用指定Table表的形式生成主键,并指定部分值
// @GeneratedValue(generator = "pk_gen",strategy = GenerationType.TABLE)
//
// @TableGenerator(name = "pk_gen",
// name表示该表主键生成策略的名称,它被引用在@GeneratedValue中设置的“generator”值中
// table = "tb_genertor",
// table表示表生成策略所持久化的表名
// pkColumnName = "gen_name",
// 表示生成的表中的主键的名字
// pkColumnValue = "next_value",
// 表示生成表中主键的值的名称
// valueColumnName = "gen_value",
// 表示生成表中值得列的列名
// allocationSize = 1
// 表示每次主键值增加的大小
// )
//uuid作为主键的形式
//@GeneratedValue(generator = "gen_uuid")
//@GenericGenerator(name = "gen_uuid",strategy = "uuid")
//private String custId;
private Long custId;
@Column(name = "cust_name")
private String custName;
@Column(name = "cust_source")
private String custSource;
@Column(name = "cust_industry")
private String custIndustry;
@Column(name = "cust_level")
private String custLevel;
@Column(name = "cust_address")
private String custAddress;
@Column(name = "cust_phone")
private String custPhone;
// @Transient即配置忽略的属性
//getter and setter
public Long getCustId() {
return custId;
}
public void setCustId(long custId) {
this.custId = custId;
}
public String getCustName() {
return custName;
}
public void setCustName(String custName) {
this.custName = custName;
}
public String getCustSource() {
return custSource;
}
public void setCustSource(String custSource) {
this.custSource = custSource;
}
public String getCustIndustry() {
return custIndustry;
}
public void setCustIndustry(String custIndustry) {
this.custIndustry = custIndustry;
}
public String getCustLevel() {
return custLevel;
}
public void setCustLevel(String custLevel) {
this.custLevel = custLevel;
}
public String getCustAddress() {
return custAddress;
}
public void setCustAddress(String custAddress) {
this.custAddress = custAddress;
}
public String getCustPhone() {
return custPhone;
}
public void setCustPhone(String custPhone) {
this.custPhone = custPhone;
}
//toString
@Override
public String toString() {
return "Customer{" +
"custId=" + custId +
", custName='" + custName + '\'' +
", custSource='" + custSource + '\'' +
", custIndustry='" + custIndustry + '\'' +
", custLevel='" + custLevel + '\'' +
", custAddress='" + custAddress + '\'' +
", custPhone='" + custPhone + '\'' +
'}';
}
}
JPA中的API
persistence对象
Persistence对象主要作用是用于获取EntityManagerFactory对象的。通过调用该类的createEntityManagerFactory静态方法,根据配置文件中持久化单元名称创建EntityManagerFactory。
Persistence.createEntityManagerFactory("持久化单元名称");获取一个EntityManagerFactory对象
EntityManagerFactory接口
EntityManagerFactory主要用来创建EntityManager实例
factory.createEntityManager();
由于EntityManagerFactory是一个线程安全的对象(即多个线程访问同一个EntityManagerFactory对象不会有线程安全问题),并且EntityManagerFactory 的创建极其浪费资源,所以在使用JPA编程时,我们可以对EntityManagerFactory的创建进行优化,只需要做到一个工程只存在一个EntityManagerFactory 即可
EntityManager
在 JPA 规范中, EntityManager是完成持久化操作的核心对象。实体类作为普通 java对象,只有在调用 EntityManager将其持久化后才会变成持久化对象。EntityManager对象在一组实体类与底层数据源之间进行 O/R 映射的管理。它可以用来管理和更新 Entity Bean, 根椐主键查找 Entity Bean, 还可以通过JPQL语句查询实体。
我们可以通过调用EntityManager的方法完成获取事务,以及持久化数据库的操作
方法:
getTransaction():获取事务对象
persist():保存操作
merge():更新或保存(当对象不是po时,保存对象)
remove():删除操作
find()/getReference():根据id查询,find立即查询,getReference延迟查询
EntityTransction
事务操作的核心对象
begin():开启事务
commit():提交事务
rollback():回滚事务
抽取JPA的工具类
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
/**
* Created by Levi on 2018/11/17.
* Jpa的工具类,提供了加载factory方法,以及获取实体管理器
*/
public class JpaUtils {
private static EntityManagerFactory factory;
static {
//加载持久化单元,并获取实体管理器工厂
factory = Persistence.createEntityManagerFactory("myJpa");
}
public static EntityManager getEntityManager(){
return factory.createEntityManager();
}
}
JAP的简单CRUD
注意:更新与删除都需要先进行查询,即让对象被管理
import com.qin.domain.Customer;
import com.qin.utils.JpaUtils;
import org.junit.Test;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
/**
* Created by Levi on 2018/11/17.
*/
public class SpringDataCrudTest {
@Test
public void testSave() throws Exception{
//创建一个实体管理器工厂
EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
//从工厂中获取实体类管理器
EntityManager em = factory.createEntityManager();
//获取事务并开启
EntityTransaction tx = em.getTransaction();
tx.begin();
//创建实体
Customer customer = new Customer();
customer.setCustName("Levi");
customer.setCustIndustry("游戏");
//调用em的方法,保存
em.persist(customer);
//提交事务
tx.commit();
//释放资源
em.close();
factory.close();
}
/**
* 测试保存
*/
@Test
public void testAdd() throws Exception{
//获取事务管理器
EntityManager em = JpaUtils.getEntityManager();
EntityTransaction tx = em.getTransaction();
//开启事务
tx.begin();
//crud
//创建实体
Customer customer = new Customer();
customer.setCustName("Levi");
customer.setCustIndustry("游戏22222");
//调用em的方法,保存
em.persist(customer);
//提交事务
tx.commit();
//释放资源
em.close();
}
/**
* 测试修改
*/
@Test
public void testUpdate() throws Exception{
//获取事务管理器
EntityManager em = JpaUtils.getEntityManager();
EntityTransaction tx = em.getTransaction();
//开启事务
tx.begin();
//crud
//Customer customer = em.find(Customer.class, 1l);
//创建实体
Customer customer = new Customer();
customer.setCustName("Levi");
customer.setCustIndustry("游戏22222");
customer.setCustIndustry("change");
em.merge(customer);
//提交事务
tx.commit();
//释放资源
em.close();
}
/**
* 删除
*/
@Test
public void testDelete() throws Exception{
//获取事务管理器
EntityManager em = JpaUtils.getEntityManager();
EntityTransaction tx = em.getTransaction();
//开启事务
tx.begin();
//crud
Customer customer = em.find(Customer.class, 3l);
em.remove(customer);
//提交事务
tx.commit();
//释放资源
em.close();
}
/**
* 测试延迟记载
*/
@Test
public void testFindDelay() throws Exception{
//获取事务管理器
EntityManager em = JpaUtils.getEntityManager();
EntityTransaction tx = em.getTransaction();
//开启事务
tx.begin();
//crud
Customer reference = em.getReference(Customer.class, 1l);
System.out.println(reference);
//提交事务
tx.commit();
//释放资源
em.close();
}
}
JPA的复杂查询
import com.qin.utils.JpaUtils;
import org.junit.Test;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;
import java.util.List;
/**
* Created by Levi on 2018/11/17.
* 测试jpa中的方法
*/
public class JpaTest {
/**
* 查询所有
* sql的查询所有
* select * from 表
* jpql的查询所有
* from 实体类
* @throws Exception
*/
@Test
public void testSelectAll() throws Exception{
EntityManager em = JpaUtils.getEntityManager();
EntityTransaction tx = em.getTransaction();
//开启事务
tx.begin();
String jpql = "from Customer";
Query query = em.createQuery(jpql);
//查询并返回结果
List resultList = query.getResultList();
for (Object o : resultList) {
System.out.println(o);
}
//提交事务
tx.commit();
//释放资源
em.close();
}
/**
* 倒序查询
* sql的倒序
* select * from 表 order by 字段 desc
* jpql的倒序
* from 实体类 order by 属性 desc
* @throws Exception
*/
@Test
public void testDesc() throws Exception{
EntityManager em = JpaUtils.getEntityManager();
EntityTransaction tx = em.getTransaction();
//开启事务
tx.begin();
String jpql = "from Customer order by custId desc";
Query query = em.createQuery(jpql);
//查询并返回结果
List resultList = query.getResultList();
for (Object o : resultList) {
System.out.println(o);
}
//提交事务
tx.commit();
//释放资源
em.close();
}
/**
* 分页
* sql的分页
* select * from 表 limit ?,?
* jpql的分页
* from 实体类
* @throws Exception
*/
@Test
public void testLimit() throws Exception{
EntityManager em = JpaUtils.getEntityManager();
EntityTransaction tx = em.getTransaction();
//开启事务
tx.begin();
String jpql = "from Customer";
Query query = em.createQuery(jpql);
//设置开始索引
query.setFirstResult(0);
//设置分页条数
query.setMaxResults(1);
//查询并返回结果
List resultList = query.getResultList();
for (Object o : resultList) {
System.out.println(o);
}
//提交事务
tx.commit();
//释放资源
em.close();
}
/**
* 统计客户的总数
* sql的查询总数
* select count(字段) from 表
* jpql的查询所有
* select count(属性) from 实体类
* @throws Exception
*/
@Test
public void testCount() throws Exception{
EntityManager em = JpaUtils.getEntityManager();
EntityTransaction tx = em.getTransaction();
//开启事务
tx.begin();
String jpql = "select count(custId) from Customer";
Query query = em.createQuery(jpql);
//查询并返回结果
Object singleResult = query.getSingleResult();
System.out.println(singleResult);
//提交事务
tx.commit();
//释放资源
em.close();
}
/**
* 测试条件查询
* sql的条件查询
* select * from 表 where 字段 like ?
* jpql的条件查询
* from 实体类 where 属性 like ?
* @throws Exception
*/
@Test
public void testLikeSelect() throws Exception{
EntityManager em = JpaUtils.getEntityManager();
EntityTransaction tx = em.getTransaction();
//开启事务
tx.begin();
String jpql = "from Customer where custName like ? ";
String jpql1 = "from Customer where custName like :name ";
Query query = em.createQuery(jpql1);
//query.setParameter(1,"L%");
query.setParameter("name","L%");
//查询并返回结果
List resultList = query.getResultList();
for (Object o : resultList) {
System.out.println(o);
}
//提交事务
tx.commit();
//释放资源
em.close();
}
}