springboot 之jpa高級查詢操作
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ù)庫,對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方法;支持跨表查詢;
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 類,或者List<Map<String,Object>> 的形式
github項(xiàng)目地址 https://github.com/Christain1993/SpringBootIntegration
補(bǔ)充:springBootJpa的復(fù)雜查詢
分頁
/** * 條件查詢+分頁 * @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); } /** * 條件查詢 * @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>(); // 案件名稱 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")+"%")); } // 案件編號uuid類型 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查詢
想實(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ò)誤或未考慮完全的地方,望不吝賜教。
相關(guān)文章
聊聊springmvc中controller的方法的參數(shù)注解方式
本篇文章主要介紹了聊聊springmvc中controller的方法的參數(shù)注解方式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10Java靜態(tài)和非靜態(tài)成員變量初始化過程解析
這篇文章主要介紹了Java靜態(tài)和非靜態(tài)成員變量初始化過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01Spring使用注解進(jìn)行引用類型的自動(dòng)裝配逐步分析
自動(dòng)裝配是springboot的核心,一般提到自動(dòng)裝配就會(huì)和springboot聯(lián)系在一起。實(shí)際上Spring Framework早就實(shí)現(xiàn)了這個(gè)功能。Spring Boot只是在其基礎(chǔ)上,通過SPI的方式,做了進(jìn)一步優(yōu)化2023-03-03SpringBoot2 Jpa 批量刪除功能的實(shí)現(xiàn)
這篇文章主要介紹了SpringBoot2 Jpa 批量刪除功能的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01解決Java的InputMismatchException異常
這篇文章介紹了解決Java的InputMismatchException異常的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-12-12寧可用Lombok也不把成員設(shè)置為public原理解析
這篇文章主要為大家介紹了寧可用Lombok也不把成員設(shè)置為public原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03關(guān)于Java中增強(qiáng)for循環(huán)使用的注意事項(xiàng)
for循環(huán)語句是java循環(huán)語句中最常用的循環(huán)語句,一般用在循環(huán)次數(shù)已知的情況下使用,這篇文章主要給大家介紹了關(guān)于Java中增強(qiáng)for循環(huán)使用的注意事項(xiàng),需要的朋友可以參考下2021-06-06spring?boot如何配置靜態(tài)路徑詳解(404出現(xiàn)的坑)
這篇文章主要給大家介紹了關(guān)于spring?boot如何配置靜態(tài)路徑的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-02-02