springboot学习笔记5(JPA实现分页、排序、返回map集合)前⾔
在相当长的⼀段时间⾥,实现应⽤程序的数据访问层⾮常⿇烦。必须编写太多的模板代码来执⾏简单的查询,以及执⾏分页。Spring data JPA旨在通过减少实际需要的⼯作量来显著改进数据访问层的实现。作为开发⼈员,您可以编写存储库接⼝,包括⾃定义查程序⽅法。spring data JPA核⼼接⼝是Repository,其它所有接⼝都在此类的基础上进⾏了扩展。 下⾯是JPA关系图解图:
熟悉JPA的⼏个API
CurdRepository提供了增删改产⽅法,PagingAndSortingRepositroy增加了分页查询⽅法,JpaRepositroy⼜增加了实例查询⽅法。实际应⽤中可以有选择的继承上⾯接⼝即可。上⾯说过,jpa提供了封装查询数据库模板⽅法。下⾯就来⼀⼀介绍JPA给我们提供的模板⽅法:
CurdRepository
接⼝,提供增删改查基本的功能:
@NoRepositoryBean
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {
<S extends T> S save(S entity);
<S extends T> Iterable<S> save(Iterable<S> entities);
T findOne(ID id);
boolean exists(ID id);
Iterable<T> findAll();
Iterable<T> findAll(Iterable<ID> ids);
long count();
void delete(ID id);
void delete(T entity);
void delete(Iterable<? extends T> entities);
void deleteAll();
}
PagingAndSortingRepositroy
接⼝ ,分页查询,和排序:
@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
//分类查询
Iterable<T> findAll(Sort sort);
//分页查询
Page<T> findAll(Pageable pageable);
}
JpaRepositroy
接⼝,提供实例查询⽅法
@NoRepositoryBean
public interface JpaRepository<T, ID extends Serializable>
extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
<S extends T> S saveAndFlush(S entity);
void deleteInBatch(Iterable<T> entities);
void deleteAllInBatch();
T getOne(ID id);
//实例查询
@Override
<S extends T> List<S> findAll(Example<S> example);
//实例查询,分类排序
@Override
<S extends T> List<S> findAll(Example<S> example, Sort sort);
}
SimpleRepository
实现类,增加了事务注解,进⾏事务管理,这就不介绍了,讲到⾃定义封装基类的时候会⽤到,⼀般都不会继承使⽤这个类.
使⽤
⾃定义⼀个PersonRepository接⼝继承上述任何⼀个接⼝都可以。不需要在接⼝上加@Repository注解,也不需要写实现类,即可在service,controller层注⼊使⽤,是不是很简洁。对于⼀般的修改保存操作,只要直接调⽤JPA接⼝提供的⽅法就可以⽤了,这⾥就不在介绍了。
entity层
Person实体类:
@Entity
public class Person {
private Integer id;
private String name;
private String password;
.....省略get set⽅法
}
持久层
PersonRepository 接⼝
下⾯介绍了JPA查询⽅法,条件查询,list集合查询,分页查询,排序查询,sql语句查询,指定字段查询,实例查询,基本上包含了实际开发中所需要的查询⽅法。
//省略了注释。
public interface PersonRepository extends JpaRepository<Person, Integer> {
//⾃定义查询,AND为jpa 关键字,相当于(where x.lastname = ?1 and x.firstname = ?2)
jpa关键字应该都要熟悉
Person findByNameAndPassword(String name ,String password);
//指定字段查询,只返回name
PersonName findById(Integer id);
//排序查询,返回list集合
List<Person> findByNameAndPassword(String name ,String password,Sort sort);
//分页查询查询计算元素总个数总页数,数据多的情况下,代价是昂贵的
Page<Person> findByNameAndPassword(String name ,String password,Pageable pageable);
//分页查询,返回的是⼀个⽚段,它只知道下⼀⽚段或者上⼀⽚段是否可⽤。
Slice<Person> findByNameAndPassword(String name,Pageable pageable);
//sql查询。?后⾯数字,对应⽅法中参数位置。使⽤原⽣sql语句
@Query("select p from person as p where p.name = ?1 and p.password = ?2 ",nativeQuery = true)
Person myfind(String name ,String password);
/
/实例查询
Person findByExample(Example example)
}
说明: spring data JPA 提供两种查询⽅式,⼀种就是直接从⽅法名中派⽣中查询(需要遵循它的规范,见下⽂ JPA 查询语句关键字)上⾯的例⼦就是这种⽅式;另⼀种就是⼿动定义查询了(使⽤JPA 核⼼类 EntityManager,下⽂⾃定义查询会介绍)。
Controller 层
@RestController public class TestController {
@Resource
private PersonRepository personRepository;
@GetMapping(value = "/test")
public String test(Integer personId){
Person p = personRepository.findByNameAndPassword("张三","123");
//排序
List<Person> p1 = personRepository.findByNameAndPassword("张三","123",
new Sort(Sort.Direction.ASC,"id"));
//分页
Page<Person> p2 = personRepository.findByNameAndPassword("张三",
"123", new PageRequest(1,10,new Sort("id")));
Person tempPerson=new Person();
tempPerson.setId(personId));
//通过实例查询
Person p3= personRepository.findByExample(Example.of(tempPerson))
return p+"+"+ p1 "+"+p2.getTotalElements()+"+"+p3;
}
JPA 查询语句关键字
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 findByFirstname,findByFirstnameIs,findByFirstnameEqual
s
… 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
GreaterThanEqua
l
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<Age> ages)… where x.age in ?1
NotIn findByAgeNotIn(Collection<Age> 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)
⾃定义查询(返回map集合)
上⾯的例⼦都是⼀些简单的查询,但实际开发中,我们可能会需要⽤到复杂的sq、连接查询或者需要
查询结果只包含我们需要的字段。如果实体之间的关联关系都配置得当的话,JPA提供的⽅法也可以满⾜我们的需求。当然我们也可以⾃定义⼀个继承JPA的模板类,然后封装查询的⽅法:
BaseRepository
创建⼀个BaseRepository ,定义两个sq语句查询:
/**
* repository 基类,封装⾃定义查询⽅法
*
* @author
* @date 2017/5/12 8:32
* @Package com.base
sql查询语句实例大全* @Version v1.0
*/
@NoRepositoryBean //该注解表⽰ spring 容器不会创建该对象
public interface BaseRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID>,JpaRepository<T,ID> {
/**
* sql查询
*
* @param sql
* @param args
* @return
*/
List<Map> findAllByParams(String sql, args);
/**
* sql分页查询
*
* @param sql
* @param args
* @return
*/
Page<Map> findPageByParams(String sql, Pageable pageable, args);
}
BaseRepositoryImpl
BaseRepositoryImpl 类,实现BaseRepository 接⼝:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论