##1、Spring Data JPA的概述
Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据库的访问和操作。它提供了包括增删改查等在内的常用功能,且易于扩展!学习并使用 Spring Data JPA 可以极大提高开发效率!
Spring Data JPA 让我们解脱了DAO层的操作,基本上所有CRUD都可以依赖于它来实现,在实际的工作工程中,推荐使用Spring Data JPA + ORM(如:hibernate)完成操作,这样在切换不同的ORM框架时提供了极大的方便,同时也使数据库层操作更加简单,方便解耦
SpringData Jpa 极大简化了数据库访问层代码。 如何简化的呢? 使用了SpringDataJpa,我们的dao层中只需要写接口,就自动具有了增删改查、分页查询等方法。
JPA是一套规范,内部是有接口和抽象类组成的。hibernate是一套成熟的ORM框架,而且Hibernate实现了JPA规范,所以也可以称hibernate为JPA的一种实现方式,我们使用JPA的API编程,意味着站在更高的角度上看待问题(面向接口编程)
Spring Data JPA是Spring提供的一套对JPA操作更加高级的封装,是在JPA规范下的专门用来进行数据持久化的解决方案。
使用Spring Data JPA,需要整合Spring与Spring Data JPA,并且需要提供JPA的服务提供者hibernate,所以需要导入spring相关坐标,hibernate坐标,数据库驱动坐标等
5.0.2.RELEASE
5.0.7.Final
1.6.6
1.2.12
0.9.1.2
5.1.18
junit
junit
4.12
test
org.aspectj
aspectjweaver
1.6.8
org.springframework
spring-aop
${spring.version}
org.springframework
spring-context
${spring.version}
org.springframework
spring-context-support
${spring.version}
org.springframework
spring-orm
${spring.version}
org.springframework
spring-beans
${spring.version}
org.springframework
spring-core
${spring.version}
org.hibernate
hibernate-core
${hibernate.version}
org.hibernate
hibernate-entitymanager
${hibernate.version}
org.hibernate
hibernate-validator
5.2.1.Final
c3p0
c3p0
${c3p0.version}
log4j
log4j
${log4j.version}
org.slf4j
slf4j-api
${slf4j.version}
org.slf4j
slf4j-log4j12
${slf4j.version}
mysql
mysql-connector-java
${mysql.version}
org.springframework.data
spring-data-jpa
1.9.0.RELEASE
org.springframework
spring-test
${spring.version}
javax.el
javax.el-api
2.2.4
org.glassfish.web
javax.el
2.2.4
import javax.persistence.*;
/**
* 客户实体类
*/
@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_address")
private String custAddress;
@Column(name="cust_phone")
private String custPhone;
// 省略 setter and getter 及 toString 方法
}
import com.domain.Customer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
/**
* 创建符合SpringDataJpa规范的接口: 约定优于配置
* 1、继承JpaRepository,并写上相应的泛型 : 增删改查
* *第一个泛型:我们要操作的实体类
* *第二个泛型:主键属性的数据类型
* 2、继承JpaSpecificationExecutor,并写上相应的泛型 : 复杂查询,动态查询
* *只有一个泛型: 就是我们操作的实体类
*
*
* SpringDataJpa中的查询:
*
* 1、dao接口中定义的方法
save和delete
findAll();查询所有
findOne(id);查询一个对象:立即查询
getOne(id); 查询一个对象:延迟加载
@Transactional
* 为了测试延迟加载,这个测试方法上需要加上一个事务注解:只是为了去掉no session异常
* 调用的是EntityManager.getReference();
count();查询总记录数
exists(id的值);查询对象是否存在,true存在,false不存在
* 判断一个实体是否存在: exists方法
* 1、发送根据id查询语句,如果查出来不为空,就代表存在,反之不存在
* select * from cst_customer where cust_id = ?
* 2、发送统计查询语句,统计有几条,如果大于0,就代表存在这条数据,反之不存在
* select count(*) from cst_customer where cust_id = ?
*
* SpringDataJpa用那种?看控制它发送的sql语句就可以了,我们测试发送,Spring用的是第二种
* 1、调用的是exists方法,传入的id主键值
* 2、返回的是布尔类型:
* true: 存在
* false:不存在
2、JPQL查询
JPA Query Language : jpa查询语言
需要写JPQL:
1、把sql中的表名换成实体类的名称
2、把sql中的字段名换成实体类中属性的名称
SpringDataJpa中使用jpql查询注意点:
1、需要在我们的接口中编写方法
2、在这个方法上使用注解:@Query,此注解中的value属性出入的就是jpql语句
3、如果是【更新】操作:除了加入Query之外还需要一个@Modifying注解
4、测试更新的时候需要加入事务和回滚的注解,只是为了测试
@Transactional
@Rollback(false)
*
* 1、在测试更新的时候,需要用到一个注解:@Transactional : 加入这个注解只是为了让程序不报错
* 2、加入了@Transactional注解后,程序不报错,但是数据没有更新
* 3、默认的情况下,我们在service层使用到是声明式事务,可以正常去更新数据,但是现在我们没有service层,所以需要加入另外一个注解
* @Rollback : 默认情况下我们没有service的时候,执行完之后,会回滚
* value: true 回滚
* value: false 不回滚
3、SQL查询【了解】
@Query注解:
* value属性:写的sql语句
* nativeQuery:
* true: sql查询
* false: jpql查询【默认值】
4、方法名规则查询
1)编写dao中的方法,编写有规则的
2)方法名以 findBy开头
3)findBy后面跟上的是 对象的属性名称,首字母大写
5、动态查询
*/
public interface CustomerDao extends JpaRepository,JpaSpecificationExecutor{
//================== 2、JPQL查询 ==================================
/**
* 查询所有客户
* @return
*/
@Query("from Customer")
public List findJPQL();
/**
* JPQL的条件查询:精确匹配
*/
@Query("from Customer where custName = ?")
public Customer findJPQL2(String n);
/**
* JPQL的条件查询:模糊查询
*/
@Query("from Customer where custName like ?")
public List findJPQL3(String n);
/**
* JPQL的多条件查询
* 默认情况下: 方法中的参数有索引:从1开始, 占位符可以指定索引
* ?1 获取的是方法参数列表中的第一个参数
* ?2 获取的是方法参数列表中的第二个参数
*
*/
@Query("from Customer where custName like ?2 and custId = ?1")
public List findJPQL4(Long id ,String n);
/**
* 需求:只修改客户的名称
*
* 使用JPQL来执行
* 需要用到两个注解:
* @Query里面写入的是update的语句
* @Modifying 告诉框架我们进行的是一个修改操作
*/
@Query("update Customer set custName = ?2 where custId = ?1")
@Modifying
public void updateCustomerName(Long id,String name);
//================== 3、SQL查询【了解】 ==================================
/**
* sql查询:
* @Query注解:
* value属性:写的sql语句
* nativeQuery:
* true: sql查询
* false: jpql查询【默认值】
*
*/
@Query(value="select * from cst_customer where cust_name like ?2 and cust_id = ?1",nativeQuery = true)
public List findsql(Long id,String name);
//================== 4、方法名规则查询【推荐】==================================
/**
* 根据方法名查询:
* findByCustName : 根据客户名称精确查询
*/
public List findByCustName(String name);
/**
* 根据方法名查询:
* findByCustName + Like : 根据客户名称模糊查询
*/
public List findByCustNameLike(String name);
/**
* 根据方法名查询:多条件
* findByCustName + Like + And | Or + 对象的属性名称,首字母大写 + [Like ]
*/
public List findByCustNameLikeAndCustId(String name,Long id);
}
1、注入的dao的实现类:代理对象,JDKDynamicAopProxy
2、代理对象实现InvocationHandler接口,此接口中有invoke方法
3、此方法中调用具体dao的实现类:target = SimpleJpaRepository
4、底层完成的增删改查都是SimpleJpaRepository来完成
5、此类实现implements JpaRepository, JpaSpecificationExecutor接口
6、我们调用customerDao.findOne(1L);方法底层其实就是调用SimpleJpaRepository的findOne
7、findOne的方法中调用:em.find(domainType, id);
8、em到底是谁?
它就是jpa规范中的实体类管理器
SpringDataJpa其实就是JPA规范封装
实例详解Spring Data JPA的使用
https://blog.csdn.net/l1357852347/article/details/73718700#t6