日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

querydsl动态 sql_JPA整合Querydsl入门篇

發(fā)布時間:2023/12/20 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 querydsl动态 sql_JPA整合Querydsl入门篇 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

JPA整合Querydsl入門篇

不知道你們喜不喜歡用JPA ,我本人是很喜歡 不要和我說JPA不適合復(fù)雜查詢等等的,你要知道現(xiàn)在都是微服務(wù),只要你服務(wù)器拆分夠細(xì)表設(shè)計夠合理,都是服務(wù)之間調(diào)能用到多少關(guān)聯(lián)查詢呢? 而且結(jié)合了QueryDsl工具讓你寫起來更快,本博客后臺就是使用了JPA+QueryDsl 做的查詢 下面開始講解吧。

1.為什么要用QueryDsl

先來看個代碼

@Override

public List findByPcardCardOrder(

PcardCardOrder pcardCardOrder,String applyInstName2,Integer page, Integer rows) {

StringBuffer sql = new StringBuffer(

"SELECT p.*"

+",p2.vcard_make_des"

+",p3.cardnum_rule_id,p3.vtype_nm"

+",p4.cn_card_bin,p4.cn_nm"

+",p5.inst_id,p5.inst_name,p5.apply_range,p5.card_name,p5.card_type,p5.bin_card_material"

+",p6.inst_name AS apply_inst_name "

+",p7.inst_name AS apply_inst_name2"

+ ",p8.inst_name as receive_inst_name"

+ " FROM "

+" tbl_pcard_card_order p LEFT JOIN tbl_pcard_vcard_make p2 ON p.make_id = p2.vcard_make_id"

+" LEFT JOIN tbl_pcard_vtype p3 ON p2.vcard_make_vtype_id=p3.vtype_id"

+" LEFT JOIN tbl_pcard_cardnum_rule p4 ON p3.cardnum_rule_id=p4.cn_id"

+" LEFT JOIN tbl_pcard_cardbin p5 ON p4.cn_card_bin=p5.card_bin"

+" LEFT JOIN tbl_pcard_institution p6 ON p5.apply_range=p6.inst_id"

+" LEFT JOIN tbl_pcard_institution p7 ON p.apply_inst_id=p7.inst_id"

+" LEFT JOIN tbl_pcard_institution p8 ON p.receive_inst=p8.inst_id"

+" WHERE 1=1 ");

int i = 1;

Map map = new HashMap();

if (!StringUtils.isEmpty(pcardCardOrder.getCordId())) {

sql.append(" and p.cord_id=");

sql.append("?" + i);

map.put(i + "", pcardCardOrder.getCordId());

i++;

}

if (!StringUtils.isEmpty(pcardCardOrder.getAppointMchtcard())) {

sql.append(" and p.appoint_mchtcard=");

sql.append("?" + i);

map.put(i + "", pcardCardOrder.getAppointMchtcard());

i++;

}

if (!StringUtils.isEmpty(pcardCardOrder.getMakeId())) {

sql.append(" and p.make_id like ");

sql.append("?" + i);

map.put(i + "","%%"+ pcardCardOrder.getMakeId()+"%%");

i++;

}

if (!StringUtils.isEmpty(applyInstName2)) {

sql.append(" and p7.inst_name like ");

sql.append("?"+i);

map.put(i+"","%%"+applyInstName2+"%%");

i++;

}

sql.append(" order by p.ct_dm desc");

Query query = entityManager.createNativeQuery(sql.toString());

for (String key : map.keySet()) {

query.setParameter(key, map.get(key));

}

if (page != null && rows != null) {

query.setFirstResult(rows * (page - 1));

query.setMaxResults(rows);

}

return query.getResultList();

}

多的不用說了吧,我看到這種代碼就想吐 也沒心情看,說真的這個還算好的了,還見過更多更惡心的

2.了解QueryDsl

QueryDSL僅僅是一個通用的查詢框架,專注于通過Java API構(gòu)建類型安全的SQL查詢。

Querydsl可以通過一組通用的查詢API為用戶構(gòu)建出適合不同類型ORM框架或者是SQL的查詢語句,也就是說QueryDSL是基于各種ORM框架以及SQL之上的一個通用的查詢框架。

借助QueryDSL可以在任何支持的ORM框架或者SQL平臺上以一種通用的API方式來構(gòu)建查詢。目前QueryDSL支持的平臺包括JPA,JDO,SQL,Mongodb 等等。。。

3.引入QueryDsl

3.1 pom中引入依賴

com.querydsl

querydsl-jpa

com.querydsl

querydsl-apt

provided

3.2 添加maven插件

添加這個插件是為了讓程序自動生成query type(查詢實體,命名方式為:"Q"+對應(yīng)實體名)。

注:在使用過程中,如果遇到query type無法自動生成的情況,用maven更新一下項目即可解決(右鍵項目->Maven->Update Project), 或者之間終端輸入 mvn clean compile 編譯一下就會自動生成Q 類

com.mysema.maven

apt-maven-plugin

1.1.3

process

target/generated-sources/java

com.querydsl.apt.jpa.JPAAnnotationProcessor

3.3 JPA的基本配置,在application.yml中配置

spring:

jpa:

database: mysql

show-sql: true

open-in-view: true

hibernate:

ddl-auto: update

naming:

strategy: org.hibernate.cfg.DefaultComponentSafeNamingStrategy

properties:

hibernate:

dialect: org.hibernate.dialect.MySQL5InnoDBDialect

format_sql: true

3.4 創(chuàng)建實體

這里只是列出了部分屬性

@Data

@Entity

@EntityListeners(AuditingEntityListener.class)

public class BlogInfo {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

/**

* 博客標(biāo)題

*/

private String blogTitle;

/**

* 博客內(nèi)容

*/

@Column(columnDefinition = "text")

private String blogContent;

/**

* 博客簡要

*/

private String blogShortContent;

}

3.5 引入JPAQueryFactory

@Service

public class BlogInfoServiceImpl implements BlogInfoService {

private JPAQueryFactory queryFactory;

@PostConstruct //指定初始化queryFactory

public void init() {

queryFactory = new JPAQueryFactory(entityManager);

}

@PersistenceContext

private EntityManager entityManager;

}

4.使用QueryDsl

先定義一個Q類 ,Q類是QueryDsl幫我們編譯的時候生成的對應(yīng)的是實體類

QBlogInfo qBlogInfo = QBlogInfo.blogInfo;

5. 查詢所有屬性

通過queryFactory查詢

queryFactory.select(qBlogInfo)

.from(qBlogInfo) 表示查詢BlogInfo所有的屬性 相當(dāng)于select * from blog_Info

6.查詢特定屬性

queryFactory.select(qBlogInfo.blogTitle,qBlogInfo.blogContent)

.from(qBlogInfo) 表示查詢BlogInfo實體的 blogTitle 屬性 相當(dāng)于 select blogTitle,blogContent from blog_Info

7.帶where查詢

queryFactory.select(qBlogInfo)

.from(qBlogInfo)

.where(qBlogInfo.id.eq(1)) 相當(dāng)于 select blogTitle from blog_Info where id = 1;

8.多表查詢

多表返回Tuple ,tuple.get(0) 就是第一個屬性qBlogInfo , tuple.get(1) 就是獲取第二個屬性 typeName

queryFactory.select(qBlogInfo, qBlogType.typeName)

.from(qBlogInfo)

.leftJoin(qBlogType)

.on(qBlogInfo.blogTypeId.eq(qBlogType.id))

9.排序查詢

追加orderBy方法指定按照什么屬性進(jìn)行排序

queryFactory.select(qBlogInfo)

.from(qBlogInfo)

.orderBy(qBlogInfo.createTime.desc())

10.分頁查詢

追加offset 偏移位置,就是從哪條數(shù)據(jù)開始查詢最佳limit 限制查詢多少條

JPAQuery jpaQuery = queryFactory.select(qBlogInfo, qBlogType.typeName)

.from(qBlogInfo)

.leftJoin(qBlogType)

.on(qBlogInfo.blogTypeId.eq(qBlogType.id))

.orderBy(qBlogInfo.createTime.desc())

.offset(pageable.getPageNumber() * pageable.getPageSize())

.limit(pageable.getPageSize());

11.執(zhí)行查詢

通過上面構(gòu)造的 jpaQuery

jpaQuery.fetchResults(); 查詢list ,返回 list 泛型根據(jù)是否有多表查詢,

如果沒有就返回 比如上面的QBlogInfo 對應(yīng)的 BlogInfo ==》 list,

如果有多表查詢 返回 list 類型,再根據(jù)tuple.get(0) tuple.get(1) 去獲取對應(yīng)的屬性

jpqQuery.fetchOne(); 查詢單條記錄 比如where id = xxx 的時候可以使用

12.樣例 根據(jù)ID查詢博客

/**

* 根據(jù) Id 查詢博客信息

*

* @param id : id

* @return : 博客信息

*/

@Override

public BlogInfoVo queryById(Long id) {

QBlogInfo qBlogInfo = QBlogInfo.blogInfo;

QBlogType qBlogType = QBlogType.blogType;

Tuple tuple = queryFactory.select(qBlogInfo, qBlogType.typeName)

.from(qBlogInfo)

.leftJoin(qBlogType)

.on(qBlogInfo.blogTypeId.eq(qBlogType.id))

.where(qBlogInfo.id.eq(id))

.fetchOne();

BlogInfo blogInfo = tuple.get(0, BlogInfo.class);

Gson gson = new Gson();

List list = gson.fromJson(blogInfo.getAnchorJson(), List.class);

BlogInfoVo blogInfoVo = BlogInfoConverter.INSTANCE.domain2vo(tuple.get(0, BlogInfo.class)).setBlogTypeName(tuple.get(1, String.class));

blogInfoVo.setAnchors(list);

return blogInfoVo;

}

總結(jié):

本篇簡單介紹了在JPA中如何使用QueryDsl,包括pom依賴 插件, queryFactory的初始化,以及 各種例子包括 分頁 排序 等等查詢 看著使用QueryDsl寫出來的sql查詢 是不是很舒服呢! 后續(xù)會深入講解一下 QueryDsl的高級點的用法

總結(jié)

以上是生活随笔為你收集整理的querydsl动态 sql_JPA整合Querydsl入门篇的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。