springboot+jpa查询(拼接条件查询)

更新时间:2023-05-22 09:13:12 阅读: 评论:0

springboot+jpa查询(拼接条件查询)
最近在学习springboot使⽤jpa操作数据库,总结⼀下。
Dao层创建与JavaBean对应的接⼝,继承JpaRepository<K,E>接⼝
@Repository
public interface AccountDao extends JpaRepository<Account,Integer>{}
//Account对应的是JavaBean实体类,Integer是实体类主键的类型
⽆需创建接⼝的实现类
个⼈学习到的jpa的⼏种查询⽅法:
1、jpa⾃带的⽅法:
使⽤的编程语⾔是Kotlin
//主要记录分页和排序
/
/rvice层
class AccountServiceImpl:AccountService{
@Autewired
lateinit var accountDao:AccountDao
override fun queryOnLoad(apu: AccountPageUtil): Map<String, Any?>{
//创建排序对象
val sort:Sort=Sort.by(Sort.Direction.ASC,"id")
//创建分页对象
val page:Pageable=PageRequest.Start(),ws,sort)
val map = hashMapOf<String,Any?>()
//通过findAll⽅法进⾏分页查询
var pageResult=accountDao.findAll(page)
//findAll(Pageable)返回的是page对象,其中包含了分页所需要的总页数、总信息条数、每页中的对象等资源。可以查看源码获取所需要的信息//分页的结果
map["rows"]=t
//分页总数
map["total"]=alPages
return map
}
}
2、jpa可以通过⽅法名进⾏查询
Dao层的接⼝
@Repository
interface SubjectDao:JpaRepository<Subject,Int>{
/**
* 根据Clazz查询
*/
fun findByClazz(clazz:String,pageable:Pageable):List<Subject>
my precious
/**
* 根据sid精确查询单个对象
*/
fun findBySid(id:Int):Subject
}
3、⾃定义SQL查询语句进⾏查询
Dao层的接⼝
@Repository
interface SubjectDao:JpaRepository<Subject,Int>{
@Query(value="lect sid as sid,sname as sname,slevel as slevel,clazz as clazz,pname as pname,pid as pid from Subject where sid like %?1%) ") fun myFindBySidLike(sid:Int,pageable: Pageable):List<Map<String,Any>>
}
在这⾥有⼏个注意点
@Query中有⼀个属性:nativeQuery = true 添加该属性等于true则是原⽣SQL语句查询,不添加则是HQL语句(Hibernate⾯向对象的查询)
like模糊查询时可在后⾯直接加%
⽅法中给的参数类型必须和实体类中定义的类型⼀样,否则会报类型不⼀致的错
⽅法的返回值好像只能返回List<Map<K,V>>类型(因为我只试过返回Page类型和List类型,都是类型不对)。Map中的Key就是查询语句中的别名,所以这⾥添加了别名。
⽅法名不能是findBySidLike,因为这样他就不会执⾏⾃⼰写的SQL语句。
4、复杂的条件拼接查询
看到其他⼈的博客中说,Dao层接⼝再继承⼀个接⼝JpaSpecificationExecutor<;实体类>
Dao层
@Repository
interface SubjectDao:JpaRepository<Subject,Int>, JpaSpecificationExecutor<Subject>{}
private Specification<Db1NewsFilesEntity>countByAppidAndKwAndSearchId(String appId, String wk , String archId){
return new Specification<Db1NewsFilesEntity>(){
@Override
public Predicate toPredicate(Root<Db1NewsFilesEntity> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder){
//创建存放Predicate对象的集合
List<Predicate> list =new ArrayList<>();
/*⽤于关联查询join⽅法的第⼆个参数可以设置
JoinType.LEFT、JoinType.RIGHT、JoinType.INNER*/
Join<Db1NewsFilesEntity, Db1NewsItemsEntity> join =
root.join("newsItem", JoinType.INNER);
//以下为添加条件
list.add(criteriaBuilder.("appId"),appId));
停机英文
list.add(criteriaBuilder.("img"),true));
list.add(criteriaBuilder.("appId"),appId));
list.add(criteriaBuilder.("isOk"),2));
list.add(criteriaBuilder.("topImgId")));
//判断并拼接条件
if(!StringUtils.isEmpty(archId)){
list.add(criteriaBuilder.("archId"),archId));
}
if(!StringUtils.isEmpty(wk)){
list.add(criteriaBuilder.("ItemTitle"),"%"+wk+"%"));
}
Predicate[] p =new Predicate[list.size()];
query.where(criteriaBuilder.Array(p)));
Restriction();
}
};
}
//此段代码摘抄⾃⽹络:/qq587492/article/details/81629689
写上上⾯的代码我主要是想说说他的弊端,我原以为他是万能的,结果个⼈认为还是⽐较局限的。
它是⼀种完全⾯向对象的。如果两个表之间没有明确的关联关系(在属性上标注OneToOne、OneToMany等)时,关联查询是不能实现的,肯定是类型对不上,等待着的就是各种报错。
他不能实现⾃定义字段查询(投影查询),每次查询时会把所有的字段都差出来。
prevention
他只能⽤在findAll⽅法上,使⽤⾃定义的⽅法,根本不回去拼接,⽽是去执⾏了⾃定义的⽅法。
所以我觉得稍微复杂⼀点的查询就要费事了。
于是继续众⾥寻他在百度,终于找到了你想怎样就怎样的⽅法。
1. 在rvice层中放这么⼀个东西。
@PersistenceContext
lateinit var em: EntityManager
java中是这么写的:
@PersistenceContext
private EntityManager em;
他有⼀些创建Query对象的⽅法,有了Query对象,就可以⾃⼰拼接条件查询了。
下⾯放上我使⽤它的⼀点代码:
/**
* ⾃定义拼接条件查询
*/
fun predicateQuery(em: EntityManager,apu: AccountPageUtil): MyResult<ResultAccount>{
var baSQL="lect new com.ity.ResultAccount(a.ateDate,a.proofNum,a.,a.go,a.ientation,a.cl azz,b.sname,c.sname) from Account a left outer join Subject b on a.subject=b.sid left outer join Subject c on a.sideSubject=c.sid where 1=1"
var comditionalSQL=""
var countSQL="lect count(id) from Account a where 1=1"
//map⽤来组装SQL占位符和对应的值麻省理工学院公开课
var map= hashMapOf<String,Any>()
if(!apu.startDate.equals("")&&!dDate.equals("")){
println("拼接条件查询:开始时间不为空,结束时间不为空")
comditionalSQL+=" and (a.createDate between :startdate and :enddate)"
map["startdate"]=apu.startDate
map["enddate"]=dDate
}el if(!apu.startDate.equals("")&&dDate.equals("")){
println("拼接条件查询:开始时间不为空,结束时间为空")
comditionalSQL+=" and (a.createDate between :startdate and :enddate)"
map["startdate"]=apu.startDate
map["enddate"]="${w()}"//相当于Java中的""+w()
}el if(apu.startDate.equals("")&&!dDate.equals("")){
println("拼接条件查询:开始时间为空,结束时间不为空")
comditionalSQL+=" and (a.createDate between :startdate and :enddate)"
//相当于java中的拼接字符串w().year+"-"+w().monthValue+"-01"
map["startdate"]="${w().year}-${w().monthValue}-01"
map["enddate"]=dDate
}el{
println("拼接条件查询:开始时间为空,结束时间为空")
comditionalSQL+=" and (a.createDate between :startdate and :enddate)"
map["startdate"]="${w().year}-${w().monthValue}-01"
map["enddate"]="${w()}"
}
tentif(apu.digest!=""){
println("拼接条件查询:digest不为空")
comditionalSQL+=" and a.digest=:digest"
map["digest"]="${apu.digest}"
}
if(apu.clazz!=""){
println("拼接条件查询:clazz不为空")
comditionalSQL+=" and a.clazz=:clazz"
map["clazz"]="${apu.clazz}"
}
if(apu.subject!=null){
724是什么意思println("拼接条件查询:关联subject不为空")
comditionalSQL+=" and a.subject=:subject"
map["subject"]=apu.subject!!
}
//组装SQL
you drink mevar resSQL="${baSQL}${comditionalSQL}"
var countSQL="${countSQL}${comditionalSQL}"
//创建查询对象
/*这⾥是重点,将SQL放⼊⽅法中,创建⼀个查询对象,确切的说应该是HQL,
他接收的也是Hibernate查询语句(我写原⽣SQL报错)。重点是,SQL是⾃⼰写的,这就灵活了很多。性能⽅⾯没有关注*/
var ateQuery(resSQL)
var ateQuery(countSQL)
//创建封装结果集的对象
var result=MyResult.of<ResultAccount>()
//设置分页,注意,分页只能⽤这种⽅式,不能写在SQL中,否则报错
res.Start())
res.ws)
//添加参数,此处我⽤了kotlin的⽅式将占位符和参数⼀⼀对应放⼊Query对象中
for((index,ele)in map){
res.tParameter(index,ele)
countRes.tParameter(index,ele)
}
//组装结果集
/*
此处注意的是:如果⽤普通是SQL样式查询,如:"lect a,b,c from d where ..."
他返回的不是键值对形式对象,有些难以控制。
所以我在SQL中使⽤了Hibernate的投影查询⽅式:
"lect new com.ity.ResultAccount(a,b,c) from d where ..."
考研调剂流程com.ity.ResultAccount是我⾃定义的⼀个返回结果集的类,这个类要有⼀个和查询的字段类型⼀⼀对应的构造⽅法。
那么返回的就是⼀个该对象的集合。当然需要强转⼀下
a as ResultAccount就是将a强转为ResultAccount
*/
for(a sultList){
}
//查询⼀个对象时使⽤singleResult()⽅法获得
//查询⼀堆对象时⽤resultList()⽅法获得,
//查询的数值返回的是伪Long型,所以先转为Long型,再转为Integer
怎样才能快速祛斑
return result
}
在线辅导平台//创建HQL语句
@PersistenceContext
private EntityManager em;
String hql="lect a,b from C where d=:e "// :e是占位符,也相当于给占位符起⼀个名字//通过HQL语句创建query对象
Query ateQuery(hql)
//给条件添加值,占位符不能使⽤?的形式
//query.tParameter(占位符,值)
query.tParameter("e",255)
//获取结果
List<C> ResultList
//遍历结果集组装想要的结果...
如有不对之处还请⼤神告知⼀⼆

本文发布于:2023-05-22 09:13:12,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/90/118150.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:查询   对象   条件   拼接   类型   创建   结果   占位
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图