<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
這裡自定義的實體是沒有在資料對映的實體。可以返回聚合函數的值。(個人理解可以。。。。。。)
實體類。(這裡本人使用的是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資料庫 不行。可能是sql查詢結果不太一樣
可以在特定的場合使用。
自定義類
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; }
在java開發中,用Jpa框架做連表查詢時(需要返回兩張表的各自部分欄位),在返回物件的過程中感覺比較棘手,一直沒有一個好的解決方案,網上也有各種版本的方法,下面的方法本人感覺最方便使用
先看專案結構,為了簡化,沒有引入service層,直接使用controller呼叫dao層
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>
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
我們現在需要聯查user和address表,address表中的user_id是和user表中id是做關聯查詢
附上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(); }
package com.lss.jpa.entity.dto; public interface UserAddressDto { Integer getId(); String getName(); String getAddressName(); Integer getAddressId(); String getCommon(); }
此處我們自定義了UserAdressDto來接收兩張表返回的資料,注意:此時建立的是一個interface,並且裡面的欄位是用get的形式建立的接收引數
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的方法體相當於呼叫了引數值,這樣就會把資料取出來
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45