前言
SpringBoot 整合 JPA
。
实现
理论
Spring Data 是 Spring 提供的一个操作数据的框架,Spring Data JPA
是 Spring Data
下的一个基于 JPA
标准的操作数据的模块。
JPA(Java Persistence API)
是 Java 母公司 Sun 公司提出的一套 Java 持久化规范。所谓规范,就是只定义标准,不提供实现。
JPA 的提出主要是为了整合市面上已有的 ORM 框架,比如说 Hibernate、EclipseLink 等。官方觉得你们搞框架可以,但不要乱搞,得按照标准来。
Spring Data JPA 只是一个抽象层,它上接 JPA 下接 ORM 框架,通过基于 JPA 的 Respository
接口极大地减少了 JPA 作为数据访问方案的代码量,简化了持久层开发并且屏蔽了各大 ORM 框架的差异。
总结一下就是:
JPA
是规范,统一了规范才便于使用。Hibernate
是 JPA 的实现,是一套成熟的 ORM 框架。Spring Data JPA
是 Spring 提出的,它增加了一个抽象层,用来屏蔽不同 ORM 框架的差异。
SpringBoot
新建一个 SpringBoot 项目。
pom.xml
在 pom.xml
文件中导入以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
application.properties
在 application.properties
中添加如下配置项:
spring.datasource.username=root
spring.datasource.password=
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false
# 开启JPA的SQL输出
spring.jpa.show-sql=true
User实体类
创建 User 实体类。
package com.langjialing.jpademo.entity;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* @author 郎家岭伯爵
* @time 2023/7/12 10:56
*/
@Data
@Entity
@Table(name = "user")
public class User {
@Id
private Integer userId;
private Integer age;
private String userName;
private String password;
}
@Data
注解为 lombok 注解,会自动为该类添加getter/setter
方法。@Entity
和@Table
注解都是 JDK 1.5 以后引入的元数据注解,遵循 JPA 规范中定义的查询语言JPQL(Java Persistence Query Language)
执行数据库查询。JPQL 类似于 SQL,但是针对实体对象而不是数据库表,类似 SQL 语法,适用于 Java 类。@Entity
表明该类是一个实体类,默认使用ORM
规则,即类名为数据库表名,类中的字段名为数据库表中的字段名。@Table
注解是非必选项,它的优先级高于@Entity
注解,比如说@Entity(name="user")
和 @Table(name="users")
同时存在的话,对应的表名为users
。@Id
表名该字段为主键字段,当声明了@Entity
注解,@Id
就必须也得声明。
UserRepository接口类
创建 UserRepository
接口类。
package com.langjialing.jpademo.repository;
import com.langjialing.jpademo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
/**
* @author 郎家岭伯爵
* @time 2023/7/12 13:18
*/
public interface UserRepository extends JpaRepository<User, Integer> {
/**
* 自定义查询方法
* @param name name
* @return List
*/
@Query("select u from User u where u.userName like concat('%',?1,'%')")
List<User> findByNameLikeIgnoreCase(String name);
}
- 如果只是简单的对表进行
增删改查
操作,那么只需要继承JpaRepository
接口,并传递两个参数(第一个为实体类,第二个为主键类型)即可。 @Query
注解中的User
为实体类的类名,而非数据库的表名 user。这是 JPQL 和原生 SQL 的区别。
Service层
Service 接口类:
package com.langjialing.jpademo.service;
import com.langjialing.jpademo.entity.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import java.util.List;
/**
* @author 郎家岭伯爵
* @time 2023/7/12 13:20
*/
public interface UserService {
/**
* 根据ID查询单个用户。
* @param id id
* @return user
*/
User findById(Integer id);
/**
* 查找所有用户。
* @return List
*/
List<User> findAll();
/**
* 新增/更新用户。
* @param user user
* @return User
*/
User save(User user);
/**
* 根据ID删除用户。
* @param id ID
*/
void delete(Integer id);
/**
* 查询所有用户(分页)。
* @param pageable 分页参数
* @return Page
*/
Page<User> findAll(Pageable pageable);
/**
* 根性名字查询用户。
* @param name name
* @return List
*/
List<User> findByNameLikeIgnoreCase(String name);
}
Service 接口实现类:
package com.langjialing.jpademo.service.impl;
import com.langjialing.jpademo.entity.User;
import com.langjialing.jpademo.repository.UserRepository;
import com.langjialing.jpademo.service.UserService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
* @author 郎家岭伯爵
* @time 2023/7/12 13:23
*/
@Service
public class UserServiceImpl implements UserService {
@Resource
private UserRepository userRepository;
@Override
public User findById(Integer id) {
return userRepository.findById(id).orElse(null);
}
@Override
public List<User> findAll() {
return userRepository.findAll();
}
@Override
public User save(User user) {
return userRepository.save(user);
}
@Override
public void delete(Integer id) {
userRepository.deleteById(id);
}
@Override
public Page<User> findAll(Pageable pageable) {
return userRepository.findAll(pageable);
}
@Override
public List<User> findByNameLikeIgnoreCase(String name) {
return userRepository.findByNameLikeIgnoreCase(name);
}
}
@Resource
和@Autowired
注解都是用来自动装配对象的,可以用在字段上,也可以用在setter
方法上。@Autowired
是 Spring 提供的注解,@Resource
是 Java 提供的注解,也就是说,如果项目没有使用 Spring 框架而是 JFinal 框架,@Resource 注解也是支持的。另外,@Resource
是byName
自动装配,@Autowired
是byType
自动装配,当有两个类型完全一样的对象时,@Autowired 就会出错了。
controller层
创建 UserController 测试方法。
package com.langjialing.jpademo.controller;
import com.langjialing.jpademo.entity.User;
import com.langjialing.jpademo.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* @author 郎家岭伯爵
* @time 2023/7/12 13:34
*/
@RestController
@Slf4j
public class UserController {
@Resource
private UserService userService;
@PostMapping("/save")
public User save(@RequestBody User user) {
return userService.save(user);
}
@GetMapping("/find")
public User findById(@RequestParam Integer id) {
return userService.findById(id);
}
@GetMapping("/findByNameLikeIgnoreCase")
public List<User> findByNameLikeIgnoreCase(@RequestParam String name) {
return userService.findByNameLikeIgnoreCase(name);
}
@GetMapping("/findAll")
public List<User> findAll() {
return userService.findAll();
}
@PostMapping("/findAllPage")
public Page<User> findAllPage(Pageable pageable) {
log.info("size:{}", pageable.getPageSize());
log.info("page:{}", pageable.getPageNumber());
return userService.findAll(pageable);
}
@GetMapping("/delete")
public void delete(@RequestParam Integer id) {
userService.delete(id);
}
}
总结
SpringBoot 整合 JPA
。