成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術(shù)文章
文章詳情頁

spring data jpa 查詢自定義字段,轉(zhuǎn)換為自定義實體方式

瀏覽:3日期:2023-07-11 13:56:55

目標(biāo):查詢數(shù)據(jù)庫中的字段,然后轉(zhuǎn)換成 JSON 格式的數(shù)據(jù),返回前臺。

環(huán)境:idea 2016.3.4, jdk 1.8, mysql 5.6, spring-boot 1.5.2

背景:首先建立 entity 映射數(shù)據(jù)庫(非專業(yè) java 不知道這怎么說)

@Entity@Table(name = 'user')public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String userName; // 賬號 private String password; // 密碼 // getter setter 方法略過}

然后建立與之對應(yīng)的 model

public class UserModel implements Serializable { // 一些屬性}

這里我們分情況討論

首先第一種情況:

查詢的字段與表中的字段全部對應(yīng)(就是查表里所有的字段,但是使用 Model 作為接收對象)

這種情況比較簡單,調(diào)用 Repository 提供的方法,返回一個 entity , 然后將 entity 的屬性復(fù)制到 model 中。像這樣

UserModel user = new UserModel();User userEntity = new User();// 一個工具類,具體使用方法請百度BeanUtils.copyProperties(user, userEntity);第二種情況:只查詢指定的幾個字段

現(xiàn)在我有張表,有字段如下:

@Entity@Table(name = 'user_info')public class UserInfo { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name = '用戶'; // 昵稱 private String signature; // 個性簽名 private String gender = '未知'; // 性別 private String description; // 個人說明 private String avatar; // 頭像 private Long role;// 權(quán)限 private Boolean disable; // 是否凍結(jié) private Date createTime; // 創(chuàng)建時間 private Boolean isDelete; // 是否刪除 private Long userId; // 用戶 Id // ...}

但是我只需要查詢指定的幾個字段,然后轉(zhuǎn)換成 JSON,返回給前臺,咋辦呢?

第一種方法:使用 model 查詢時轉(zhuǎn)化

首先建立一個 model ,寫上自己想要查詢的字段,然后寫上構(gòu)造函數(shù),這步很重要,因為spring jpa 轉(zhuǎn)化時會調(diào)用這個構(gòu)造方法

public class MyModel implements Serializable { private String userName; private String name; private String gender; private String description; public MyModel() {}; public MyModel(String userName, String name, String gender, String description) {this.userName = userName;this.name = name;this.gender = gender;this.description = description; }}

然后在 dao 類中寫查詢方法

@Query(value = 'select new pers.zhuch.model.MyModel(u.userName, ui.name, ui.gender, ui.description) from UserInfo ui, User u where u.id = ui.userId')public List<MyModel> getAllRecord();

直接在查詢語句中 new model 框架底層會調(diào)用它,然后返回這個對象(這里我寫了完整的類路徑,不寫的時候它報錯說找不到類型什么的)

然后就可以獲得只有指定字段的 model 了。然后就把它轉(zhuǎn)成 JSON 格式就 O 了。

第二種方法:在service 里邊轉(zhuǎn)換成 JSON

原理其實和第一種方法差不多,只是處理結(jié)果的方式不太一樣,只是這種方法我們就不在 hql 中 new Model 了,直接寫查詢方法

@Query(value = 'select new map(u.userName, ui.name, ui.gender, ui.description) from UserInfo ui, User u where u.id = ui.userId')public List<Map<String, Object>> getCustomField();

直接new map(這里得是小寫,不知道大寫有木有問題,反正沒試,編譯器提示是要小寫的)

然后返回的結(jié)果是這樣的

[ {'0': 'admin', '1': '你猜', '2': '男', '3': '一段描述' }, {'0': 'abc', '1': '你猜人家', '2': '女', '3': '沒事先掛了' }]

然后在 service 層里直接封裝成 JSON 對象,返回

List<JsonObject> list = new ArrayList();for(Map map : result) { JsonObject j = new JsonObject(); j.addProperty(attrName, val); ... list.add(j);}gson.toJson(list);

還有一種返回結(jié)果,這樣寫:

@Query(value = 'select u.userName, ui.name, ui.gender, ui.description from UserInfo ui, User u where u.id = ui.userId')public List<Object> getCustomField();

返回結(jié)果是這樣的格式:

[ ['admin', '你猜', '男', '一段描述' ], ['abc', '你猜人家', '女', '沒事先掛了' ]]

返回的是數(shù)組,也一樣可以通過上面的方法轉(zhuǎn)成 json ,這里我的程序中出現(xiàn)了一點點 BUG,就是空值的字段不會在數(shù)組中,不知道為什么。

這種方法必須明確的知道查詢了哪些字段,靈活性比較差,雖然它解決了手頭的問題。還有就是版本的不同,有可能會出現(xiàn)丟失空字段的情況,我個人特別的不喜歡這樣的方法,萬一我實體幾十個字段,寫著寫著忘了寫到哪了,就 over 了

第三種方法:返回一個便于轉(zhuǎn)換成 json 格式的 list

其實和上面很相似,都是 dao 層返回一個 List < Map < String, Object >>,但是上面的結(jié)果集返回的 Map 的 key 只是列的下標(biāo),這種方式稍微理想一點點,就是 Map 的 key 就是查詢的列名。

但是這種方式需要實現(xiàn)自定義 Repository( 這里不詳細(xì)介紹,請自行百度 ),并且只是 jpa 集成 hibenate 的時候可以使用。

public List getCustomEntity() { String sql = 'select t.id, t.name, t.gender, t.is_delete, t.create_time, t.description from t_entity t'; Query query = em.createNativeQuery(sql); // Query 接口是 spring-data-jpa 的接口,而 SQLQuery 接口是 hibenate 的接口,這里的做法就是先轉(zhuǎn)成 hibenate 的查詢接口對象,然后設(shè)置結(jié)果轉(zhuǎn)換器 query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); return query.getResultList();}

這種方法返回的就是比較標(biāo)準(zhǔn)的 JSON 格式的 java 對象了,只需要用 jackson 或者 Gson 轉(zhuǎn)一下就是標(biāo)準(zhǔn)的 json 了

[ {attr: val,... }, {attr: val,... },]

這種方式其實已經(jīng)比較理想了,因為直接就能返回到前臺,但是有時候,結(jié)果不是一條 sql 能夠解決的,得兩條或者以上的 sql 來解決一個復(fù)雜的查詢需求,這個過程中,結(jié)果比較需要轉(zhuǎn)換成 pojo,以便于組裝操作。

第四種方案:dao 中直接轉(zhuǎn)成 pojo 返回

這個方案還是依賴于 hibenate,有點操蛋,但是更明確一些。

public List getCustomEntity() { String sql = 'select t.id, t.name, t.gender, t.is_delete as isEnable, t.create_time as createTime, t.description from t_entity t'; Query query = em.createNativeQuery(sql); query.unwrap(SQLQuery.class) // 這里是設(shè)置字段的數(shù)據(jù)類型,有幾點注意,首先這里的字段名要和目標(biāo)實體的字段名相同,然后 sql 語句中的名稱(別名)得與實體的相同 .addScalar('id', StandardBasicTypes.LONG) .addScalar('name', StandardBasicTypes.STRING) .addScalar('gender', StandardBasicTypes.STRING) .addScalar('isEnable', StandardBasicTypes.BOOLEAN) .addScalar('createTime', StandardBasicTypes.STRING) .addScalar('description', StandardBasicTypes.STRING) .setResultTransformer(Transformers.aliasToBean(EntityModel.class)); return query.getResultList();}

這次返回的就是 List 了。這里要注意的是 StandardBasicTypes這個常量類,在一些舊版本中,是 Hibenate 類,具體哪個包我不知道,我這個版本中是換成了前面的那個常量類

繼承jpa Repository 寫自定義方法查詢

今天在寫jpa查詢的時候,遇到了添加自定義方法,項目啟動報錯原因,現(xiàn)總結(jié)如下:

首先定義實體類

@Entity@Table(name = 'user')Class User{ @Id @GeneratedValue int id; @Column String age; @Column String school; @Column String userName; set,get方法 (省略)}public interface UserRepository extends JpaRepository<User, Long> { List<User> findByUsernameLike(String username); List<User> aaa();}

啟動項目時,項目報錯提示信息為:

org.springframework.data.mapping.PropertyReferenceException: No property aaa found for type com.fpi.safety.common.entity.po.User

再將List<User> aaa();方法去掉后,項目又可以正常啟動運(yùn)行

是什么原因呢?

經(jīng)查找,原來是繼承jpa,必須滿足一些規(guī)則,規(guī)則如下

spring data jpa 查詢自定義字段,轉(zhuǎn)換為自定義實體方式

spring data jpa 查詢自定義字段,轉(zhuǎn)換為自定義實體方式

Spring Data JPA框架在進(jìn)行方法名解析時,會先把方法名多余的前綴截取掉,比如find,findBy,read,readBy,get,getBy,然后對剩下的部分進(jìn)行解析。

假如創(chuàng)建如下的查詢:findByUserName(),框架在解析該方法時,首先剔除findBy,然后對剩下的屬性進(jìn)行解析,假設(shè)查詢實體為User

1:先判斷userName(根據(jù)POJO規(guī)范,首字母變?yōu)樾懀┦欠駷椴樵儗嶓w的一個屬性,如果是,則表示根據(jù)該屬性進(jìn)行查詢;如果沒有該屬性,繼續(xù)第二步;

2:從右往左截取第一個大寫字母開頭的字符串此處是Name),然后檢查剩下的字符串是否為查詢實體的一個屬性,如果是,則表示根據(jù)該屬性進(jìn)行查詢;如果沒有該屬性,則重復(fù)第二步,繼續(xù)從右往左截取;最后假設(shè)用戶為查詢實體的一個屬性;

3:接著處理剩下部分(UserName),先判斷用戶所對應(yīng)的類型是否有userName屬性,如果有,則表示該方法最終是根據(jù)“User.userName”的取值進(jìn)行查詢;否則繼續(xù)按照步驟2的規(guī)則從右往左截取,最終表示根據(jù)“User.userName”的值進(jìn)行查詢。

4:可能會存在一種特殊情況,比如User包含一個的屬性,也有一個userNameChange屬性,此時會存在混合??梢悦鞔_在屬性之間加上“_”以顯式表達(dá)意思,比如“findByUser_NameChange )“或者”findByUserName_Change()“

從上面,我們可以得知,jap在解析是,aaa在user類中是沒有屬性的,所以報錯No property aaa found.

如果我們想要使用jap框架,又不想再多增加一個自定義類,則必須符合其命名規(guī)則

如果,你記不住jpa的規(guī)則也沒關(guān)系,你可以自己再多寫一個類來實現(xiàn)自定義查詢方法

如下:

1. 自定義一個接口,該接口用來聲明自己額外定義的查詢。

public interface UseerRepositoryTwo { public List<User> searchUser(String name, int id);}

2. 創(chuàng)建一個接口,該接口 extends JpaRepository 或者 CurdRepository, 以及上面自己定義的接口 UseerRepositoryTwo

public interface UserRepositoryTwoService extends CrudRepository<LogDTO, Integer>, CustomizedLogRepository {}

3. 實現(xiàn)UserRepositoryTwoService

注意此處的類名,必須以 2 中創(chuàng)建的接口的名字UserRepositoryTwoService,后面加上 Impl 來聲明,而不是寫成 UseerRepositoryTwoImpl

public class UserRepositoryTwoServiceImpl implements UserRepositoryTwoService { @Autowired @PersistenceContext private EntityManager entityManager; @Override public List<User> searchLogs(int Id, String name) {...... }}

自己在寫自定義實現(xiàn)即可

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: Spring
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
中文字幕永久在线不卡| 精品日韩99亚洲| 日韩欧美电影一区| 美女久久久精品| 性刺激综合网| 亚洲乱码国产乱码精品精可以看| 99国产精品视频免费观看| 欧美亚洲国产一区在线观看网站| 夜夜亚洲天天久久| 亚洲欧洲三级| 亚洲欧美综合色| 欧美视频一区| 国产精品看片你懂得| 91在线精品秘密一区二区| 日韩欧美国产一区二区在线播放| 激情成人综合网| 在线观看日韩精品| 久草中文综合在线| 欧美日韩一级片网站| 极品少妇一区二区三区精品视频| 欧美写真视频网站| 激情综合五月天| 91精品国产aⅴ一区二区| 国产精品资源在线看| 欧美日韩免费视频| 欧美啪啪一区| 国产精品对白交换视频 | 欧美日韩亚洲一区| 欧美激情一区在线| 国产精品多人| 中文字幕日韩精品一区| 欧美日韩成人| 国产精品久久久久影院老司| 国产精品yjizz| 亚洲美女一区二区三区| 亚洲综合国产激情另类一区| 三级成人在线视频| 欧美三级日韩三级国产三级| 国产美女在线精品| 精品少妇一区二区三区视频免付费| 不卡的av在线播放| 国产精品三级av在线播放| 伊人精品成人久久综合软件| 亚洲制服丝袜一区| 色播五月激情综合网| 久久99国产精品久久99果冻传媒| 欧美日韩电影在线| 丁香一区二区三区| 国产欧美日产一区| 国产亚洲成人一区| 蜜桃免费网站一区二区三区| 欧美一区二区网站| 99精品视频一区二区三区| 国产精品美女www爽爽爽| 一区二区国产在线观看| 日韩和欧美的一区| 欧美一激情一区二区三区| 91在线精品一区二区三区| 亚洲日本乱码在线观看| 久久一区二区三区超碰国产精品| 久久99国产精品麻豆| 精品国产在天天线2019| 欧美精选一区| 亚洲6080在线| 91精品国产一区二区三区香蕉| 97se亚洲国产综合自在线不卡 | 国产精品欧美极品| 久久精品国产清高在天天线| 国产综合一区二区| 国产欧美精品一区二区色综合朱莉| 国产亚洲高清视频| 国产激情偷乱视频一区二区三区| 国产精品丝袜91| 色噜噜狠狠色综合欧洲selulu| 国产福利一区二区三区| 国产精品嫩草影院av蜜臀| 色偷偷久久人人79超碰人人澡| 国产久卡久卡久卡久卡视频精品| 久久婷婷综合激情| 亚洲人体大胆视频| 美女一区二区视频| 久久久久高清精品| 亚洲欧美日韩专区| 丁香桃色午夜亚洲一区二区三区| 中文字幕中文在线不卡住| 在线观看区一区二| 欧美国产激情| 喷水一区二区三区| 2欧美一区二区三区在线观看视频 337p粉嫩大胆噜噜噜噜噜91av | 国产精品妹子av| 一本久道久久综合中文字幕| 成人app在线观看| 亚洲成人中文在线| 亚洲精品一区二区在线观看| 免费国产一区二区| 成人av片在线观看| 午夜电影一区二区三区| 久久亚洲影视婷婷| 免费视频一区| 91小视频在线| 日本不卡视频在线观看| 中文字幕欧美日本乱码一线二线| 欧美视频在线一区| 亚洲视屏一区| 国产精品资源网| 亚洲欧美日本在线| 日韩亚洲欧美高清| 亚洲尤物影院| av高清不卡在线| 丝袜美腿亚洲一区二区图片| 国产欧美日韩另类视频免费观看| 欧美性色黄大片手机版| 在线播放一区| 国产69精品久久久久777| 亚洲午夜在线观看视频在线| 久久网站热最新地址| 欧美日韩综合在线| 99爱精品视频| av在线综合网| 蜜桃视频一区二区| 亚洲激情自拍视频| 精品乱人伦一区二区三区| 91黄色免费版| 日韩亚洲国产精品| 97久久超碰精品国产| 国产一区二区三区四区五区美女 | 成人国产一区二区三区精品| 午夜成人免费电影| 国产精品天美传媒沈樵| 日韩欧美亚洲另类制服综合在线| 久久婷婷丁香| 亚洲国产激情| 色综合天天综合在线视频| 国产精品综合一区二区| 日韩一区欧美二区| 亚洲乱码国产乱码精品精小说| 久久久久国产精品厨房| 91精品国产一区二区三区蜜臀 | 粉嫩一区二区三区在线看| 六月婷婷色综合| 亚洲人123区| 久久精品夜夜夜夜久久| 欧美一区二区在线不卡| 欧洲精品在线观看| 国产精品婷婷| 亚洲福利精品| 欧美不卡三区| 波波电影院一区二区三区| 韩国成人在线视频| 日本不卡一区二区三区 | 中文字幕欧美区| 久久综合色之久久综合| 日韩一二三区不卡| 欧美三区在线观看| 色香蕉成人二区免费| 免费亚洲电影| 蜜乳av另类精品一区二区| 99香蕉国产精品偷在线观看 | 亚洲视频一区二区免费在线观看| 久久日一线二线三线suv| 欧美一卡在线观看| 69堂成人精品免费视频| 欧洲av一区二区嗯嗯嗯啊| 久久xxxx| 国产精品久久久对白| 亚洲欧洲精品一区二区三区波多野1战4 | 欧美日本不卡视频| 欧美三级视频在线播放| 色香蕉成人二区免费| 久久久精品性| 一本色道久久加勒比精品| 久久一区二区三区四区五区| 色婷婷综合久久久中文一区二区| 美脚丝袜一区二区三区在线观看| 国产精品乱子乱xxxx| 国产精品视频免费一区| 国产伦精品一区二区三区| 一区二区三区免费看| 亚洲最黄网站| 国产欧美精品| 性高湖久久久久久久久| 欧美资源在线| 91国偷自产一区二区三区成为亚洲经典 | 91亚洲男人天堂| 91欧美激情一区二区三区成人| 91蜜桃网址入口| 欧美一区激情| 亚洲先锋成人| 日韩午夜黄色| 亚洲综合社区| 日本韩国一区二区三区| 精品视频全国免费看| 欧美一区二区性放荡片| 久久综合狠狠综合久久综合88 | 久久五月激情| 欧美日韩另类一区| 日韩午夜精品电影| 精品成a人在线观看| 国产日韩欧美激情| 亚洲欧美影音先锋|