JPA二:FindBy和JPQL
生活随笔
收集整理的這篇文章主要介紹了
JPA二:FindBy和JPQL
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
文章目錄
- 1 環(huán)境搭建
- 2 Find By
- 2 JPQL
1 環(huán)境搭建
參考鏈接:SpringBoot二:整合其他框架
SQL腳本
-- Boolean類型在mysql中用tinyint(1)表示,1 true, 0 false。 CREATE TABLE `t_users` (`id` int NOT NULL AUTO_INCREMENT COMMENT '用戶id',`name` varchar(45) NOT NULL COMMENT '用戶名',`age` int DEFAULT NULL COMMENT '年齡',`address` varchar(45) DEFAULT NULL COMMENT '地址',`phone` varchar(11) DEFAULT NULL COMMENT '電話',`active` tinyint(1) DEFAULT NULL COMMENT '用戶是否激活',PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;INSERT INTO `t_users` VALUES (1,'ZHANGSAN',18,'北京','18362610001',1), (2,'李四',25,'上海','18362610002',0), (3,'王五',30,'洛陽','18362610003',1), (4,'趙六',28,'蘇州','18362610004',1), (5,'趙玉',20,'南京','18362610005',1), (6,'zhangsan',15,'西安','18362610006',1), (7,'張三',20,'南京','18362610007',1);SpringBoot 集成 JPA
-
項目結(jié)構(gòu)如下
創(chuàng)建普通maven工程,導(dǎo)入依賴
<dependencies><!-- spring-boot 測試類依賴 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><version>2.5.6</version></dependency><!-- jpa 依賴--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId><version>2.6.0</version></dependency><!-- mysql 依賴 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.22</version></dependency><!-- lombok 依賴 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.16</version></dependency> </dependencies>配置文件 application.yml
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: rooturl: jdbc:mysql://192.168.181.160:3306/test?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=falsejpa:show-sql: true實體類
package cn.entity; import lombok.Data; import javax.persistence.*;@Entity @Table(name = "t_users") @Data public class UserEntity {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "id")private Integer userId;@Column(name = "name")private String userName;@Column(name = "age")private Integer userAge;@Column(name = "address")private String userAddress;@Column(name = "phone")private String userPhone;@Column(name = "active")private Boolean userActive; // 用戶是否激活 }持久層
package cn.repository; import cn.entity.UserEntity; import org.springframework.data.jpa.repository.JpaRepository;public interface UserRepository extends JpaRepository<UserEntity, Integer> { }啟動類
package cn; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication public class App {public static void main(String[] args) {SpringApplication.run(App.class, args);} }測試
package test;import cn.App; import cn.entity.UserEntity; import cn.repository.UserRepository; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest;import javax.annotation.Resource; import javax.transaction.Transactional; import java.util.List;@SpringBootTest(classes = App.class) public class TestEnv {@Resourceprivate UserRepository userRepository;@Test@Transactional // no Session 異常加事務(wù)注解public void test1() {UserEntity usersEntity = userRepository.getById(1);System.out.println(usersEntity);// UserEntity(userId=1, userName=ZHANGSAN, userAge=18, userAddress=北京, userPhone=18362610001, userActive=true)}@Testpublic void test2() {List<UserEntity> list = userRepository.findAll();list.forEach(user -> System.out.println(user));/*** UserEntity(userId=1, userName=ZHANGSAN, userAge=18, userAddress=北京, userPhone=18362610001, userActive=true)* UserEntity(userId=2, userName=李四, userAge=25, userAddress=上海, userPhone=18362610002, userActive=false)* UserEntity(userId=3, userName=王五, userAge=30, userAddress=洛陽, userPhone=18362610003, userActive=true)* UserEntity(userId=4, userName=趙六, userAge=28, userAddress=蘇州, userPhone=18362610004, userActive=true)* UserEntity(userId=5, userName=趙玉, userAge=20, userAddress=南京, userPhone=18362610005, userActive=true)* UserEntity(userId=6, userName=zhangsan, userAge=15, userAddress=西安, userPhone=18362610006, userActive=true)* UserEntity(userId=7, userName=張三, userAge=20, userAddress=南京, userPhone=18362610007, userActive=true)*/} }2 Find By
Spring Data JPA 命名規(guī)則:查詢方法以findBy開頭,涉及條件查詢時,條件的屬性用條件關(guān)鍵字連接【注:條件屬性首字母需大寫】。框架在進(jìn)行方法名解析時,會先把方法名多余的前綴截取掉,然后對剩下部分進(jìn)行解析。
特別說明
findBy 語法總結(jié)
| And | findByNameAndPwd | where name= ? and pwd =? |
| Or | findByNameOrSex | where name= ? or sex=? |
| Is Equals | findByIdIs findByIdEquals | where id= ? |
| Between | findByIdBetween | where id between ? and ? |
| LessThan | findByIdLessThan | where id < ? |
| LessThanEqual | findByIdLessThanEqual | where id <= ? |
| GreaterThan | findByIdGreaterThan | where id > ? |
| GreaterThanEqual | findByIdGreaterThanEqual | where id > = ? |
| After | findByIdAfter | where id > ? |
| Before | findByIdBefore | where id < ? |
| IsNull | findByNameIsNull | where name is null |
| IsNotNull NotNull | findByNameNotNull | where name is not null |
| Like | findByNameLike | where name like ? |
| NotLike | findByNameNotLike | where name not like ? |
| StartingWith | findByNameStartingWith | where name like ‘?%’ |
| EndingWith | findByNameEndingWith | where name like ‘%?’ |
| Containing | findByNameContaining | where name like ‘%?%’ |
| OrderBy | findByIdOrderByCountDesc | where id=? order by count desc |
| Not | findByNameNot | where name <> ? |
| In | findByIdIn(Collection<?> c) | where id in (?) |
| NotIn | findByNameNotIn(Collection<?> c) | where name not in (?) |
| True | findByActiveTrue | where active = true |
| False | findByActiveFalse | where active = false |
| IgnoreCase | findByNameIgnoreCase | where UPPER(name)=UPPER(?) |
- 參考鏈接:spring data jpa 命名規(guī)則
編碼&測試
在上文搭建環(huán)境的基礎(chǔ)上,修改 UserRepository 接口,添加如下方法
package cn.repository;import cn.entity.UserEntity; import org.springframework.data.jpa.repository.JpaRepository;import java.util.List;public interface UserRepository extends JpaRepository<UserEntity, Integer> {UserEntity findByUserName(String username);/*** and (參數(shù)是對象)* * 下面寫法不對,直接報如下錯誤* java.lang.IllegalStateException:* Method public abstract cn.entity.UserEntity cn.repository.UserRepository.findByUserNameAndUserPhone(cn.entity.UserEntity)* expects at least 2 arguments but only found 1. This leaves an operator of type SIMPLE_PROPERTY for property userPhone unbound.* * 就是 findByUserNameAndUserPhone() 方法需要2個參數(shù),但只發(fā)現(xiàn)1個* * ☆待解決:參數(shù)是對象怎么辦?! ==> 若是一個類幾十個屬性,根據(jù)七八個條件查詢,這是函數(shù)名就很長了 findByXXX,難不成形參還要單獨寫七八個?!*/ // UserEntity findByUserNameAndUserPhone(@Param("user") UserEntity user);// orUserEntity findByUserNameOrUserPhone(String userName, String userPhone);// is / equalsUserEntity findByUserIdIs(Integer id);UserEntity findByUserIdEquals(Integer id);// betweenList<UserEntity> findByUserAgeBetween(Integer minAge, Integer maxAge);// lessThanList<UserEntity> findByUserAgeLessThan(Integer maxAge);// greaterThanEqualList<UserEntity> findByUserAgeGreaterThanEqual(Integer minAge);// after / beforeList<UserEntity> findByUserAgeAfter(Integer minAge);List<UserEntity> findByUserAgeBefore(Integer maxAge);// like / containing (like語句中的參數(shù)需要自己手寫%,Containing不用再寫%)List<UserEntity> findByUserNameLike(String name);List<UserEntity> findByUserNameContaining(String name);// order byList<UserEntity> findByUserNameOrderByUserAgeDesc(String username);List<UserEntity> findByOrderByUserAgeDesc();// inList<UserEntity> findByUserIdIn(List<Integer> ids);// false (查找未激活用戶)List<UserEntity> findByUserActiveFalse();// ignoreCase (忽略大小寫)List<UserEntity> findByUserNameIgnoreCase(String username); }測試
package test;import cn.App; import cn.entity.UserEntity; import cn.repository.UserRepository; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest;import javax.annotation.Resource; import java.util.Arrays; import java.util.List;@SpringBootTest(classes = App.class) public class TestFindBy {@Resourceprivate UserRepository userRepository;/*** 查詢所有* (主要是其他方法的測試結(jié)果與之對比,確定實際結(jié)果是否與預(yù)期一致)*/@Testpublic void testFindAll() {List<UserEntity> list = userRepository.findAll();list.forEach(user -> System.out.println(user));/*** UserEntity(userId=1, userName=ZHANGSAN, userAge=18, userAddress=北京, userPhone=18362610001, userActive=true)* UserEntity(userId=2, userName=李四, userAge=25, userAddress=上海, userPhone=18362610002, userActive=false)* UserEntity(userId=3, userName=王五, userAge=30, userAddress=洛陽, userPhone=18362610003, userActive=true)* UserEntity(userId=4, userName=趙六, userAge=28, userAddress=蘇州, userPhone=18362610004, userActive=true)* UserEntity(userId=5, userName=趙玉, userAge=20, userAddress=南京, userPhone=18362610005, userActive=true)* UserEntity(userId=6, userName=zhangsan, userAge=15, userAddress=西安, userPhone=18362610006, userActive=true)* UserEntity(userId=7, userName=張三, userAge=20, userAddress=南京, userPhone=18362610007, userActive=true)*/}/*** findBy 普通測試*/@Testpublic void test() {UserEntity userEntity = userRepository.findByUserName("張三");System.out.println(userEntity);// UserEntity(userId=7, userName=張三, userAge=20, userAddress=南京, userPhone=2323132, userActive=true)}/*** and 測試* (參數(shù)為對象時有bug,待解決;若是參數(shù)分開寫,同下面 or 測試)*/@Testpublic void testAnd() {}/*** or 測試*/@Testpublic void testOr() {UserEntity user1 = userRepository.findByUserNameOrUserPhone("張三", null);System.out.println("user1 = " + user1);UserEntity user2 = userRepository.findByUserNameOrUserPhone(null, "18362610007");System.out.println("user2 = " + user2);/*** user1 = UserEntity(userId=7, userName=張三, userAge=20, userAddress=南京, userPhone=18362610007, userActive=true)* user2 = UserEntity(userId=7, userName=張三, userAge=20, userAddress=南京, userPhone=18362610007, userActive=true)*/}/*** is / equals*/@Testpublic void testIsAndEquals() {UserEntity user1 = userRepository.findByUserIdIs(1);System.out.println("user1 = " + user1);UserEntity user2 = userRepository.findByUserIdEquals(1);System.out.println("user2 = " + user2);/*** user1 = UserEntity(userId=1, userName=ZHANGSAN, userAge=18, userAddress=北京, userPhone=18362610001, userActive=true)* user2 = UserEntity(userId=1, userName=ZHANGSAN, userAge=18, userAddress=北京, userPhone=18362610001, userActive=true)*/}/*** between*/@Testpublic void testBetween() {List<UserEntity> list = userRepository.findByUserAgeBetween(15, 20);list.forEach(user -> System.out.println(user));/*** UserEntity(userId=1, userName=ZHANGSAN, userAge=18, userAddress=北京, userPhone=18362610001, userActive=true)* UserEntity(userId=5, userName=趙玉, userAge=20, userAddress=南京, userPhone=18362610005, userActive=true)* UserEntity(userId=6, userName=zhangsan, userAge=15, userAddress=西安, userPhone=18362610006, userActive=true)* UserEntity(userId=7, userName=張三, userAge=20, userAddress=南京, userPhone=18362610007, userActive=true)*/}/*** lessThan* greaterThanEqual*/@Testpublic void testThan() {List<UserEntity> list1 = userRepository.findByUserAgeLessThan(20);list1.forEach(user -> System.out.println(user));/*** UserEntity(userId=1, userName=ZHANGSAN, userAge=18, userAddress=北京, userPhone=18362610001, userActive=true)* UserEntity(userId=6, userName=zhangsan, userAge=15, userAddress=西安, userPhone=18362610006, userActive=true)*/List<UserEntity> list2 = userRepository.findByUserAgeGreaterThanEqual(20);list2.forEach(user -> System.out.println(user));/*** UserEntity(userId=2, userName=李四, userAge=25, userAddress=上海, userPhone=18362610002, userActive=false)* UserEntity(userId=3, userName=王五, userAge=30, userAddress=洛陽, userPhone=18362610003, userActive=true)* UserEntity(userId=4, userName=趙六, userAge=28, userAddress=蘇州, userPhone=18362610004, userActive=true)* UserEntity(userId=5, userName=趙玉, userAge=20, userAddress=南京, userPhone=18362610005, userActive=true)* UserEntity(userId=7, userName=張三, userAge=20, userAddress=南京, userPhone=18362610007, userActive=true)*/}/*** after / before*/@Testpublic void testBeforeAndAfter() {List<UserEntity> list1 = userRepository.findByUserAgeAfter(20);list1.forEach(user -> System.out.println(user));System.out.println("---------------------- 分割線 ----------------------");List<UserEntity> list2 = userRepository.findByUserAgeBefore(20);list2.forEach(user -> System.out.println(user));/*** UserEntity(userId=2, userName=李四, userAge=25, userAddress=上海, userPhone=18362610002, userActive=false)* UserEntity(userId=3, userName=王五, userAge=30, userAddress=洛陽, userPhone=18362610003, userActive=true)* UserEntity(userId=4, userName=趙六, userAge=28, userAddress=蘇州, userPhone=18362610004, userActive=true)* ---------------------- 分割線 ----------------------* UserEntity(userId=1, userName=ZHANGSAN, userAge=18, userAddress=北京, userPhone=18362610001, userActive=true)* UserEntity(userId=6, userName=zhangsan, userAge=15, userAddress=西安, userPhone=18362610006, userActive=true)*/}/*** like / containing* like語句中的參數(shù)需要自己手寫%,Containing不用再寫%*/@Testpublic void testLikeAndContaining() {List<UserEntity> list1 = userRepository.findByUserNameLike("%趙%");list1.forEach(user -> System.out.println(user));System.out.println("---------------------- 分割線 ----------------------");List<UserEntity> list2 = userRepository.findByUserNameContaining("趙");list2.forEach(user -> System.out.println(user));/*** UserEntity(userId=4, userName=趙六, userAge=28, userAddress=蘇州, userPhone=18362610004, userActive=true)* UserEntity(userId=5, userName=趙玉, userAge=20, userAddress=南京, userPhone=18362610005, userActive=true)* ---------------------- 分割線 ----------------------* UserEntity(userId=4, userName=趙六, userAge=28, userAddress=蘇州, userPhone=18362610004, userActive=true)* UserEntity(userId=5, userName=趙玉, userAge=20, userAddress=南京, userPhone=18362610005, userActive=true)*/}/*** order by*/@Testpublic void testOrderBy() {List<UserEntity> list1 = userRepository.findByOrderByUserAgeDesc();list1.forEach(user -> System.out.println(user));/*** UserEntity(userId=3, userName=王五, userAge=30, userAddress=洛陽, userPhone=18362610003, userActive=true)* UserEntity(userId=4, userName=趙六, userAge=28, userAddress=蘇州, userPhone=18362610004, userActive=true)* UserEntity(userId=2, userName=李四, userAge=25, userAddress=上海, userPhone=18362610002, userActive=false)* UserEntity(userId=5, userName=趙玉, userAge=20, userAddress=南京, userPhone=18362610005, userActive=true)* UserEntity(userId=7, userName=張三, userAge=20, userAddress=南京, userPhone=18362610007, userActive=true)* UserEntity(userId=1, userName=ZHANGSAN, userAge=18, userAddress=北京, userPhone=18362610001, userActive=true)* UserEntity(userId=6, userName=zhangsan, userAge=15, userAddress=西安, userPhone=18362610006, userActive=true)*/}/*** in*/@Testpublic void testIn() {List<Integer> idList = Arrays.asList(1, 3, 7);List<UserEntity> list = userRepository.findByUserIdIn(idList);list.forEach(user -> System.out.println(user));/*** UserEntity(userId=1, userName=ZHANGSAN, userAge=18, userAddress=北京, userPhone=18362610001, userActive=true)* UserEntity(userId=3, userName=王五, userAge=30, userAddress=洛陽, userPhone=18362610003, userActive=true)* UserEntity(userId=7, userName=張三, userAge=20, userAddress=南京, userPhone=18362610007, userActive=true)*/}/*** false* 需求:查找未激活用戶*/@Testpublic void testFalse() {List<UserEntity> list = userRepository.findByUserActiveFalse();list.forEach(user -> System.out.println(user));// UserEntity(userId=2, userName=李四, userAge=25, userAddress=上海, userPhone=18362610002, userActive=false)}/*** ignoreCase (忽略大小寫)*/@Testpublic void testIgnoreCase() {List<UserEntity> list = userRepository.findByUserNameIgnoreCase("zhangsan");list.forEach(user -> System.out.println(user));/*** UserEntity(userId=1, userName=ZHANGSAN, userAge=18, userAddress=北京, userPhone=18362610001, userActive=true)* UserEntity(userId=6, userName=zhangsan, userAge=15, userAddress=西安, userPhone=18362610006, userActive=true)*/} }2 JPQL
使用Spring Data JPA提供的查詢方法(即 find by 語法)已經(jīng)可以解決大部分的應(yīng)用場景,但是對于某些業(yè)務(wù)來說,我們還需要靈活的構(gòu)造查詢條件,這時就可以使用 @Query 注解,結(jié)合JPQL的語句方式完成查詢。
JPQL 語法
注意事項
編碼&測試
- 基于上文的項目架構(gòu),在 UserRepository 接口中添加 JPQL 查詢方法的代碼
持久層
package cn.repository;import cn.entity.UserEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param;import javax.transaction.Transactional; import java.util.List;public interface UserRepository extends JpaRepository<UserEntity, Integer> {/*-------------------------------- 使用JPQL實現(xiàn)基本的增刪改查 --------------------------------*//*** nativeQuery = true時使用SQL語言,否則使用JPQL(默認(rèn)nativeQuery = false)* 且JPQL不支持insert操作,因此要使用 nativeQuery=true 使用原生SQL進(jìn)行插入操作* <p>* 增刪改要用@Modifying和@Transactional注解* 因為@Modifying只是聲明了這是一個改動操作(包含增刪改),但沒有修改這個方法的事務(wù)等級,* 故還需@Transactional注解,該注解本質(zhì)上是聲明了@Transactional(readOnly=false)* 因此一般情況下,@Modifying和@Transactional配套使用* <p>* 參數(shù)* 普通參數(shù):* 法1:使用 ?x ,x代表下標(biāo)從1開始,參數(shù)有序,x的序號與形參對應(yīng)* 法2:使用 id=:id 和 @Param("id")注解,參數(shù)無序,因為有@Param注解確定* 對象參數(shù):* 如 Integer addUser(@Param("user") UserEntity user);* 使用時為 :#{#user.userName}、:#{#user.userAge}等*/// 增@Modifying@Transactional@Query(value = "insert into t_users(name,age,address,phone,active) values(?1,?2,?3,?4,?5)", nativeQuery = true)Integer addUser(String name, Integer age, String address, String phone, Boolean active);@Modifying@Transactional@Query(value = "insert into t_users(name,age,address,phone,active) " +"values(:#{#user.userName}, :#{#user.userAge}, :#{#user.userAddress}, " +":#{#user.userPhone}, :#{#user.userActive})", nativeQuery = true)Integer addUser(@Param("user") UserEntity user);// 刪@Modifying@Transactional@Query("delete from UserEntity where id=:id")Integer deleteUser(@Param("id") Integer id);// 改@Modifying@Transactional@Query("update UserEntity set userPhone=?2 where userId=?1")Integer updatePhone(Integer id, String newPhone);/*** 查* <p>* 使用JPQL語法,不能寫"select * ",要用別名。* 把UserEntity實體類取別名為u,再"select u",等價于SQL中的"select *"*/@Query("from UserEntity where id=?1")UserEntity findOneUser(Integer id);@Query("select u from UserEntity u where name=:#{#user.userName} and phone=:#{#user.userPhone}")UserEntity findOneUser(@Param("user") UserEntity user);@Query("from UserEntity")List<UserEntity> findAllUser(); }測試
package test;import cn.App; import cn.entity.UserEntity; import cn.repository.UserRepository; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest;import javax.annotation.Resource; import java.util.List;@SpringBootTest(classes = App.class) public class TestJPQL {@Resourceprivate UserRepository userRepository;/*** 增*/@Testpublic void testAdd() {// 法一:普通插入Integer flag1 = userRepository.addUser("test-1", 18, "洛陽", "18362610100", true);System.out.println("flag1 = " + flag1); // flag1 = 1// 法二:對象插入UserEntity paraUser = new UserEntity();paraUser.setUserName("test-2");paraUser.setUserAge(20);paraUser.setUserAddress("鄭州");paraUser.setUserPhone("18362610101");paraUser.setUserActive(false);Integer flag2 = userRepository.addUser(paraUser);System.out.println("flag2 = " + flag2); // flag2 = 1}/*** 刪*/@Testpublic void testDetele() {Integer flag = userRepository.deleteUser(9);System.out.println("flag = " + flag);}/*** 改*/@Testpublic void testUpdate() {Integer flag = userRepository.updatePhone(1, "18362611111");System.out.println("flag = " + flag);}/*** 查*/@Testpublic void testFind() {// 查詢單條數(shù)據(jù)(法一:普通形參)UserEntity user1 = userRepository.findOneUser(1);System.out.println(user1);// UserEntity(userId=1, userName=ZHANGSAN, userAge=18, userAddress=北京, userPhone=18362610001, userActive=true)// 查詢單條數(shù)據(jù)(法二:對象形參)UserEntity paraUser = new UserEntity();paraUser.setUserName("zhangsan");paraUser.setUserPhone("18362610006");UserEntity user2 = userRepository.findOneUser(paraUser);System.out.println(user2);// UserEntity(userId=6, userName=zhangsan, userAge=15, userAddress=西安, userPhone=18362610006, userActive=true)// 查詢所有List<UserEntity> list = userRepository.findAllUser();list.forEach(u -> System.out.println(u));/*** UserEntity(userId=1, userName=ZHANGSAN, userAge=18, userAddress=北京, userPhone=18362610001, userActive=true)* UserEntity(userId=2, userName=李四, userAge=25, userAddress=上海, userPhone=18362610002, userActive=false)* UserEntity(userId=3, userName=王五, userAge=30, userAddress=洛陽, userPhone=18362610003, userActive=true)* UserEntity(userId=4, userName=趙六, userAge=28, userAddress=蘇州, userPhone=18362610004, userActive=true)* UserEntity(userId=5, userName=趙玉, userAge=20, userAddress=南京, userPhone=18362610005, userActive=true)* UserEntity(userId=6, userName=zhangsan, userAge=15, userAddress=西安, userPhone=18362610006, userActive=true)* UserEntity(userId=7, userName=張三, userAge=20, userAddress=南京, userPhone=18362610007, userActive=true)*/} }- 源碼鏈接 blogs-jpa
總結(jié)
以上是生活随笔為你收集整理的JPA二:FindBy和JPQL的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C语言代码风格
- 下一篇: 教你竖屏视频上下黑边添加图片的剪辑技巧