springboot之jpa高階查詢
阿新 • • 發佈:2018-12-24
springboot的jpa可以根據方法名自動解析sql 非常方便, 只需要在 dao介面中定義方法即可;
下面是一個 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層呼叫:
@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; }
具體的關鍵字,使用方法和生產成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操作資料庫,對jpa熟悉的朋友應該很快就能理解,springboot使用原生jpa的關鍵是引入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;
動態引入entitymanger , 之後就能正常使用了;
createNativeQuery是操作原生mysql方法;支援跨表查詢;
jpa的事務 直接使用註解Transactional 引數rollbackon表示回滾條件, 這個註解一搬加在service層; 注意getSingleResult 如果查不到資料會報錯;
@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實現多表聯查;
@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;
}
這是一個聯查user 和address的例子, 返回的結果是個List<Object[]> 專案中一般封裝成vo 類,或者List<Map<String,Object>> 的形式