完整的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
#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;
}
启动重新创建好数据表后,我们添加一些测试数据到user表。
关键字 | 举例 | 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。
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);
}
}
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)将字段设置不可修改,只允许一次赋值。创建者和创建时间只需要插入一次,不需要更新。
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;
}
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));
}
}
我们在单元测试中,测试添加用户
@Test
void testAddUser() {
User user = new User();
user.setName("qq");
user.setAge(20);
userRepository.save(user);
}
执行方法后,我们查看数据表,发现自动添加上了创建者和创建时间。
接下来我们测试修改用户的方法
@Test
void testUpdateUser(){
Optional optional = userRepository.findById(2L);
User user = optional.get();
user.setAge(22);
userRepository.save(user);
}
执行方法后,我们查看数据表,发现自动修改了更新时间和修改操作人。