本文主要解决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官网文章链接,平时学习仍得查阅官网。

Spring Data JPA