欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring JPA自定義查詢結果的接收方式

 更新時間:2024年01月20日 10:06:27   作者:曉風殘月淡  
這篇文章主要介紹了Spring JPA自定義查詢結果的接收方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

一、標準使用方法

//構建實體類
@Getter
@Setter
@Entity
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Table(name = "user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    private Integer age;
    private String address;
}
//繼承JPA
public interface UserRepository extends JpaRepository<User,Long> {
}
//調用測試
@RunWith(SpringRunner.class)
@SpringBootTest
class UserTest {
    @Autowired
    UserRepository userRepository;
    @Test
    void testUser() {
        User newUser = User.builder()
				        .id(1L)
				        .username("zhangsan")
				        .age(18)
				        .address("北京市").build();
        User savedUser = userRepository.save(newUser);
        assertEquals("zhangsan",savedUser.getUsername());
    }
}

如圖所示,插入成功。

二、自定義查詢結果的接收

假設我們不想查詢user表中的所有字段,而只需要其中的幾個字段作為前端輸出。

當然,JPA給我們提供了自定義SQL的功能進行個性化的查詢。使用@Query就可以自定義SQL語句,編寫自定義的查詢語句了。

但是,它的使用方式分為兩種:

  • 一種是特定JPQL語言,這是通過實體對象來查詢屬性,而不用考慮對應的表名稱和字段名稱。
  • 一種是SQL語言,還是像原來一樣操作對應的表和字段。

1.那么在UserRepository 中應該怎么寫自定義查詢語句呢?

//創(chuàng)建個性化的DTO用于接收
@Value
public class UserDTO {
    Long id;
    String username;
}
//寫sql語句
public interface UserRepository extends JpaRepository<User,Long> {
    //@Query("select u from User u where u.id =?1")
    //是像這樣,還是怎么寫呢?
    UserDTO findUserDTOByID(Long id);
}
//調用
@RunWith(SpringRunner.class)
@SpringBootTest
class UserTest {
    @Autowired
    UserRepository userRepository;

    @Test
    void testUserDTO() {
        UserDTO dto = userRepository.findUserDTOByID(1L);
        assertEquals("zhangsan",dto.getUsername());
        
    }
}

可能的錯誤的查詢方式:

//1.意圖User實體自動映射某些屬性到UserDTO
public interface UserRepository extends JpaRepository<User,Long> {
    @Query("select u from User u where u.id =?1")
    UserDTO findUserDTOByID(Long id);
    //但是會報org.springframework.core.convert.ConverterNotFoundException錯誤
}
//2.意圖挑出User的某些字段會自動映射到UserDTO
public interface UserRepository extends JpaRepository<User,Long> {
    @Query("select u.id,u.username from User u where u.id =?1")
    UserDTO findUserDTOByID(Long id);
    //但是會報org.springframework.core.convert.ConverterNotFoundException錯誤
}
//3.意圖挑出User的某些字段會自動映射到UserDTO
public interface UserDTORepository extends JpaRepository<UserDTO,Long> {
    @Query("select u.id,u.username from User u where u.id =?1")
    UserDTO findByID(Long id);
    //但是這會生成一個新表
}

在上面雖然UserDTO只是User中的子集,只有它的兩個屬性,但是如果直接用UserDTO接收查詢結構,就會報這種 類型轉換錯誤。

這是因為UserRepository是實體對象User的倉庫,必須用User來接收,不能用別的對象來接收。

那么我們能不能再創(chuàng)建一個UserDTORepository來接收查詢結果呢?

這是不行的,因為UserDTORepository必須映射對應的表,才能查詢UserDTO對象。而我們當然不希望又創(chuàng)建與User相似的表。

正確的查詢方式:

//1.使用Object接收
public interface UserRepository extends JpaRepository<User,Long> {
    @Query("select u.id,u.username from User u where u.id =?1")
    Object findUserDTOByID(Long id);
    //倒是能接收到結果,但是丟失了屬性名稱,必須數(shù)組的索引訪問,不方便
}
//2.使用全限定名接收
public interface UserRepository extends JpaRepository<User,Long> {
    @Query("select new com.example.admin.ums.domain.user.UserDTO(id,username) from User u where u.id =?1")
    UserDTO findUserDTOByID(Long id);
    //能接收到結果,但是UserDTO必須有構造函數(shù),帶上所有參數(shù),也不方便
}
//3.定義接口來接收,使用的是projections接口投影機制
public interface IUser {
	//定義這些getter方法才能接收結果
    Long getId();
    String getUsername();
}
//用接口接收查詢結果
public interface UserRepository extends JpaRepository<User,Long> {
    @Query("select u.id as id ,u.username as username  from User u where u.id =?1")
    IUser findUserDTOByID(Long id);
    //能查詢到結果,但是必須用接口接收,可能不習慣
}
//4.泛型動態(tài)查詢投影
public interface UserRepository extends JpaRepository<User,Long> {
    <T> T  findById(Long id, Class<T> type);
    //只需要輸入ID和類類型就能查到結果,這個利用了方法名的查詢生成器機制,不用專門寫@Query
    //同時使用動態(tài)查詢投影,所以不用輸入很多參數(shù),方便了很多,強烈推薦
}
//5.用Map接收查詢的結果
public interface UserRepository extends JpaRepository<User,Long> {
    @Query("select u.id as id ,u.username as username, u.address as address  from User u where u.id =?1")
    Map<String,Object> findUserDTO(Long id);
    //需要寫JPQL語句,必須用as取別名,否則就沒有key值
    //優(yōu)點是不用構造DTO直接輸出給前端
    //缺點是查出來的不是對象,不方便再處理業(yè)務邏輯,若參數(shù)很多,就會很繁瑣    
}

總結

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

最新評論