Spring Data JPA使用规则和审计的学习

一、引入依赖

完整的pom文件如下所示:



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.7.13
         
    
    com.example
    FunlyDemo
    0.0.1-SNAPSHOT
    FunlyDemo
    FunlyDemo
    
        1.8
    
    
        
            org.springframework.boot
            spring-boot-starter-web
        
        
        
            org.projectlombok
            lombok
        
        
        
            mysql
            mysql-connector-java
            8.0.31
        
        
        
            org.springframework.boot
            spring-boot-starter-data-jpa
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    


二、application.properties配置文件

#mysql
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/funly?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&useSSL=false&rewriteBatchedStatements=true
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=123456

#jpa
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

三、创建用户实体类

package com.example.funlydemo.bean;

import lombok.Data;
import lombok.ToString;

import javax.persistence.*;

/**
 * @author qx
 * @date 2023/07/19
 * @desc 用户实体类
 */
@Entity
@Table(name = "t_user")
@Data
@ToString
public class User {

    /**
     * ID
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    /**
     * 姓名
     */
    private String name;
    /**
     * 年龄
     */
    private Integer age;
}

四、JPA规则认识

启动重新创建好数据表后,我们添加一些测试数据到user表。

Spring Data JPA使用规则和审计的学习_第1张图片

关键字 举例        JPQL片段
And        

findAllByNameAndAge

where user0_.name=? and user0_.age=?
Or

findAllByNameOrAge

where user0_.name=? or user0_.age=?
is,Equals

findAllByNameIs,findAllByNameEquals,

findAllByName

where user0_.name=?
Between

findAllByAgeBetween

where user0_.age between ? and ?

LessThan

findAllByAgeLessThan

where user0_.age

LessThanEqual

findAllByAgeLessThanEqual

where user0_.age<=?

GreaterThan

findAllByAgeGreaterThan

where user0_.age>?

GreaterThanEqual

findAllByAgeGreaterThanEqual

where user0_.age>=?

IsNull

findAllByAgeIsNull

where user0_.age is null

IsNotNull

findAllByAgeIsNotNull

where user0_.age is not null

Like

findAllByNameLike

where user0_.name like ? escape ?

NotLike

findAllByNameNotLike

where user0_.name not like ? escape ?

StartingWith

findAllByNameStartingWith

where user0_.name like ?(后置%) escape ?

EndingWith

findAllByNameEndingWith

where user0_.name like ?(前置%) escape ?

Containing

findAllByNameContaining

where user0_.name like ?(双%) escape ?

OrderBy

findAllByNameOrderByAgeDesc

where user0_.name=? order by user0_.age desc

Not

findAllByNameNot

where user0_.name<>?

In

findAllByAgeIn

where user0_.age in (? , ?)

NotIn

findAllByAgeNotIn

where user0_.age not in  (? , ?)

五、持久层方法编写

package com.example.funlydemo.repository;

import com.example.funlydemo.bean.User;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface UserRepository extends JpaRepository {

    List findAllByNameAndAge(String name, Integer age);

    List findAllByNameOrAge(String name, Integer age);

    List findAllByNameIs(String name);

    List findAllByNameEquals(String name);

    List findAllByName(String name);


    List findAllByAgeBetween(Integer age1, Integer age2);

    List findAllByAgeLessThan(Integer age);

    List findAllByAgeLessThanEqual(Integer age);

    List findAllByAgeGreaterThan(Integer age);

    List findAllByAgeGreaterThanEqual(Integer age);

    List findAllByAgeIsNull();

    List findAllByAgeIsNotNull();

    List findAllByNameLike(String name);

    List findAllByNameNotLike(String name);

    List findAllByNameStartingWith(String name);

    List findAllByNameEndingWith(String name);

    List findAllByNameContaining(String name);

    List findAllByNameOrderByAgeDesc(String name);

    List findAllByNameNot(String name);

    List findAllByAgeIn(List ageList);

    List findAllByAgeNotIn(List ageList);
}

六、单元测试类

package com.example.funlydemo;

import com.example.funlydemo.bean.User;
import com.example.funlydemo.repository.UserRepository;
import org.assertj.core.util.Lists;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
class FunlyDemoApplicationTests {

    @Autowired
    private UserRepository userRepository;

    @Test
    void testAnd() {
        List userList = userRepository.findAllByNameAndAge("aa", 11);
        System.out.println(userList);
    }

    @Test
    void testOr() {
        List userList = userRepository.findAllByNameOrAge("aa", 11);
        System.out.println(userList);
    }

    @Test
    void testEquals() {
        List userList = userRepository.findAllByNameIs("aa");
        System.out.println(userList);

        List userList1 = userRepository.findAllByNameEquals("aa");
        System.out.println(userList1);

        List userList2 = userRepository.findAllByName("aa");
        System.out.println(userList2);
    }

    @Test
    void testBetween() {
        List userList = userRepository.findAllByAgeBetween(12, 13);
        System.out.println(userList);
    }

    @Test
    void testLessThan() {
        List userList = userRepository.findAllByAgeLessThan(12);
        System.out.println(userList);
    }

    @Test
    void testLessThanEqual() {
        List userList = userRepository.findAllByAgeLessThanEqual(12);
        System.out.println(userList);
    }

    @Test
    void testGreaterThan() {
        List userList = userRepository.findAllByAgeGreaterThan(12);
        System.out.println(userList);
    }

    @Test
    void testGreaterThanEqual() {
        List userList = userRepository.findAllByAgeGreaterThanEqual(12);
        System.out.println(userList);
    }

    @Test
    void testIsNull() {
        List userList = userRepository.findAllByAgeIsNull();
        System.out.println(userList);
    }

    @Test
    void testIsNotNull() {
        List userList = userRepository.findAllByAgeIsNotNull();
        System.out.println(userList);
    }

    @Test
    void testLike() {
        List userList = userRepository.findAllByNameLike("b%");
        System.out.println(userList);
    }

    @Test
    void testNotLike() {
        List userList = userRepository.findAllByNameNotLike("b%");
        System.out.println(userList);
    }

    @Test
    void testStartingWith() {
        List userList = userRepository.findAllByNameStartingWith("b");
        System.out.println(userList);
    }

    @Test
    void testEndingWith() {
        List userList = userRepository.findAllByNameEndingWith("x");
        System.out.println(userList);
    }

    @Test
    void testContaining() {
        List userList = userRepository.findAllByNameContaining("a");
        System.out.println(userList);
    }

    @Test
    void testOrderBy() {
        List userList = userRepository.findAllByNameOrderByAgeDesc("aa");
        System.out.println(userList);
    }

    @Test
    void testNot() {
        List userList = userRepository.findAllByNameNot("aa");
        System.out.println(userList);
    }

    @Test
    void testIn() {
        List userList = userRepository.findAllByAgeIn(Lists.newArrayList(11, 12));
        System.out.println(userList);
    }

    @Test
    void testNotIn() {
        List userList = userRepository.findAllByAgeNotIn(Lists.newArrayList(11, 12));
        System.out.println(userList);
    }
}

七、自定义规则

我们可以使用JPQL和书写原生SQL的方式实现自定义的规则。JPQL最突出的特点就是以Java Bean为操作对象,遵循JPA规范屏蔽了数据库 之间的差异,使同一套代码可以用在任意数据库上;而SQL方式是以表为操作 对象的,因此可以使用某种数据库特有的功能,比如某个MySQL独有的功能, 但是切换到Oracle时就不能使用了。

JPQL使用示例代码如下:

   @Query("select u from User u where u.name=?1")
    List getDataByName(String name);

原生SQL使用示例代码如下:

 @Query(value = "select * from t_user where name=?1",nativeQuery = true)
    List getUserFromName(String name);
}

设置nativeQuery属性为true,说明使用原生SQL。

八、审计

业务数据的插入时间、最后更新时间、创建人及最后更新人的记录对每个 系统都很重要,但如果每次操作时都需要手动记录这些信息,就会非常枯燥且 烦琐。作为一个成熟的持久层框架,Spring Data JPA应该学会自己审计了。
1.启动类开启审计
package com.example.funlydemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@SpringBootApplication
// 开启审计
@EnableJpaAuditing
public class FunlyDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(FunlyDemoApplication.class, args);
    }

}

2.把审计需要的属性封装到一个公共类

package com.example.funlydemo.bean;

import lombok.Getter;
import lombok.Setter;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;

/**
 * @author qx
 * @date 2023/07/19
 * @desc
 */
@Getter
@Setter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class BaseEntity {

    @CreatedBy
    @Column(updatable = false)
    private String creater;

    @LastModifiedBy
    private String modifier;

    @CreatedDate
    @Column(updatable = false)
    private LocalDateTime createTime;

    @LastModifiedDate
    private LocalDateTime updateTime;


}

@Column(updatable=false)将字段设置不可修改,只允许一次赋值。创建者和创建时间只需要插入一次,不需要更新。

3.用户类继承公共基类

package com.example.funlydemo.bean;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

import javax.persistence.*;

/**
 * @author qx
 * @date 2023/07/19
 * @desc 用户实体类
 */
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "t_user")
@Data
@ToString
public class User extends BaseEntity {

    /**
     * ID
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    /**
     * 姓名
     */
    private String name;
    /**
     * 年龄
     */
    private Integer age;
}

4.创建一个获取当前操作人的接口实现类

package com.example.funlydemo.uti;

import org.springframework.data.domain.AuditorAware;
import org.springframework.stereotype.Component;

import java.util.Optional;

/**
 * @author qx
 * @date 2023/07/19
 * @desc 获取当前操作人的接口
 */
@Component
public class AuditorImpl implements AuditorAware {
    @Override
    public Optional getCurrentAuditor() {
        return Optional.of("admin->" + (int) (Math.random() * 10));
    }
}

5.测试审计

我们在单元测试中,测试添加用户

  @Test
    void testAddUser() {
        User user = new User();
        user.setName("qq");
        user.setAge(20);
        userRepository.save(user);
    }

执行方法后,我们查看数据表,发现自动添加上了创建者和创建时间。

Spring Data JPA使用规则和审计的学习_第2张图片

 接下来我们测试修改用户的方法

  @Test
    void testUpdateUser(){
        Optional optional = userRepository.findById(2L);
        User user = optional.get();
        user.setAge(22);
        userRepository.save(user);
    }

执行方法后,我们查看数据表,发现自动修改了更新时间和修改操作人。

 

Spring Data JPA使用规则和审计的学习_第3张图片

 

你可能感兴趣的:(SpringBoot,Spring,Data,JPA,审计)