本文主要解决Spring Data JPA提供了一些表达条件查询的关键字,entityManage的具体应用,entity外键和复合主键的应用,默认已经搭建Spring Data JPA框架。
1、按条件查询写法:
在查询时,通常需要同时根据多个属性进行查询,且查询的条件也格式各样(大于某个值、在某个范围等等),Spring Data JPA 为此提供了一些表达条件查询的关键字,大致如下:
- And --- 等价于 SQL 中的 and 关键字,比如 findByUsernameAndPassword(String user, Striang pwd);
- Or --- 等价于 SQL 中的 or 关键字,比如 findByUsernameOrAddress(String user, String addr);
- Between --- 等价于 SQL 中的 between 关键字,比如 findBySalaryBetween(int max, int min);
- LessThan --- 等价于 SQL 中的 "
- GreaterThan --- 等价于 SQL 中的">",比如 findBySalaryGreaterThan(int min);
- IsNull --- 等价于 SQL 中的 "is null",比如 findByUsernameIsNull();
- IsNotNull --- 等价于 SQL 中的 "is not null",比如 findByUsernameIsNotNull();
- NotNull --- 与 IsNotNull 等价;
- Like --- 等价于 SQL 中的 "like",比如 findByUsernameLike(String user);
- NotLike --- 等价于 SQL 中的 "not like",比如 findByUsernameNotLike(String user);
- OrderBy --- 等价于 SQL 中的 "order by",比如 findByUsernameOrderBySalaryAsc(String user);
- Not --- 等价于 SQL 中的 "! =",比如 findByUsernameNot(String user);
- In --- 等价于 SQL 中的 "in",比如 findByUsernameIn(Collection userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数;
- NotIn --- 等价于 SQL 中的 "not in",比如 findByUsernameNotIn(Collection userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数;
- Distinct ---剔重 findDistinctPeople
关键字 | 方法 命名 | sql where字句 |
And | findByNameAndPwd | where name= ? and pwd =? |
Or | findByNameOrSex | where name= ? or sex=? |
Is,Equals | findById,findByIdEquals | where id= ? |
Between | findByIdBetween | where id between ? and ? |
LessThan | findByIdLessThan | where id < ? |
LessThanEquals | findByIdLessThanEquals | where id |
GreaterThan | findByIdGreaterThan | where id > ? |
GreaterThanEquals | findByIdGreaterThanEquals | where id > = ? |
After | findByIdAfter | where id > ? |
Before | findByIdBefore | where id < ? |
IsNull | findByNameIsNull | where name is null |
isNotNull,NotNull | findByNameNotNull | where name is not null |
Like | findByNameLike | where name like ? |
NotLike | findByNameNotLike | where name not like ? |
StartingWith | findByNameStartingWith | where name like '?%' |
EndingWith | findByNameEndingWith | where name like '%?' |
Containing | findByNameContaining | where name like '%?%' |
OrderBy | findByIdOrderByXDesc | where id=? order by x desc |
Not | findByNameNot | where name <> ? |
In | findByIdIn(Collection c) | where id in (?) |
NotIn | findByIdNotIn(Collection c) | where id not in (?) |
True | findByAaaTue | where aaa = true |
False | findByAaaFalse | where aaa = false |
IgnoreCase | findByNameIgnoreCase | where UPPER(name)=UPPER(?) |
这里提示一下,findBy也可以换成deleteBy,语法是一样。
2、具体sql语句的写法:
这种写法适用于批量删除、新增等操作,比较第1点,处理效率更高。
@Repository
public interface SystemLogRepository extends JpaRepository<SystemLogEntity,String>{
@Modifying
@Transactional
@("delete from system_log where s_logdate <= ?1")
void deletByLogdate(Timestamp edate);
//虽然是批量删除,实际是先查到id,再按id删除,删除效率很低
@Transactional
void deleteByLogdateLessThan(Timestamp edate);
}
3、entityManage的写法:
这种写法较第1点,虽然麻烦,但是灵活,可以写较为复杂的逻辑。
我的理解,就是将from,select,where,groupby,用代码拼接起来,可以写一个通用的函数,方便调用,后续就不用处理这些细节啦。
import javax.persistence.EntityManager;
@PersistenceContext
private EntityManager em;
public List<Map<String,Object>> groupBy(Timestamp bdate,Timestamp edate){
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> criteriaQuery = cb.createTupleQuery();
/*from*/
Root<ViewXiaonengWaipaiEntity> root = criteriaQuery.from(tableEntity.class);
/*select*/
List<Selection<?>> selections = new ArrayList<Selection<?>>();
selections.add(root.get("AA").alias("AA"));
selections.add(cb.count(root.get("BB")).alias("BB"));
selections.add(cb.sum(root.get("CC")).alias("CC"));
criteriaQuery.multiselect(selections);
/*where*/
Predicate pd = cb.conjunction();
Predicate p1 = cb.between(root.get("DD"), bdate, edate);
Predicate p2 = cb.isTrue(cb.literal(Boolean.TRUE));
pd = cb.and(p1,p2);
criteriaQuery.where(pd);
/*groupby*/
criteriaQuery.groupBy(root.get("AA"));
/*exec*/
TypedQuery<Tuple> query = em.createQuery(criteriaQuery);
List<Tuple> result = query.getResultList();
}
4、entity关联主键的写法:
Jpa可以外链其他的表,通过装载的方式实现,在entity中声明。这里实现了两种写法,分别对应一对多、多对一的具体实践。
@Data
@Entity(name="table")
public class tableEntity implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
//该字段存放duty_type的id,只需关联SystemTypesEntity,就能获取对应的名称
@ManyToOne(fetch=FetchType.EAGER, optional = false)
@JoinColumn(name="duty_type")
private SystemTypesEntity dutyTypesEntity;
//该字段存放 流水号的 id,只需关联processEntity表,就能获取该流水号的处理过程
@OneToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
@JoinColumn(name="lsh")
@OrderBy("slsj desc")
private List<processEntity> processEntity;
}
最后分享springboot官网文章链接,平时学习仍得查阅官网。