1. 相关概念
(1) JPA 由来
JPA(Java Persistence API)是 Java EE 的一部分,提供了一个对象关系映射(ORM)框架,用于将 Java 对象持久化到数据库中。它的主要目标是简化数据库操作,并减少开发人员在处理数据库时所需的低级编程工作。JPA 在 2006 年的 JSR 220 中被正式定义,并由多个实现如 Hibernate、EclipseLink 和 OpenJPA 提供支持
(2) JPA 是什么
JPA 是一种标准的 Java API,用于定义和管理 Java 应用程序中的持久化操作。它提供了将 Java 对象映射到数据库表的机制,并提供了进行 CRUD(创建、读取、更新、删除)操作的方法。JPA 主要通过实体类(Entity)、持久化上下文(Persistence Context)和查询语言(JPQL)来实现数据访问
(3) Spring Data JPA
Spring Data JPA 是 Spring 数据访问模块的一部分,旨在简化 JPA 的使用。它提供了一个用于访问数据库的高级抽象层,减少了样板代码,并提供了许多便捷的功能,例如动态查询、分页和排序。Spring Data JPA 通过创建 JPA 仓库接口来管理数据访问,这些接口自动生成实现类,从而简化了开发过程
2. 核心功能
(1) 基本操作
1.实体类定义
package com.ktjiaoyu.ch02.pojo;
import javax.persistence.*;
import java.io.Serializable;
/**
* @Author: wangtao
* @CreateTime: 2024-08-28-19:57
* @Description: 用户实体类
* @Version: 1.0
*/
@Entity
@Table(name = "sys_user")
@NamedQueries(@NamedQuery(name = "User.findUsersByName",query = "select u from User u where u.usrName = ?1"))
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "usr_id")
private Long usrId;
@Column(name = "usr_name")
private String usrName;
@Column(name = "usr_password")
private String usrPassword;
@Column(name = "usr_role_id")
private Long usrRoleId;
@Column(name = "usr_flag")
private Integer usrFlag;
public User() {
}
public User(String usrName, String usrPassword, Long usrRoleId, Integer usrFlag) {
this.usrName = usrName;
this.usrPassword = usrPassword;
this.usrRoleId = usrRoleId;
this.usrFlag = usrFlag;
}
public Long getUsrId() {
return usrId;
}
public void setUsrId(Long usrId) {
this.usrId = usrId;
}
public String getUsrName() {
return usrName;
}
public void setUsrName(String usrName) {
this.usrName = usrName;
}
public String getUsrPassword() {
return usrPassword;
}
public void setUsrPassword(String usrPassword) {
this.usrPassword = usrPassword;
}
public Long getUsrRoleId() {
return usrRoleId;
}
public void setUsrRoleId(Long usrRoleId) {
this.usrRoleId = usrRoleId;
}
public Integer getUsrFlag() {
return usrFlag;
}
public void setUsrFlag(Integer usrFlag) {
this.usrFlag = usrFlag;
}
}
2.JPA 仓库接口
package com.ktjiaoyu.ch02.repository;
import com.ktjiaoyu.ch02.pojo.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
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 org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* @Author: wangtao
* @CreateTime: 2024-08-28-20:01
* @Description:
* @Version: 1.0
*/
public interface UserRepository extends JpaRepository<User,Long>, JpaSpecificationExecutor<User> {
//添加根据用户名模糊查询(SpringBoot自动实现)
public List<User> findByUsrNameLike(String usrName);
// 自定义SQL
// @Query("select u from User u where u.usrRoleId=?1")
// 原生SQL
// @Query(value = "select * from sys_suer where usr_role_id=?1",nativeQuery = true)
//@Param注解命名参数
@Query("select u from User u where u.usrRoleId=:roleId")
public List<User> findByRoleId(@Param("roleId") Long roleId);
//根据Id修改Name
@Transactional(timeout = 10)
@Modifying
@Query("update User u set u.usrName = ?1 where u.usrId = ?2")
public int modifyNameById(String usrName,Long usrId);
//此方法对应User实体中的命名查询
List<User> findUsersByName(String usrName);
//分页查询
@Query("select u from User u where u.usrRoleId = ?1")
Page<User> findPageByUsrRoleId(Long roleId , Pageable pageable);
}
3.服务层
package com.ktjiaoyu.ch02.service;
import com.ktjiaoyu.ch02.pojo.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import java.util.Map;
/**
* @Author: wangtao
* @CreateTime: 2024-08-28-20:42
* @Description: 用户类服务接口
* @Version: 1.0
*/
public interface UserService {
Page<User> findPageByMap(Map param, Pageable pageable);
}
package com.ktjiaoyu.ch02.service.impl;
import com.ktjiaoyu.ch02.pojo.User;
import com.ktjiaoyu.ch02.repository.UserRepository;
import com.ktjiaoyu.ch02.service.UserService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @Author: wangtao
* @CreateTime: 2024-08-28-20:43
* @Description: 用户服务接口实现类
* @Version: 1.0
*/
@Service
public class UserServiceImpl implements UserService {
@Resource
private UserRepository userRepository;
public Page<User> findPageByMap(final Map param, Pageable pageable) {
return userRepository.findAll(new Specification<User>() {
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
List<Predicate> predicates = new ArrayList<Predicate>();
if (param.get("usrName") != null) {
predicates.add(cb.like(root.<String>get("usrName"), "%" + param.get("usrName") + "%"));
}
if (param.get("roleId") != null) {
predicates.add(cb.equal(root.get("usrRoleId"), param.get("roleId")));
}
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
}
},pageable);
}
}
(2) 复杂操作
1.动态查询
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface UserRepository extends JpaRepository<User, Long> {
@Query("SELECT u FROM User u WHERE u.name = :name")
List<User> findByName(@Param("name") String name);
}
2.分页和排序
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
public class UserService {
@Autowired
private UserRepository userRepository;
public Page<User> getUsersByPage(int page, int size) {
return userRepository.findAll(PageRequest.of(page, size, Sort.by(Sort.Direction.ASC, "name")));
}
}
3.使用 Specification 进行复杂查询
import org.springframework.data.jpa.domain.Specification;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
public class UserSpecifications {
public static Specification<User> hasEmail(String email) {
return new Specification<User>() {
@Override
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
return criteriaBuilder.equal(root.get("email"), email);
}
};
}
}