springboot 之jpa高級(jí)查詢(xún)操作
springboot的jpa可以根據(jù)方法名自動(dòng)解析sql 非常方便, 只需要在 dao接口中定義方法即可;
下面是一個(gè) demo
package com.bus365.root.dao;
import java.io.Serializable;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import com.bus365.root.model.User;
public interface UserDao extends JpaRepository<User,Long>,JpaSpecificationExecutor<User>,Serializable {
User findByName(String name);
User findByNameAndAge(String name, Integer age);
User findByNameOrAge(String name, Integer age);
/*@Query(value = "from User where name = :name")
List<User> findbyname(@Param("name") String name);*/
}
下面展示service層調(diào)用:
@Override
public User findByName(String name) {
User user = userDao.findByName(name);
return user;
}
@Override
public User findByNameAndAge(String name, Integer age) {
User user = userDao.findByNameAndAge(name,age);
return user;
}
@Override
public User findByNameOrAge(String name, Integer age) {
User user = userDao.findByNameOrAge(name,age);
return user;
}
具體的關(guān)鍵字,使用方法和生產(chǎn)成SQL如下表所示
| Keyword | Sample | JPQL snippet |
|---|---|---|
| And | findByLastnameAndFirstname | … where x.lastname = ?1 and x.firstname = ?2 |
| Or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
| Is,Equals | findByFirstnameIs,findByFirstnameEquals | … where x.firstname = ?1 |
| Between | findByStartDateBetween | … where x.startDate between ?1 and ?2 |
| LessThan | findByAgeLessThan | … where x.age < ?1 |
| LessThanEqual | findByAgeLessThanEqual | … where x.age ⇐ ?1 |
| GreaterThan | findByAgeGreaterThan | … where x.age > ?1 |
| GreaterThanEqual | findByAgeGreaterThanEqual | … where x.age >= ?1 |
| After | findByStartDateAfter | … where x.startDate > ?1 |
| Before | findByStartDateBefore | … where x.startDate < ?1 |
| IsNull | findByAgeIsNull | … where x.age is null |
| IsNotNull,NotNull | findByAge(Is)NotNull | … where x.age not null |
| Like | findByFirstnameLike | … where x.firstname like ?1 |
| NotLike | findByFirstnameNotLike | … where x.firstname not like ?1 |
| StartingWith | findByFirstnameStartingWith | … where x.firstname like ?1 (parameter bound with appended %) |
| EndingWith | findByFirstnameEndingWith | … where x.firstname like ?1 (parameter bound with prepended %) |
| Containing | findByFirstnameContaining | … where x.firstname like ?1 (parameter bound wrapped in %) |
| OrderBy | findByAgeOrderByLastnameDesc | … where x.age = ?1 order by x.lastname desc |
| Not | findByLastnameNot | … where x.lastname <> ?1 |
| In | findByAgeIn(Collection ages) | … where x.age in ?1 |
| NotIn | findByAgeNotIn(Collection age) | … where x.age not in ?1 |
| TRUE | findByActiveTrue() | … where x.active = true |
| FALSE | findByActiveFalse() | … where x.active = false |
| IgnoreCase | findByFirstnameIgnoreCase | … where UPPER(x.firstame) = UPPER(?1) |
下面介紹使用java原生的jpa操作數(shù)據(jù)庫(kù),對(duì)jpa熟悉的朋友應(yīng)該很快就能理解,springboot使用原生jpa的關(guān)鍵是引入entitymanger
看一下service層
package com.bus365.root.service.impl;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Service;
import com.bus365.root.model.Address;
import com.bus365.root.service.AddressService;
@Service
public class AddressServiceImpl implements AddressService {
@PersistenceContext
private EntityManager entityManager;
public List<Address> listAddress(){
List resultList = entityManager.createNativeQuery("select * from address ", Address.class).getResultList();
return resultList;
}
}
注意 @PersistenceContext
private EntityManager entityManager;
動(dòng)態(tài)引入entitymanger , 之后就能正常使用了;
createNativeQuery是操作原生mysql方法;支持跨表查詢(xún);
jpa的事務(wù) 直接使用注解Transactional 參數(shù)rollbackon表示回滾條件, 這個(gè)注解一搬加在service層; 注意getSingleResult 如果查不到數(shù)據(jù)會(huì)報(bào)錯(cuò);
@Transactional(rollbackOn= {Exception.class})
public Address getAddressByid(Long id) {
Address singleResult = null;
try {
singleResult = (Address) entityManager
.createNativeQuery("select * from address where id = :id", Address.class).setParameter("id", id)
.getSingleResult();
} catch (Exception e) {
e.printStackTrace();
}
return singleResult;
}
jpa實(shí)現(xiàn)多表聯(lián)查;
@Transactional
public List<Object[]> getUserWithAddrByid(Long id) {
List resultList = entityManager.createNativeQuery(
"select u.id id,u.age age,u.name name,a.name aname,a.completeaddress addre from user u left join address a on u.addressid = a.id where u.id = :id")
.setParameter("id", id).getResultList();
return resultList;
}
這是一個(gè)聯(lián)查user 和address的例子, 返回的結(jié)果是個(gè)List<Object[]> 項(xiàng)目中一般封裝成vo 類(lèi),或者List<Map<String,Object>> 的形式
github項(xiàng)目地址 https://github.com/Christain1993/SpringBootIntegration
補(bǔ)充:springBootJpa的復(fù)雜查詢(xún)
分頁(yè)
/**
* 條件查詢(xún)+分頁(yè)
* @param whereMap
* @param page
* @param size
* @return
*/
public Page<CaseManage> findSearch(Map whereMap, int page, int size,Integer createId) {
Sort sort = new Sort(Sort.Direction.DESC,"id");
Specification<CaseManage> specification = createSpecification(whereMap,createId);
PageRequest pageRequest = new PageRequest(page,size,sort);
return caseDao.findAll(specification, pageRequest);
}
/**
* 條件查詢(xún)
* @param whereMap
* @return
*/
public List<CaseManage> findSearch(Map whereMap,Integer createId) {
Specification<CaseManage> specification = createSpecification(whereMap, createId);
return caseDao.findAll(specification);
}
/**
* 動(dòng)態(tài)條件構(gòu)建
* @param searchMap
* @return
*/
private Specification<CaseManage> createSpecification(Map searchMap,Integer createId) {
return new Specification<CaseManage>() {
@Override
public Predicate toPredicate(Root<CaseManage> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
List<Predicate> predicateList = new ArrayList<Predicate>();
// 案件名稱(chēng)
if (searchMap.get("case_name")!=null && !"".equals(searchMap.get("case_name"))) {
predicateList.add(cb.like(root.get("case_name").as(String.class), "%"+(String)searchMap.get("case_name")+"%"));
}
// 案件編號(hào)uuid類(lèi)型
if (searchMap.get("case_uuid")!=null && !"".equals(searchMap.get("case_uuid"))) {
predicateList.add(cb.equal(root.get("case_uuid").as(String.class), (String)searchMap.get("case_uuid")));
}
return cb.and( predicateList.toArray(new Predicate[predicateList.size()]));
}
};
}
or查詢(xún)
想實(shí)現(xiàn)這樣的效果
where (state=1 or state=2)and name='zhangsan'
java代碼
List<Predicate> predicateList = new ArrayList<Predicate>();
Predicate or = cb.or(cb.and(cb.equal(root.get("case_authority").as(String.class), "0")), cb.and(cb.equal(root.get("create_id").as(String.class), String.valueOf(createId))));
predicateList.add(or);
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
- springboot + jpa實(shí)現(xiàn)刪除數(shù)據(jù)的操作代碼
- Spring?Boot?整合JPA?數(shù)據(jù)模型關(guān)聯(lián)使用操作(一對(duì)一、一對(duì)多、多對(duì)多)
- SpringDataJPA詳解增刪改查操作方法
- Spring?Data?JPA映射自定義實(shí)體類(lèi)操作
- SpringDataJpa多表操作的實(shí)現(xiàn)
- Springboot使用Spring Data JPA實(shí)現(xiàn)數(shù)據(jù)庫(kù)操作
- SpringBoot集成JPA持久層框架,簡(jiǎn)化數(shù)據(jù)庫(kù)操作
- springboot-jpa的實(shí)現(xiàn)操作
- Springboot JPA級(jí)聯(lián)操作的實(shí)現(xiàn)(一對(duì)一、一對(duì)多、多對(duì)多)
相關(guān)文章
java開(kāi)發(fā)之MD5加密算法的實(shí)現(xiàn)
本篇文章介紹了,java開(kāi)發(fā)之MD5加密算法的實(shí)現(xiàn)。需要的朋友參考下2013-05-05
linux部署springBoot項(xiàng)目的腳本問(wèn)題
這篇文章主要介紹了linux部署springBoot項(xiàng)目的腳本問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-05-05
Spring MVC打印@RequestBody、@Response日志的方法
這篇文章主要介紹了Spring MVC打印@RequestBody、@Response日志的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-02-02
JavaSE API實(shí)現(xiàn)生成隨機(jī)數(shù)的2種方法(Random類(lèi)和Math類(lèi)的Random方法)
本文主要介紹了JavaSE API實(shí)現(xiàn)生成隨機(jī)數(shù)的2種方法,主要包括Random類(lèi)和Math類(lèi)的random方法都可以用來(lái)生成隨機(jī)數(shù),具有一定的參考價(jià)值,感興趣的可以了解一下2023-10-10
java實(shí)現(xiàn)爬取知乎用戶(hù)基本信息
這篇文章主要為大家介紹了一個(gè)基于JAVA的知乎爬蟲(chóng),抓取知乎用戶(hù)基本信息,感興趣的小伙伴們可以參考一下2016-05-05
淺談springboot多模塊(modules)開(kāi)發(fā)
這篇文章主要介紹了淺談springboot多模塊(modules)開(kāi)發(fā),詳細(xì)的介紹了springboot多模塊的實(shí)現(xiàn),有興趣的可以了解一下2017-09-09
java面向?qū)ο笤O(shè)計(jì)原則之合成復(fù)用原則示例詳解
這篇文章主要介紹了java面向?qū)ο笤O(shè)計(jì)原則之合成復(fù)用原則的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2021-10-10
如何在JDK 9中更簡(jiǎn)潔使用 try-with-resources 語(yǔ)句
本文詳細(xì)介紹了自 JDK 7 引入的 try-with-resources 語(yǔ)句的原理和用法,以及介紹了 JDK 9 對(duì) try-with-resources 的改進(jìn),使得用戶(hù)可以更加方便、簡(jiǎn)潔的使用 try-with-resources 語(yǔ)句。,需要的朋友可以參考下2019-06-06
通過(guò)實(shí)例了解Java 8創(chuàng)建Stream流的5種方法
這篇文章主要介紹了通過(guò)實(shí)例了解Java 8創(chuàng)建Stream流的5種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12

