springDataJPA笔记
第一 orm思想
主要目的:操作实体类就相当于操作数据库表
建立两个映射关系:
实体类和表的映射关系
实体类中属性和表中字段的映射关系
不再重点关注:sql语句
实现了ORM思想的框架:mybatis,hibernate
第二 hibernate框架介绍
Hibernate是一个开放源代码的对象关系映射框架,
它对JDBC进行了非常轻量级的对象封装,
它将POJO与数据库表建立映射关系,是一个全自动的orm框架
第三 JPA规范
jpa规范,实现jpa规范,内部是由接口和抽象类组成
第四 jpa的基本操作
案例:是客户的相关操作(增删改查)
客户:就是一家公司
客户表:
jpa操作的操作步骤
1.加载配置文件创建实体管理器工厂
Persisitence:静态方法(根据持久化单元名称创建实体管理器工厂)
createEntityMnagerFactory(持久化单元名称)
作用:创建实体管理器工厂
2.根据实体管理器工厂,创建实体管理器
EntityManagerFactory :获取EntityManager对象
方法:createEntityManager
* 内部维护的很多的内容
内部维护了数据库信息,
维护了缓存信息
维护了所有的实体管理器对象
再创建EntityManagerFactory的过程中会根据配置创建数据库表
* EntityManagerFactory的创建过程比较浪费资源
特点:线程安全的对象
多个线程访问同一个EntityManagerFactory不会有线程安全问题
* 如何解决EntityManagerFactory的创建过程浪费资源(耗时)的问题?
思路:创建一个公共的EntityManagerFactory的对象
* 静态代码块的形式创建EntityManagerFactory
3.创建事务对象,开启事务
EntityManager对象:实体类管理器
beginTransaction : 创建事务对象
presist : 保存
merge : 更新
remove : 删除
find/getRefrence : 根据id查询
Transaction 对象 : 事务
begin:开启事务
commit:提交事务
rollback:回滚
4.增删改查操作
5.提交事务
6.释放资源
i.搭建环境的过程
1.创建maven工程导入坐标
2.需要配置jpa的核心配置文件
*位置:配置到类路径下的一个叫做 META-INF 的文件夹下
*命名:persistence.xml
3.编写客户的实体类
4.配置实体类和表,类中属性和表中字段的映射关系
5.保存客户到数据库中
ii.完成基本CRUD案例
persist : 保存
merge : 更新
remove : 删除
find/getRefrence : 根据id查询
iii.jpql查询
sql:查询的是表和表中的字段
jpql:查询的是实体类和类中的属性
* jpql和sql语句的语法相似
1.查询全部
2.分页查询
3.统计查询
4.条件查询
5.排序
以上是课件的内容:
总结:
使用jpa的步骤,但是不适用springboot注解的形式,那么
第一步就需要创建xml文件进行配置:
具体代码:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<!--需要配置persistence-unit-->
<!--持久化单元-->
<!--name:持久化单元名称
transaction-type:事务管理的方式
JTA:分布式事务管理
RESOURCE_LOCAL:本体事务管理
-->
<persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL">
<!--jpa的实现方式-->
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<!--开始配置基本属性-->
<!--需要数据库信息
用户名:javax.persistence.jdbc.user
密码:javax.persistence.jdbc.password
驱动:javax.persistence.jdbc.driver
数据库地址:javax.persistence.jdbc.url
-->
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="root"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql:///springdatajpa"/>
<!--可选的配置:为了配置jpa实现方的配置信息
hibernate:
显示sqlhibernate.show_sql
自动创建数据库表hibernate.hbm2ddl.auto
create:程序运行时创建数据库表(如果有表,先删除表再创建)
update:c程序运行时创建表(如果有表不会创建表)
none:不会创建表
-->
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
以上的代码进行了详细的注解,就不需要解释了。
第二步:需要创建实体类,根据实体类进行创建数据库表结构:
package cn.itcast.domain;
/**
* @Created by Intellij IDEA.
* @author: 陈亚萌
* @Date: 2020/1/18
*/
import javax.persistence.*;
/**
* 客户实体类:
* 配置映射关系:
* 1. 实体类和表的映射关系
* 2. 实体类中属性和表中字段的映射关系
* @Entity声明实体列
* @Table:声明实体类和表的映射关系 name 属性是配置数据库的名称
* @Id:声明主键
* strategy
* @GeneratedValue(strategy = GenerationType.IDENTITY) 表示主键生成策略是自增 mysql
* * 底层数据库必须支持自动增长,底层数据库支持的自动增长方式,对id递增
* GenerationType.SEQUENCE: 序列 Oracle
* 底层数据库必须支持序列
* GenerationType.TABLE :
* jpa提供的一种机制,通过数据库表的形式帮我们完成主键自增
* GenerationType.AUTO:
* 由程序自动帮我们选择主键生成策略
* @Column(name = 'cust_id')配置属性和字端的映射关系 name代表数据库表中的字段名
*/
@Entity
@Table(name = "cst_customer")
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "cust_id")
private Long custId;
@Column(name = "cust_name")
private String custName;
@Column(name = "cust_source")
private String custSource;
@Column(name = "cust_level")
private String custLevel;
@Column(name = "cust_industry")
private String custIndustry;
@Column(name = "cust_phone")
private String custPhone;
@Column(name = "cust_address")
private String custAddress;
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 getCustLevel() {
return custLevel;
}
public void setCustLevel(String custLevel) {
this.custLevel = custLevel;
}
public String getCustIndustry() {
return custIndustry;
}
public void setCustIndustry(String custIndustry) {
this.custIndustry = custIndustry;
}
public String getCustPhone() {
return custPhone;
}
public void setCustPhone(String custPhone) {
this.custPhone = custPhone;
}
public String getCustAddress() {
return custAddress;
}
public void setCustAddress(String custAddress) {
this.custAddress = custAddress;
}
@Override
public String toString() {
return "Customer{" +
"custId=" + custId +
", custName='" + custName + '\'' +
", custSource='" + custSource + '\'' +
", custLevel='" + custLevel + '\'' +
", custIndustry='" + custIndustry + '\'' +
", custPhone='" + custPhone + '\'' +
", custAddress='" + custAddress + '\'' +
'}';
}
}
以上也有对每段代码的详细注解,也可以不用手写setget方法,直接使用lombok进行@Data注解即可。
第三步,进行测试:
package cn.itcast;
import cn.itcast.domain.Customer;
import cn.itcast.utils.JpaUtils;
import org.junit.Test;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
/**
* @Created by Intellij IDEA.
* @author: 陈亚萌
* @Date: 2020/1/18
*/
public class test {
/*
* 测试jpa的保存
* 案例 保存一个客户到数据库
* jpa操作步骤:
* 1. 加载配置文件创建工厂(实体管理工厂)对象
* 2. 通过实体管理类获取实体管理器
* 3. 获取事务对象,开启事务
* 4. 完成增删改查操作
* 5. 提交事务(回滚事务)
* 6. 释放资源
* */
@Test
public void testSave(){
/* //1. 加载配置文件创建工厂(实体管理工厂)对象
EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");
//2. 通过实体管理类获取实体管理器
EntityManager em = factory.createEntityManager();*/
EntityManager em= JpaUtils.getEntityManager();
// 3 . 获取事务对象,开启事务
EntityTransaction tx = em.getTransaction();
//开启事务
tx.begin();
//4。完成增删改查操作
Customer customer=new Customer();
customer.setCustName("chenyameng");
customer.setCustIndustry("IT");
//保存
em.persist(customer);
// 5. 提交事务(回滚事务)
tx.commit();
// 6. 释放资源
em.close();
//factory.close();
}
/**
* 根据id查询用户
*/
@Test
public void testFind(){
//1, 通过工具类获取entityManger
EntityManager em = JpaUtils.getEntityManager();
//2,开启事务
EntityTransaction tx=em.getTransaction();
tx.begin();
//3, 增删改查
/**
* find:根据id查询数据
* class:字节码,查询数据的结果需要包装的实体类类型的字节码
* id:查询的主键的取值
*
* 使用find方法查询
* 1. 查询的对象就是当前客户对象本身
* 2. 调用find方法的时候,就会发送sql请求
*/
Customer customer = em.find(Customer.class, 1l);
System.out.println(customer.toString());
//4,提交事务,
tx.commit();
// 释放资源
em.close();
}
/**
* 根据id查询用户
*/
@Test
public void testReference(){
//1, 通过工具类获取entityManger
EntityManager em = JpaUtils.getEntityManager();
//2,开启事务
EntityTransaction tx=em.getTransaction();
tx.begin();
//3, 增删改查
/**
* getReference:根据id查询数据
* class:字节码,查询数据的结果需要包装的实体类类型的字节码
* id:查询的主键的取值
*
* 特点:
* 获取的对象是动态代理的对象
* 调用reference方法不会立即发送sql语句查询数据库
* * 当调用查询结果的时候,才会发送sql语句,什么时候用,什么时候发送sql语句
* 延迟加载,特点:
* 得到的是动态代理对象
* 什么时候用什么时候查
*
*/
Customer customer = em.getReference(Customer.class, 1l);
System.out.println(customer.toString());
//4,提交事务,
tx.commit();
// 释放资源
em.close();
}
/**
* s删除客户
*/
@Test
public void testRemove(){
//1, 通过工具类获取entityManger
EntityManager em = JpaUtils.getEntityManager();
//2,开启事务
EntityTransaction tx=em.getTransaction();
tx.begin();
//3, 增删改查
//3.1 根据id查询客户
final Customer customer = em.find(Customer.class, 1L);
// 3.2 调用remove 方法删除操作
em.remove(customer);
//4,提交事务,
tx.commit();
// 释放资源
em.close();
}
/**
* 更新客户
*/
@Test
public void testUpdate(){
//1, 通过工具类获取entityManger
EntityManager em = JpaUtils.getEntityManager();
//2,开启事务
EntityTransaction tx=em.getTransaction();
tx.begin();
//3, 增删改查
//3.1 客户的更新
final Customer customer = em.find(Customer.class, 2L);
customer.setCustIndustry("it教育");
// 3.2 调用update
em.merge(customer);
//4,提交事务,
tx.commit();
// 释放资源
em.close();
}
}
以上代码也有详细的解释。
jqpl语言的简单讲解:
package cn.itcast;
import cn.itcast.utils.JpaUtils;
import org.junit.Test;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;
import java.util.List;
/**
* @Created by Intellij IDEA.
* @author: 陈亚萌
* @Date: 2020/1/18
* jpql测试
*/
public class JpqlTest {
/**
* 查询全部:
* jqpl:from cn.itcast.domain.Customer
* sql:select * from cst_customer
*/
@Test
public void testFindAll(){
//1, 获取Entitymanager对象
EntityManager em=JpaUtils.getEntityManager();
//2 开启事务
final EntityTransaction transaction = em.getTransaction();
transaction.begin();
//3 查询全部
String jpql="from Customer";
//创建Query对象,query对象才是执行spql对象
Query query = em.createQuery(jpql);
//发送查询,并封装结果集
List list = query.getResultList();
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// 4.提交事务
transaction.commit();
// 释放资源
em.close();
}
/**
* 排序查询:
* jqpl:from cn.itcast.domain.Customer order by custId
* sql:select * from cst_customer order by cust_id DESC
* 进行jpql查询:
* 1. 创建query对象
* 2. 对参数进行复制
* 3. 查询并返回结果
*/
@Test
public void testOrder(){
//1, 获取Entitymanager对象
EntityManager em=JpaUtils.getEntityManager();
//2 开启事务
final EntityTransaction transaction = em.getTransaction();
transaction.begin();
//3 查询全部
String jpql="from cn.itcast.domain.Customer order by custId DESC";
//创建Query对象,query对象才是执行spql对象
Query query = em.createQuery(jpql);
//发送查询,并封装结果集
List list = query.getResultList();
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// 4.提交事务
transaction.commit();
// 释放资源
em.close();
}
/**
* 计数查询:
*
* 使用jpql查询,统计客户的总数:
* sql:select count(cus_id) from customer
* jpql:select count(custId) from Customer
*/
@Test
public void testCount(){
//1, 获取Entitymanager对象
EntityManager em=JpaUtils.getEntityManager();
//2 开启事务
final EntityTransaction transaction = em.getTransaction();
transaction.begin();
//3 查询全部
//1 根据jpql语句创建query对象
String jpql="select count(custId) from Customer";
//2 参数赋值
// 3 发送查询,并封装结果
Query query = em.createQuery(jpql);
//发送查询,并封装结果集
/**
* getResultList:直接将查询结果封装成为list集合
* getSingleResult:得到唯一的结果集
*/
final Object singleResult = query.getSingleResult();
System.out.println(singleResult);
// 4.提交事务
transaction.commit();
// 释放资源
em.close();
}
/**
* 分页查询:
* sql:select * from cst_customer limit ?,?
* jpql:from Customer
*/
@Test
public void testPage(){
//1, 获取Entitymanager对象
EntityManager em=JpaUtils.getEntityManager();
//2 开启事务
final EntityTransaction transaction = em.getTransaction();
transaction.begin();
//3 查询全部
//1 根据jpql语句创建query对象
String jpql="from Customer";
// 3 发送查询,并封装结果
Query query = em.createQuery(jpql);
//发送查询,并封装结果集
/**
* getResultList:直接将查询结果封装成为list集合
* getSingleResult:得到唯一的结果集
*/
final List resultList = query.getResultList();
for (Object o : resultList) {
System.out.println(o);
}
//2 参数赋值
//起始索引,
query.setFirstResult(0);
//每页查询的条数
query.setMaxResults(2);
// 4.提交事务
transaction.commit();
// 释放资源
em.close();
}
/**
* 条件查询:
* 查询客户名称以“传值”开头的
* sql: select * from cst_customer where cust_name like '搜索%'
* jpql: from Customer where custName like ?
*/
@Test
public void testCondition(){
//1, 获取Entitymanager对象
EntityManager em=JpaUtils.getEntityManager();
//2 开启事务
final EntityTransaction transaction = em.getTransaction();
transaction.begin();
//3 查询全部
//1 根据jpql语句创建query对象
String jpql="from Customer where custName like ?";
// 3 发送查询,并封装结果
Query query = em.createQuery(jpql);
//发送查询,并封装结果集
/**
* getResultList:直接将查询结果封装成为list集合
* getSingleResult:得到唯一的结果集
*/
//2 参数赋值 占位符参数
// 第一个参数: 占位符的索引位置:(从1开始) 第二个参数:取值
final Query query1 = query.setParameter(1, "chenya%");
final List resultList = query.getResultList();
for (Object o : resultList) {
System.out.println(o);
}
// 4.提交事务
transaction.commit();
// 释放资源
em.close();
}
}
这种方法一般不常用,常用的是已经封装好的,但是底层源码应该就是这样的,初步理解,如果错误,指出更正。
代码上传到git:
"springdatajpa"