溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

springboot?jpa如何實現返回結果自定義查詢

發(fā)布時間:2022-02-23 13:53:38 來源:億速云 閱讀:318 作者:iii 欄目:開發(fā)技術

這篇文章主要講解了“springboot jpa如何實現返回結果自定義查詢”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“springboot jpa如何實現返回結果自定義查詢”吧!

jpa 返回結果自定義查詢

這里自定義的實體是沒有在數據映射的實體??梢苑祷鼐酆虾瘮档闹?。

第一種方法

實體類。(這里本人使用的是idea)

@Data
public class NameOnlyDto   implements Serializable {
    private  String  firstName;
    private  String  lastName;
    private  String  sex ;
}

repository類(這里不是 使用的繼承jpa中的 的方式。而是使用的EntityManager)。代碼中有詳細的注釋。

@Repository
public class CustomEntity {
    // 實體管理器EntityManager是負責管理Entity的對象。對Entity的操作包括添加、刪除、修改和查詢,都是通過實體管理器來實現的。
    @PersistenceContext
    private EntityManager entityManager;
 
    //EntityManagerFactory
 
    @Transactional
    public List<NameOnlyDto> listNameOnlyDto(){
        String sql = "select p.last_name lastName, p.first_name firstName from PERSON p";
        // hibernate 5.2 之前
        // SQLQuery sqlQuery = entityManager.createNativeQuery(sql).unwrap(NativeQueryImpl.class);
        // hibernate 5.2 之后的 寫法
 
        // unwrap 讓JPA的Query返回Map對象 javax.persistence.Query.unwrap
        // hibernate 或jpa 中使用 AliasToBeanResultTransformer 自定義類型轉換ResultTransformer 下劃線轉駝峰
        SQLQuery sqlQuery = entityManager.createNativeQuery(sql).unwrap(NativeQueryImpl.class);
        /*Query query =
                sqlQuery.setResultTransformer(Transformers.aliasToBean(NameOnlyDto.class));
        List<NameOnlyDto> list = query.getResultList();//.list();*/
 
        Query query =
                sqlQuery.setResultTransformer(Transformers.aliasToBean(NameOnlyDto.class));
 
        List<NameOnlyDto>  list =query.getResultList();
        entityManager.clear();
        return list;
    }
}

OK。就這樣就可以了。個人測試似乎在oracle數據庫 不行??赡苁莝ql查詢結果不太一樣

第二種方法

可以在特定的場合使用。

自定義類

public class NameOnlyDtoT implements Serializable {
    private  String  firstName;
    private  String  lastName;
    // private  String  address;
    private  String  sex;
    //構造函數 特殊注意 這里返回幾個字段就要有幾個字段的構造參數 感覺不太合適的地方
    public NameOnlyDtoT(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
   /* public NameOnlyDtoT(String firstName, String lastName, String sex) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.sex = sex;
    }*/
}

這里是repository中的寫法

// 切記不能使用@query.如果使用@query 個人感覺和上面那種方法是一樣的邏輯
List<T> findByLastName(String lastname,Class<T> type);
        使用(這里注意的是NameOnlyDtoT 中字段能賦值的只能是person中 含有的字段。這是個人覺得雞肋的存在)
    public  List<NameOnlyDtoT>  testNameOnlyDtoTS(){
        List<NameOnlyDtoT>  nameOnlyDtoTS= personRepository.findByLastName("哈哈", NameOnlyDtoT.class);
      return nameOnlyDtoTS;
}

使用jpa兩張表聯查返回自定義實體

在java開發(fā)中,用Jpa框架做連表查詢時(需要返回兩張表的各自部分字段),在返回對象的過程中感覺比較棘手,一直沒有一個好的解決方案,網上也有各種版本的方法,下面的方法本人感覺最方便使用

1、創(chuàng)建一個SpringBoot空白項目,引入pom依賴

先看項目結構,為了簡化,沒有引入service層,直接使用controller調用dao層

springboot?jpa如何實現返回結果自定義查詢

pom.xml配置

        <!-- web依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--  lombok依賴 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
        </dependency>
        <!-- jpa依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!-- mysql依賴 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

2、application.yml配置文件

server:
  port: 13333
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull
    username: root
    password: 12345678
    driver-class-name: com.mysql.jdbc.Driver
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: none

3、數據庫(有兩張表user/address)

springboot?jpa如何實現返回結果自定義查詢

我們現在需要聯查user和address表,address表中的user_id是和user表中id是做關聯查詢

4、User.java 和 Address.java

springboot?jpa如何實現返回結果自定義查詢

5、UserDaoRepository.java 和 AddressDaoRepository.java

springboot?jpa如何實現返回結果自定義查詢

附上UserDaoRepository.java的代碼

package com.lss.jpa.dao;
import com.lss.jpa.entity.dto.UserAddressDto;
import com.lss.jpa.entity.po.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
import java.util.Map;
public interface UserDaoRepository extends JpaRepository<User, Integer> {
    @Query(value = "select \"title\" as common, u.id as id, u.name as name, a.id as addressId, a.address as addressName from user u, address a where u.id = a.user_id", nativeQuery = true)
    public List<UserAddressDto> findAllUserAddress();
    @Query(value = "select \"title\" as common, u.id as id, u.name as name, a.id as addressId, a.address as addressName from user u, address a where u.id = a.user_id and u.id=1", nativeQuery = true)
    public UserAddressDto findAllUserAddressById();
    @Query(value = "select \"title\" as common, u.id as id, u.name as name, a.id as addressId, a.address as addressName from user u, address a where u.id = a.user_id and u.id=1", nativeQuery = true)
    public Map<String, Object> findAllUserAddressByMap();
}

6、UserAddressDto.java代碼

package com.lss.jpa.entity.dto;
public interface UserAddressDto {
    Integer getId();
    String getName();
    String getAddressName();
    Integer getAddressId();
    String getCommon();
}

此處我們自定義了UserAdressDto來接收兩張表返回的數據,注意:此時創(chuàng)建的是一個interface,并且里面的字段是用get的形式創(chuàng)建的接收參數

7、TestController.java

package com.lss.jpa.web;
import com.lss.jpa.dao.UserDaoRepository;
import com.lss.jpa.entity.dto.UserAddressDto;
import com.lss.jpa.entity.po.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@RestController
@Slf4j
public class TestController {
    @Autowired
    private UserDaoRepository userDaoRepository;
    @GetMapping("test")
    public String test(){
        List<UserAddressDto> all = userDaoRepository.findAllUserAddress();
        all.stream().forEach(dto -> {
            log.info("result: id:{}, name:{}, addressId:{}, addressName:{}, common:{}", dto.getId(), dto.getName(), dto.getAddressId(), dto.getAddressName(), dto.getCommon());
        });
        UserAddressDto dto = userDaoRepository.findAllUserAddressById();
        log.info("result: id:{}, name:{}, addressId:{}, addressName:{}, common:{}", dto.getId(), dto.getName(), dto.getAddressId(), dto.getAddressName(), dto.getCommon());
        Map<String, Object> map = userDaoRepository.findAllUserAddressByMap();
        log.info("map:{}", map);
        List<User> userList = userDaoRepository.findAll();
        log.info("userList:{}", userList);
        return "ok";
    }
}

最后,啟動項目,調用/test接口

curl http://localhost:13333/test

看console里打印結果

Hibernate: select "title" as common, u.id as id, u.name as name, a.id as addressId, a.address as addressName from user u, address a where u.id = a.user_id
2020-02-23 13:14:33.293  INFO 2816 --- [io-13333-exec-3] com.lss.jpa.web.TestController           : result: id:1, name:zhangsan , addressId:1, addressName:beijing, common:title
2020-02-23 13:14:33.293  INFO 2816 --- [io-13333-exec-3] com.lss.jpa.web.TestController           : result: id:2, name:lisi, addressId:2, addressName:tianjin, common:title
Hibernate: select "title" as common, u.id as id, u.name as name, a.id as addressId, a.address as addressName from user u, address a where u.id = a.user_id and u.id=1
2020-02-23 13:14:33.296  INFO 2816 --- [io-13333-exec-3] com.lss.jpa.web.TestController           : result: id:1, name:zhangsan , addressId:1, addressName:beijing, common:title
Hibernate: select "title" as common, u.id as id, u.name as name, a.id as addressId, a.address as addressName from user u, address a where u.id = a.user_id and u.id=1
2020-02-23 13:14:33.299  INFO 2816 --- [io-13333-exec-3] com.lss.jpa.web.TestController           : map:org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap@72cce81
Hibernate: select user0_.id as id1_1_, user0_.name as name2_1_ from user user0_
2020-02-23 13:14:33.305  INFO 2816 --- [io-13333-exec-3] com.lss.jpa.web.TestController           : userList:[User(id=1, name=zhangsan ), User(id=2, name=lisi), User(id=3, name=wangwu), User(id=4, name=zhaoliu)]

我們可以拷到輸出的sql和聯查出來的數據結果,都被dto完美接收

特別注意,接收的dto一定要是interface,里面的參數要寫成get形式的方法體,這樣jpa在查詢到數據后,會自動映射到interface里,通過調用get的方法體相當于調用了參數值,這樣就會把數據取出來

感謝各位的閱讀,以上就是“springboot jpa如何實現返回結果自定義查詢”的內容了,經過本文的學習后,相信大家對springboot jpa如何實現返回結果自定義查詢這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI