diff --git a/starter-data/starter-data-jpa/pom.xml b/starter-data/starter-data-jpa/pom.xml index c78700d..51f02f1 100644 --- a/starter-data/starter-data-jpa/pom.xml +++ b/starter-data/starter-data-jpa/pom.xml @@ -15,7 +15,7 @@ 1.5.3.Final 1.18.20 - + @@ -45,11 +45,11 @@ postgresql 42.3.4 - + test + com.alibaba druid diff --git a/starter-data/starter-data-jpa/src/main/java/com/zja/dao/example/ExampleUserRepo.java b/starter-data/starter-data-jpa/src/main/java/com/zja/dao/example/ExampleUserRepo.java index 658877e..8ee5ac6 100644 --- a/starter-data/starter-data-jpa/src/main/java/com/zja/dao/example/ExampleUserRepo.java +++ b/starter-data/starter-data-jpa/src/main/java/com/zja/dao/example/ExampleUserRepo.java @@ -6,9 +6,12 @@ import org.springframework.data.domain.Sort; 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.CrudRepository; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.Optional; @@ -23,38 +26,105 @@ public interface ExampleUserRepo extends CrudRepository, JpaSpecificationExecutor { + //==================查询================== + + // 简单查询 Optional findByLoginName(String loginName); + // ExampleUser findByLoginName(String loginName); + + // 按loginName查询name值 + @Query("SELECT u.name FROM ExampleUser u WHERE u.loginName = ?1") + Optional findNameByLoginName(String loginName); + // String findNameByLoginName(String loginName); - List findByIdIn(List ids); + // 批量查询 + List findByLoginNameIn(List loginNames); - //统计查询 + // 模糊查询,支持:%name%、%name、name% + List findByNameLike(String name); + + // 统计查询 long countByName(String name); - //删除查询 - long deleteByName(String name); + //==================查询-end================== - List removeByName(String name); - //实体类名称 - @Query("select u from #{#entityName} u where u.name = ?1") -// @Query("select u from ExampleUser u where u.name = ?1") - List findByName(String name); + //==================分页查询+排序================== + + // 分页查询 + Page findByName(String name, Pageable pageable); + // List findByName(String name, Pageable pageable); - //分页查询 - Page findByName(String lastname, Pageable pageable); + // 分页模糊查询,支持:%name%、%name、name% + Page findByNameLike(String name, Pageable pageable); - //分页模糊查询 - Page findByNameLike(String lastname, Pageable pageable); + // 按name模糊分页查询,并按age和createTime排序 + Page findByNameContainingIgnoreCaseOrderByAgeAscCreateTimeDesc(String name, Pageable pageable); + // 排序查询 List findByName(String name, Sort sort); - //List findByName(String lastname, Pageable pageable); -/* //使用 SpEL 表达式 - 通配符快捷方式 - @Query("select u from ExampleUser u where u.name like %:#{[0]}% and u.name like %:lastname%") - List findByNameWithSpelExpression(@Param("name") String name); + //==================分页查询-end================== + + + //==================SpEL 表达式 通配符 ================== + + // 按关键词name模糊分页查询,并按age和createTime排序,采用SpEL 表达式 通配符 + @Query("SELECT u FROM ExampleUser u WHERE u.name LIKE %:keyword% ORDER BY u.age ASC, u.createTime DESC") + Page findByKeywordOrderByAgeAscCreateTimeDesc(@Param("keyword") String keyword, Pageable pageable); + + // 按实体类名称和name字段模糊分页查询,并按age和createTime排序,采用SpEL 表达式 通配符 + // 注:entityName=ExampleUser + @Query("SELECT u FROM #{#entityName} u WHERE u.name LIKE %:keyword% ORDER BY u.age ASC, u.createTime DESC") + Page findByEntityAndNameLikeOrderByAgeAscCreateTimeDesc(@Param("entityName") String entityName, @Param("keyword") String keyword, Pageable pageable); + + // 实体类名称 + @Query("select u from #{#entityName} u where u.name = :name") + // @Query("select u from ExampleUser u where u.name = ?1") + List querySpELByName(String entityName, String name); + + //==================SpEL 表达式 通配符-end ================== + + + //==================更新================== - //修改查询 + // 按loginName更新name值 + @Transactional @Modifying - @Query("update ExampleUser u set u.firstname = ?1 where u.name = ?2") - int setFixedFirstnameFor(String firstname, String name);*/ + @Query("UPDATE ExampleUser u SET u.name = :newName WHERE u.loginName = :loginName") + void updateNameByLoginName(String newName, String loginName); + // @Query("update ExampleUser u set u.name = ?1 where u.loginName = ?2") + // int updateNameByLoginName(String name, String loginName); + + // 按loginName更新name值,采用nativeQuery=true写法 + // @Modifying + // @Query(value = "UPDATE example_user SET name = :newName WHERE login_name = :loginName", nativeQuery = true) + // void updateNameByLoginName(String newName, String loginName); + + //==================更新-end================== + + //==================删除================== + + // 按 loginName 删除相关记录 + void deleteByLoginName(String loginName); + + // 按loginName删除name值 + @Transactional + @Modifying + @Query("UPDATE ExampleUser u SET u.name = NULL WHERE u.loginName = :loginName") + void deleteNameByLoginName(String loginName); + + // 按loginName删除name值,采用nativeQuery=true写法 + // @Modifying + // @Query(value = "UPDATE example_user SET name = NULL WHERE login_name = :loginName", nativeQuery = true) + // void deleteNameByLoginName(String loginName); + + // 按name删除,并返回删除的相关记录个数 + long deleteByName(String name); + + // 按name删除,并放回删除的相关记录 + List removeByName(String name); + + //==================删除-end================== + } diff --git a/starter-data/starter-data-jpa/src/main/java/com/zja/entitys/example/ExampleUser.java b/starter-data/starter-data-jpa/src/main/java/com/zja/entitys/example/ExampleUser.java index c06aae7..451c9cf 100644 --- a/starter-data/starter-data-jpa/src/main/java/com/zja/entitys/example/ExampleUser.java +++ b/starter-data/starter-data-jpa/src/main/java/com/zja/entitys/example/ExampleUser.java @@ -25,7 +25,7 @@ public class ExampleUser extends BaseEntity { /** * 用户名 */ - @Column(name = "user_name", nullable = false) + @Column(name = "user_name") private String name; /** @@ -34,6 +34,11 @@ public class ExampleUser extends BaseEntity { @Column(name = "LOGIN_NAME", nullable = false) private String loginName; + /** + * 住址 + */ + private String address; + /** * 年龄 */ diff --git a/starter-data/starter-data-jpa/src/test/java/com/zja/dao/example/ExampleUserRepoTest.java b/starter-data/starter-data-jpa/src/test/java/com/zja/dao/example/ExampleUserRepoTest.java deleted file mode 100644 index b29c28c..0000000 --- a/starter-data/starter-data-jpa/src/test/java/com/zja/dao/example/ExampleUserRepoTest.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.zja.dao.example; - -import com.zja.JpaApplicationTest; -import com.zja.entitys.User; -import com.zja.entitys.example.ExampleUser; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; - -import java.time.LocalDateTime; -import java.util.List; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; - -/** - * -单元测试类 - * - * @author: zhengja - * @since: 2024/04/15 13:16 - */ -@SpringBootTest -public class ExampleUserRepoTest extends JpaApplicationTest { - - @Autowired - ExampleUserRepo repo; - - @Test - public void test_1() { - for (int i = 0; i < 10; i++) { - ExampleUser user = new ExampleUser(); - user.setName("李四"); - user.setLoginName("lisi"); - user.setAge(10 + i); - user.setCreateTime(LocalDateTime.now()); - ExampleUser save = repo.save(user); - System.out.println(save); - } - } - - @Test - public void test_2() { - long byName = repo.countByName("李四"); - System.out.println(byName); - } - - @Test - public void test_3() { - Page users = page("李四", 1, 5); - - assertThat(users).isNotNull(); - for (ExampleUser user : users) { - System.out.println(user.getName()); - } - } - - public Page page(String name, - Integer pageNum, - Integer pageSize) { - // 当前页, 每页记录数 - Pageable pageable = PageRequest.of(pageNum - 1, pageSize); - return repo.findByName(name, pageable); - } - - @Test - public void test_4() { - List users = sort("李四"); - System.out.println(users); - } - - /** - * 列举了四种排序方式: - * 1)直接创建Sort对象,适合对单一属性做排序 - * 2)通过Sort.Order对象创建Sort对象,适合对单一属性做排序 - * 3)通过属性的List集合创建Sort对象,适合对多个属性,采取同一种排序方式的排序 - * 4)通过Sort.Order对象的List集合创建Sort对象,适合所有情况,比较容易设置排序方式 - */ - public List sort(String name) { - return repo.findByName(name, Sort.by("id", "createTime")); - } - - @Test - public void test_5() { - Pageable pageable = PageRequest.of(0, 5); - Page userPage = repo.findByNameLike("%李%", pageable); - for (ExampleUser exampleUser : userPage) { - System.out.println(exampleUser.getName()); - } - } -} \ No newline at end of file diff --git a/starter-data/starter-data-jpa/src/test/java/com/zja/dao/example/ExampleUserRepoTests.java b/starter-data/starter-data-jpa/src/test/java/com/zja/dao/example/ExampleUserRepoTests.java new file mode 100644 index 0000000..fe6cfcc --- /dev/null +++ b/starter-data/starter-data-jpa/src/test/java/com/zja/dao/example/ExampleUserRepoTests.java @@ -0,0 +1,234 @@ +package com.zja.dao.example; + +import com.zja.entitys.example.ExampleUser; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.test.annotation.Commit; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +/** + * @DataJpaTest 每次运行测试时,都会使用新的、干净的数据库,并且在测试完成后会自动回滚更改。 + *

+ * 使用了@DataJpaTest注解,可能导致了数据不准确的问题: + * 由于@DataJpaTest使用嵌入式数据库,默认情况下不会将数据写入实际的数据库,而是将其存储在内存中。这可能导致在测试中更新数据后,再次查询时获取的数据仍然是之前的值,而不是预期的更新后的值。 + *

+ * @author: zhengja + * @since: 2024/04/22 10:25 + */ +// @SpringBootTest +@DataJpaTest // 默认采用内存库:h2 +// @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) // 采用业务库:mysql等 +public class ExampleUserRepoTests { + + @Autowired + private ExampleUserRepo exampleUserRepo; + + @Test + public void testFindByLoginName() { + ExampleUser user = new ExampleUser(); + user.setLoginName("john123"); + user.setName("John Doe"); + exampleUserRepo.save(user); + + Optional result = exampleUserRepo.findByLoginName("john123"); + Assertions.assertTrue(result.isPresent()); + Assertions.assertEquals("John Doe", result.get().getName()); + } + + @Test + public void testFindNameByLoginName() { + ExampleUser user = new ExampleUser(); + user.setLoginName("jane456"); + user.setName("Jane Smith"); + exampleUserRepo.save(user); + + Optional result = exampleUserRepo.findNameByLoginName("jane456"); + Assertions.assertTrue(result.isPresent()); + Assertions.assertEquals("Jane Smith", result.get()); + } + + @Test + public void testFindByLoginNameIn() { + ExampleUser user1 = new ExampleUser(); + user1.setLoginName("user1"); + user1.setName("User 1"); + + ExampleUser user2 = new ExampleUser(); + user2.setLoginName("user2"); + user2.setName("User 2"); + + exampleUserRepo.saveAll(Arrays.asList(user1, user2)); + + List result = exampleUserRepo.findByLoginNameIn(Arrays.asList("user1", "user2")); + Assertions.assertEquals(2, result.size()); + } + + @Test + public void testFindByNameLike() { + ExampleUser user1 = new ExampleUser(); + user1.setLoginName("john123"); + user1.setName("John Doe"); + + ExampleUser user2 = new ExampleUser(); + user2.setLoginName("jane456"); + user2.setName("Jane Smith"); + + exampleUserRepo.saveAll(Arrays.asList(user1, user2)); + + List result = exampleUserRepo.findByNameLike("%John%"); + Assertions.assertEquals(1, result.size()); + Assertions.assertEquals("John Doe", result.get(0).getName()); + } + + @Test + public void testCountByName() { + ExampleUser user1 = new ExampleUser(); + user1.setLoginName("john123"); + user1.setName("John Doe"); + + ExampleUser user2 = new ExampleUser(); + user2.setLoginName("jane456"); + user2.setName("Jane Smith"); + + exampleUserRepo.saveAll(Arrays.asList(user1, user2)); + + long count = exampleUserRepo.countByName("John Doe"); + Assertions.assertEquals(1, count); + } + + @Test + public void testFindByNameWithPagination() { + ExampleUser user1 = new ExampleUser(); + user1.setLoginName("john123"); + user1.setName("John Doe"); + + ExampleUser user2 = new ExampleUser(); + user2.setLoginName("jane456"); + user2.setName("Jane Smith"); + + exampleUserRepo.saveAll(Arrays.asList(user1, user2)); + + Pageable pageable = PageRequest.of(0, 10, Sort.by(Sort.Direction.ASC, "name")); + Page pageResult = exampleUserRepo.findByName("John Doe", pageable); + + Assertions.assertEquals(1, pageResult.getTotalElements()); + Assertions.assertEquals(1, pageResult.getTotalPages()); + List users = pageResult.getContent(); + Assertions.assertEquals(1, users.size()); + Assertions.assertEquals("John Doe", users.get(0).getName()); + } + + @Test + public void testFindByKeywordOrderByAgeAscCreateTimeDesc() { + ExampleUser user1 = new ExampleUser(); + user1.setLoginName("john123"); + user1.setName("John Doe"); + + ExampleUser user2 = new ExampleUser(); + user2.setLoginName("jane456"); + user2.setName("Jane Smith"); + + exampleUserRepo.saveAll(Arrays.asList(user1, user2)); + + Pageable pageable = PageRequest.of(0, 10, Sort.by(Sort.Direction.ASC, "age").and(Sort.by(Sort.Direction.DESC, "createTime"))); + Page pageResult = exampleUserRepo.findByKeywordOrderByAgeAscCreateTimeDesc("John", pageable); + + Assertions.assertEquals(1, pageResult.getTotalElements()); + Assertions.assertEquals(1, pageResult.getTotalPages()); + List users = pageResult.getContent(); + Assertions.assertEquals(1, users.size()); + Assertions.assertEquals("John Doe", users.get(0).getName()); + } + + @Test + public void testUpdateNameByLoginName() { + ExampleUser user = new ExampleUser(); + user.setLoginName("john123"); + user.setName("John Doe"); + exampleUserRepo.save(user); + + exampleUserRepo.updateNameByLoginName("John Smith", "john123"); + + Optional result = exampleUserRepo.findByLoginName("john123"); + Assertions.assertTrue(result.isPresent()); + Assertions.assertEquals("John Smith", result.get().getName()); // todo 没解决,使用了@DataJpaTest注解,可能导致了数据不准确的问题 + } + + @Test + public void testDeleteByLoginName() { + ExampleUser user = new ExampleUser(); + user.setLoginName("john123"); + user.setName("John Doe"); + exampleUserRepo.save(user); + + exampleUserRepo.deleteByLoginName("john123"); + + Optional result = exampleUserRepo.findByLoginName("john123"); + Assertions.assertFalse(result.isPresent()); + } + + @Test + public void testDeleteNameByLoginName() { + ExampleUser user = new ExampleUser(); + user.setLoginName("john123"); + user.setName("John Doe"); + exampleUserRepo.save(user); + + exampleUserRepo.deleteNameByLoginName("john123"); + + Optional result = exampleUserRepo.findByLoginName("john123"); + Assertions.assertTrue(result.isPresent()); + Assertions.assertNull(result.get().getName()); // todo 没解决,使用了@DataJpaTest注解,可能导致了数据不准确的问题 + } + + @Test + public void testDeleteByName() { + ExampleUser user1 = new ExampleUser(); + user1.setLoginName("john123"); + user1.setName("John Doe"); + + ExampleUser user2 = new ExampleUser(); + user2.setLoginName("jane456"); + user2.setName("Jane Smith"); + + exampleUserRepo.saveAll(Arrays.asList(user1, user2)); + + long count = exampleUserRepo.deleteByName("John Doe"); + Assertions.assertEquals(1, count); + + Optional result = exampleUserRepo.findByLoginName("john123"); + Assertions.assertFalse(result.isPresent()); + } + + @Test + public void testRemoveByName() { + ExampleUser user1 = new ExampleUser(); + user1.setLoginName("john123"); + user1.setName("John Doe"); + + ExampleUser user2 = new ExampleUser(); + user2.setLoginName("jane456"); + user2.setName("Jane Smith"); + + exampleUserRepo.saveAll(Arrays.asList(user1, user2)); + + List removedUsers = exampleUserRepo.removeByName("John Doe"); + Assertions.assertEquals(1, removedUsers.size()); + Assertions.assertEquals("John Doe", removedUsers.get(0).getName()); + + Optional result = exampleUserRepo.findByLoginName("john123"); + Assertions.assertFalse(result.isPresent()); + } +}