springboot学习第5期 - spring data jpa

spring data jpa 简化了数据库操作,在国外比较受欢迎,国内用的比较多的是 mybatis-plus。

引入依赖

xml 复制代码
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
  <groupId>com.mysql</groupId>
  <artifactId>mysql-connector-j</artifactId>
  <scope>runtime</scope>
</dependency>

配置

properties 复制代码
spring.datasource.url=jdbc:mysql://localhost:3306/helloword
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

上面 4 个属性就不多讲了,讲一下下面三个配置属性。

  • spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect

Hibernate 为不同的数据库类型提供了翻译器,如果你使用的是 mysql 8.x,则声明为 MySQL8Dialect,不写的话可能会导致兼容性问题。

  • spring.jpa.hibernate.ddl-auto=update

自动更新表结构,但不会删除表数据。

具体表现如下:

场景 Hibernate 会做什么
表不存在 自动创建表
表存在但字段不匹配 自动添加缺失的列
字段类型变化 尝试修改类型(可能失败,取决于数据库)
删除实体类里的字段 不会删除数据库中的列(安全)

还有其他取值:

取值 作用(启动时 Hibernate 对数据库表结构的处理) 常用场景
none 什么都不做,不检查也不修改表结构。 生产环境默认推荐
validate 只校验实体类字段和表是否匹配,不匹配就抛异常。 生产/测试,防止意外改表
update 自动更新表结构 开发/调试
create 先删所有表,再重新创建(数据全丢)。 单元测试或快速原型
create-drop 启动时 create,应用退出时再全部删表 一次性演示/集成测试
  • spring.jpa.show-sql=true

控制台会打印sql,生产环境建议关闭。

定义表结构

定义如下的对象,当程序启动后,会自动创建 tbl_user 表,不需要自己手动写sql语句。

java 复制代码
@Data
@Entity
@Table(name = "tbl_user")
public class UserDo {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    private Integer age;
}

主键策略 GenerationType.IDENTITY 的意思是: 把主键的生成完全交给数据库的自增机制(MySQL 的 AUTO_INCREMENT),JPA/Hibernate 执行 INSERT 时 ,而是等数据库成功插入后,再把数据库生成的主键值 取出来回填到实体对象的 id 字段。

唯一约束 和 非null 约束

可以给字段添加唯一约束 和 非null 约束。

java 复制代码
@Column(unique = true, nullable = false)
private String name;

注意,如果表和字段已经存在,再重新设置唯一约束和非null约束,是不会生效的,所以最好创建的时候就确定好,生产环境一般会使用 flyway 固化sql

字符长度设置

默认 String 类型的长度是 varchar(255),可以自定义它的长度。

java 复制代码
@Column(length = 512)
private String email;

实际生产中还是会结合 flyway 手写sql定义表结构,所以定义表结构的很多用法,了解即可。

定义Repository

java 复制代码
public interface UserRepository extends JpaRepository<UserDo, Long> {
}

JpaRepository 内部已经自带了常用的sql操作,比如根据id查询,查询所有数据;也可以自己添加一些操作,不用手写sql,jpa有一套规则,会自动生成sql。

java 复制代码
public interface UserRepository extends JpaRepository<UserDo, Long> {

    UserDo findByName(String name);

}

规则有如下:

关键字 示例方法名 生成的 SQL 片段
And findByNameAndAge where name = ? and age = ?
Or findByNameOrAge where name = ? or age = ?
Is / Equals findByNameIs where name = ?
IsNot findByNameIsNot where name <> ?
Like findByNameLike where name like ?
NotLike findByNameNotLike where name not like ?
StartingWith findByNameStartingWith where name like 'xxx%'
EndingWith findByNameEndingWith where name like '%xxx'
Containing findByNameContaining where name like '%xxx%'
LessThan findByAgeLessThan where age < ?
LessThanEqual findByAgeLessThanEqual where age <= ?
GreaterThan/GreaterThanEqual findByAgeGreaterThan where age > ?
Between findByAgeBetween where age between ? and ?

使用 Repository

java 复制代码
@RestController
@RequestMapping("/api/hello")
@Validated
@RequiredArgsConstructor
public class HelloController {

    private final UserRepository userRepository;

    @GetMapping
    public List<UserDo> hello() {
        return userRepository.findAll();
    }
}

审计功能

审计就是什么人再什么时间点删除/修改了记录。

spring data jpa 支持 创建时间,修改时间,创建人,修改人 这几个审计字段。

开启审计

再主类上添加注解 @EnableJpaAuditing 即可。

审计父类

实际使用的时候可以将审计字段抽离出来:

java 复制代码
@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class AuditableEntity {

    @CreatedDate
    private LocalDateTime createdAt;

    @LastModifiedDate
    private LocalDateTime updatedAt;

    @CreatedBy
    private String createdBy;

    @LastModifiedBy
    private String updatedBy;
}

实际使用可以继承这个类:

java 复制代码
@Entity
@Getter
@Setter
@Table(name = "tbl_user")
public class UserDo extends AuditableEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String username;

    private String passwordHash;

    private String email;
}

其中创建者和修改者,需要定义填充规则:

java 复制代码
@Component
public class AuditorAwareImpl implements AuditorAware<String> {
    @Override
    public Optional<String> getCurrentAuditor() {
        // 示例:从 SecurityContext 拿登录人
        return Optional.of("system");
    }
}

软删除

软删除就是数据库中有个字段专门标记是否被删除,而不是直接删除记录。

首先表中先定义一个字段表示是否删除,比如 is_deleted,然后可以在审计类中,添加下面这行即可:

java 复制代码
@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
@SoftDelete(columnName = "is_deleted")
public abstract class AuditableEntity {

    @CreatedDate
    private LocalDateTime createdAt;

    @LastModifiedDate
    private LocalDateTime updatedAt;

    @CreatedBy
    private String createdBy;

    @LastModifiedBy
    private String updatedBy;
}

对于 is_deleted 为 true 的字段,正常查询是查不到的,除非自己自定义sql查询。

分页

自带分页功能,直接用就行:

java 复制代码
@GetMapping
public Page<UserDo> hello() {

    Pageable pageable = PageRequest.of(0, 1, Sort.by("id").descending());

    Page<UserDo> all1 = userRepository.findAll(pageable);

    return all1;
}

page = 0 是第1页,如果想和前端保持统一,数字1才是第1也,则传进后端的page参数减去1再调用api即可。

特殊场景,需要结合其他条件进行分页,只要参数带上 pageable 就好了。

java 复制代码
public interface UserRepository extends JpaRepository<User, Long> {

    // 1) 自带分页
    Page<User> findAll(Pageable pageable);

    // 2) 带条件的分页
    Page<User> findByUsernameContaining(String keyword, Pageable pageable);
}

主类上可以添加 @EnableSpringDataWebSupport(pageSerializationMode = EnableSpringDataWebSupport.PageSerializationMode.VIA_DTO),否则Controller直接返回Page的实现类会出现告警

多表查询

待补充

相关推荐
smileNicky9 小时前
SpringBoot系列之从繁琐配置到一键启动之旅
java·spring boot·后端
柏油12 小时前
Spring @TransactionalEventListener 解读
spring boot·后端·spring
小小工匠13 小时前
Maven - Spring Boot 项目打包本地 jar 的 3 种方法
spring boot·maven·jar·system scope
板板正15 小时前
Spring Boot 整合MongoDB
spring boot·后端·mongodb
泉城老铁15 小时前
在高并发场景下,如何优化线程池参数配置
spring boot·后端·架构
泉城老铁16 小时前
Spring Boot中实现多线程6种方式,提高架构性能
spring boot·后端·spring cloud
hrrrrb16 小时前
【Java Web 快速入门】九、事务管理
java·spring boot·后端
布朗克16818 小时前
Spring Boot项目通过RestTemplate调用三方接口详细教程
java·spring boot·后端·resttemplate
IT毕设实战小研19 小时前
基于Spring Boot校园二手交易平台系统设计与实现 二手交易系统 交易平台小程序
java·数据库·vue.js·spring boot·后端·小程序·课程设计
孤狼程序员20 小时前
【Spring Cloud 微服务】1.Hystrix断路器
java·spring boot·spring·微服务