1.什么是JPA?(JPA规范本质上就是一种ORM规范。
全称Java Persistence API,可以通过注解或者XML描述【对象-关系表】之间的映射关系,并将实体对象持久化到数据库中。
为我们提供了:
1)ORM映射元数据:JPA支持XML和注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中,Object·/Relation Mapping 对象/关系数据库映射,它完成的是面向对象的编程语言到关系型数据库的映射,可以理解为ORM其实就是应用程序和数据库的桥梁;
如:@Entity、@Table、@Column、@Transient等注解。
2)JPA 的API:用来操作实体对象,执行CRUD操作,框架在后台替我们完成所有的事情,开发者从繁琐的JDBC和SQL代码中解脱出来。
如:entityManager.merge(T t);
3)JPQL查询语言:通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。
如:from Student s where s.name = ?
但是:
JPA仅仅是一种规范,也就是说JPA仅仅定义了一些接口,而接口是需要实现才能工作的。所以底层需要某种实现,而Hibernate就是实现了JPA接口的ORM框架。
也就是说:
JPA是一套ORM规范,Hibernate实现了JPA规范!
2.什么是spring data jpa?
spirng data jpa是spring提供的一套简化JPA开发的框架,按照约定好的【方法命名规则】写dao层接口,就可以在不写接口实现的情况下,实现对数据库的访问和操作。同时提供了很多除了CRUD之外的功能,如分页、排序、复杂查询等等。
Spring Data JPA 可以理解为 JPA 规范的再次封装抽象,底层还是使用了 Hibernate 的 JPA 技术实现。
3.JPQL?(JPA提供的是JPQL查询语言
jpql与SQL的区别就是SQL是面向对象关系数据库,他操作的是数据表和数据列,而jpql操作的对象是实体对象和实体属性 。jpql的查询语句设计非常简单。主要是由于Query接口来完成的,而我们的Query接口是由EntityManager创建出来的。
3.1)JPQL 查询基本格式
Query createNamedQuery(String name)创建查询的名称来创建一个命名查询,使用sql和jpql都可以
Query createNativeQuery(String SQLString)根据的原生的sql语句查询
QuerycreateQuery(String jpqlString)根据指定的JPQL语句创建一个查询
3.2)JPQL 执行基本格式
List getResultList()执行JPQL的select语句,并且返回的是list集合
Object getSingleResult()执行返回的那个结果的select语句
int executeupdate()表示执行批量的删除和更新
Query setFirstResult(int startPosition)设置查询结果从第几条记录开始
Query setMaxResults(int maxResult)表示设置查询最多返回几条语句
4.JPA入门小demo
4.1)创建Maven工程(jar
4.2)在src/main/java下创建cn.zf.entity.Customer类
package cd.zf.entity;
import javax.persistence.*;
// jpa的实体类
//配置实体类和数据库表的映射关系
@Entity
@Table(name="cst_customer")
public class Customer {
// 配置主键生成的策略(主键自增
@GeneratedValue(strategy = GenerationType.IDENTITY)
// 配置主键使用的字段
@Id
@Column(name="cust_id")
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;
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;
}
@Override
public String toString() {
return "Customer{" +
"custId=" + custId +
", custName='" + custName + '\'' +
", custSource='" + custSource + '\'' +
", custIndustry='" + custIndustry + '\'' +
", custLevel='" + custLevel + '\'' +
", custAddress='" + custAddress + '\'' +
", custPhone='" + custPhone + '\'' +
'}';
}
}
4.3)在src/main/resources下创建MATA-INF/persistence.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<!--配置持久化单元 name:持久化单元的名称-->
<!--transaction-type:事物的类型-->
<!--RESOURCE_LOCAL 单数据库的事务-->
<!--JTA: 分布式事务 跨数据库的事务-->
<persistence-unit name="myjpa" transaction-type="RESOURCE_LOCAL">
<properties>
<!--数据库连接属性配置-->
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="123456"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/springdatajpa9502"/>
<!--hibernate属性配置-->
<!--是否显示sql 语句 在控制台-->
<property name="hibernate.show_sql" value="true"/>
<!--是否格式化sql 语句-->
<property name="hibernate.format_sql" value="true"/>
<!--是否自动 创建数据库的表-->
<!--值:update 程序自动创建表 假如有这个表就不在创建-->
<!--create 程序自动创建表 有 先删 再创建-->
<!--none 不会创建表-->
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
4.4)在src/test/java下创建cn.zf.test.JpaCRUDTest类
package cn.zf.test;
import cd.zf.entity.Customer;
import org.junit.Before;
import org.junit.Test;
import javax.persistence.*;
import java.util.List;
public class JpaCRUDTest {
//将EntityManagerFactory对象提出来使用(没有将EntityManager对象提出来是因为执行的操作时多例的,所关闭的线程不是同一个
private EntityManagerFactory entityManagerFactory;
//@Before在方法执行之前执行该注解下的方法
@Before
//创建EntityManagerFactory对象
public void init(){
entityManagerFactory = Persistence.createEntityManagerFactory("myjpa");
}
/*
循环添加数据
*/
@Test
public void addCustomer(){
//通过EntityManagerFactory对象创建EntityManager对象
EntityManager entityManager = entityManagerFactory.createEntityManager();
//通过EntityManager对象获得事务
EntityTransaction transaction = entityManager.getTransaction();
//开启事务
transaction.begin();
//循环插入数据
for (int i = 0; i < 20; i++) {
Customer customer = new Customer();
customer.setCustIndustry("hh");
customer.setCustSource("爱格");
customer.setCustPhone("456789");
customer.setCustName("斗牛");
customer.setCustAddress("西班牙");
customer.setCustLevel("5");
entityManager.persist(customer);
}
//提交事务
transaction.commit();
//关闭资源(没有关闭entityManagerFactory是因为后面要使用
entityManager.close();
}
/*
删除数据
*/
@Test
public void delCustomer(){
//通过EntityManagerFactory创建EntityManager对象
EntityManager entityManager = entityManagerFactory.createEntityManager();
//通过EntityManager获得事务
EntityTransaction transaction = entityManager.getTransaction();
//开启事务
transaction.begin();
//使用EntityManager的find方法查询id为1的数据(先查询,后删除
Customer customer = entityManager.find(Customer.class, 1l);
//使用EntityManager的remove方法删除id为1的数据
entityManager.remove(customer);
//提交事务
transaction.commit();
//关闭资源
entityManager.close();
}
/*
更新数据
*/
@Test
public void updateCustomer(){
//通过EntityManagerFactory创建EntityManager对象
EntityManager entityManager = entityManagerFactory.createEntityManager();
//通过EntityManager获得事务
EntityTransaction transaction = entityManager.getTransaction();
//开启事务
transaction.begin();
//通过EntityManager的find方法查询id为4的数据
Customer customer = entityManager.find(Customer.class, 4l);
//重新为id=4的数据赋值
customer.setCustLevel("1");
customer.setCustAddress("法国");
customer.setCustPhone("456789");
customer.setCustIndustry("78");
customer.setCustSource("heart");
customer.setCustName("小镇");
//通过EntityManager的merge方法更新数据
entityManager.merge(customer);
//提交事务
transaction.commit();
//关闭资源
entityManager.close();
}
/*
根据id查询(使用EntityManager对象的getReference方法
*/
@Test
public void getByIdCustomer(){
//通过EntityManagerFactory获得EntityManager对象
EntityManager entityManager = entityManagerFactory.createEntityManager();
//getReference是延时加载,getReference方法执行后 访问对象的属性时才执行(查询id为4的数据
Customer reference = entityManager.getReference(Customer.class, 4l);
System.out.println("哈哈哈哈哈哈哈哈哈哈哈哈哈哈");
System.out.println(reference);
//关闭资源
entityManager.close();
}
/*
根据id查询(使用EntityManager对象的find方法
*/
@Test
public void findByIdCustomer(){
//通过EntityManagerFactory获得EntityManager对象
EntityManager entityManager = entityManagerFactory.createEntityManager();
//find方法是及时加载,find方法执行后SQL语句才执行
Customer customer = entityManager.find(Customer.class, 4l);
System.out.println("哈哈哈哈哈哈哈哈哈哈哈哈哈哈");
System.out.println(customer);
//关闭资源
entityManager.close();
}
//JPQL查询所有
@Test
public void findAll(){
//通过EntityManagerFactory工厂对象获得EntityManager对象
EntityManager entityManager = entityManagerFactory.createEntityManager();
//通过EntityManager对象的createQuery方法创建查询条件(使用entityManager对象创建一个query对象 基于jpql创建
Query query = entityManager.createQuery("from Customer");
//通过查询对象获得结果集
List<Customer> resultList = query.getResultList();
//遍历结果集
for (Customer customer : resultList) {
System.out.println(customer);
}
//关闭资源
entityManager.close();
}
//分页
@Test
public void findAllWithPage(){
//通过EntityManagerFactory工厂对象获得EntityManager对象
EntityManager entityManager = entityManagerFactory.createEntityManager();
//通过EntityManager对象的createQuery方法创建查询条件(使用entityManager对象创建一个query对象 基于jpql创建
Query query = entityManager.createQuery("from Customer");
//设置开始查询的下标(下标从0开始
query.setFirstResult(0);
//设置每页的条数
query.setMaxResults(5);
//通过query查询对象获得结果集
List<Customer> resultList = query.getResultList();
//遍历结果集
for (Customer customer : resultList) {
System.out.println(customer);
}
//关闭资源
entityManager.close();
}
//根据id查
@Test
public void findById(){
//通过EntityManagerFactory工厂对象创建EntityManager对象
EntityManager entityManager = entityManagerFactory.createEntityManager();
//通过EntityManager对象的createQuery方法创建查询条件(使用entityManager对象创建一个query对象 基于jpql创建
Query query = entityManager.createQuery("from Customer where custId=?");
//通过query查询对象设置查询条件(第一个参数:从第一个开始查 第二个参数:查询id为3的数据
query.setParameter(1,3l);
//通过query的getSingleResult方法获得数据(getSingleResult查询结果为一个时使用
Customer singleResult = (Customer) query.getSingleResult();
System.out.println(singleResult);
//关闭资源
entityManager.close();
}
//根据name查
@Test
public void findByName(){
//通过EntityManagerFactory工厂对象创建EntityManager对象
EntityManager entityManager = entityManagerFactory.createEntityManager();
//通过EntityManager对象的createQuery方法创建查询条件(使用entityManager对象创建一个query对象 基于jpql创建
Query query = entityManager.createQuery("from Customer where custName like ?");
//通过query查询对象设置查询条件(第一个参数:从第一个开始查 第二个参数:查询name中含有1的数据
query.setParameter(1,"%1%");
//执行查询,通过query的getResultList方法获得数据(getResultList查询结果为集合时使用
List<Customer> resultList = query.getResultList();
//遍历集合
for (Customer customer : resultList) {
System.out.println(customer);
}
//关闭资源
entityManager.close();
}
//排序
@Test
public void findAllWithOrder(){
//通过EntityManagerFactory工厂对象创建EntityManager对象
EntityManager entityManager = entityManagerFactory.createEntityManager();
//通过EntityManager对象的createQuery方法创建查询条件(使用entityManager对象创建一个query对象 基于jpql创建
//asc升序 desc降序
Query query = entityManager.createQuery("from Customer order by custId asc");
//执行查询,通过query的getResultList方法获得数据(getResultList查询结果为集合时使用
List<Customer> resultList = query.getResultList();
//遍历集合
for (Customer customer : resultList) {
System.out.println(customer);
}
//关闭资源
entityManager.close();
}
//聚合函数
@Test
public void findCount(){
//通过EntityManagerFactory工厂对象创建EntityManager对象
EntityManager entityManager = entityManagerFactory.createEntityManager();
//通过EntityManager对象的createQuery方法创建查询条件(使用entityManager对象创建一个query对象 基于jpql创建
Query query = entityManager.createQuery("select count(custId) from Customer");
//通过query的getSingleResult方法获得数据(getSingleResult查询结果为一个时使用
Long count = (Long) query.getSingleResult();
System.out.println(count);
//关闭资源
entityManager.close();
}
}
注:EntityManager(实体是与数据库映射的,但是没有起到持久化的作用,只有用上EntityManager的实体进行操作的时候才会有持久化能力
over~