Spring Data Repository有趣的定义query方法
2016-07-05 16:20
537 查看
学习了Spring的一个小tutorial: Accessing Data with GemFire。我们为自定义的数据对象建立Repository,作为管理数据对象的接口。通常,我们继承Spring框架的CrudRepository接口,它为我们的Repository提供了基本的CRUD(增删改查)功能。
自定义的Repository如下:
非常有趣的地方在于,以上就是我们要定义的全部了!定义一个Repository接口,写上几个接口方法名,然后,你就能使用这些接口方法了!下面就讲讲Spring Data Repository怎么样根据方法名来生成query的!
以下都是参考的Spring Data JPA - Reference Documentation中的4.4 Defining Query Methods。
例一:
以上可以看到,SQL中的AND, OR, ASC, DESC, ORDER BY, IGNORE CASE, ALL IGNORE CASE, DISTINCT都可用。
例二
例三
由于我不完全懂Pageable在此的用法,所以只能直译一段原文说明:
第一个方法允许你向query方法中传入一个org.springframework.data.domain.Pageable实例,以动态地向你静态定义的query中添加分页(paging)。一个Page知道available的元素和业的总数。它能做到,是通过infrastructure生成一个计数query,来计算总数。基于所用的存储,这可能成本高,此时可以使用Slice。Slice只知道是不是有下一个Slice,这在遍历一个大结果集时已足够。
不过在返回List时使用Sort和Pageable的区别我暂不清楚。
返回Page接口、Slice接口、List三种接口有哪些显著的利弊呢?这里只介绍一下三者的关系吧:
Slice继承了Iterable,Page继承了Slice。
Slice: A slice of data that indicates whether there’s a next or previous slice available. Allows to obtain a Pageable to request a previous or next Slice.
Page: A page is a sublist of a list of objects. It allows gain information about the position of it in the containing entire list.
Page有三个新方法,getTotalElements()返回元素总数,getTotalPages()返回总页数。可以感到,Page像是个容器,而Slice像只是个迭代器。
例四:
例五
哈!多线程中。Spring的Repository query有异步执行的能力。 此时,query方法被调用后会立刻返回,但是实际的query执行发生在一个Spring TaskExecutor里,此query任务已被提交给它。一个Spring TaskExecutor么,就是一个线程。
自定义的Repository如下:
public interface PersonRepository extends CrudRepository<Person, String> { //The repository proxy can understand what "findByName", //"findByAgeGreaterThan", "findByAgeLessThan",etc. mean! Person findByName(String name); Iterable<Person> findByAgeGreaterThan(int age); Iterable<Person> findByAgeLessThan(int age); Iterable<Person> findByAgeGreaterThanAndAgeLessThan(int age1, int age2); }
非常有趣的地方在于,以上就是我们要定义的全部了!定义一个Repository接口,写上几个接口方法名,然后,你就能使用这些接口方法了!下面就讲讲Spring Data Repository怎么样根据方法名来生成query的!
以下都是参考的Spring Data JPA - Reference Documentation中的4.4 Defining Query Methods。
例一:
public interface PersonRepository extends Repository<User, Long> { //Spring会把find…By, read…By, query…By, count…By和get…By这些前缀去掉,而只处理之后的字符串。例如,以下方法名,在Spring看来,就是EmailAddressAndLastname而已。 //而And和Or都被作为保留关键字,并起到SQL中AND和OR的作用。 //当然,你定义的Person对象,必须含有emailAddress和lastname属性,否则Spring找不到这些属性就会出错。 List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname); // Enables the distinct flag for the query //在find和By之间可以使用Distinct关键词。 List<Person> findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname); List<Person> findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname); //忽略大小写要放在最后,IgnoreCase和AllIgnoreCase // Enabling ignoring case for an individual property List<Person> findByLastnameIgnoreCase(String lastname); // Enabling ignoring case for all suitable properties List<Person> findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname); // Enabling static ORDER BY for a query List<Person> findByLastnameOrderByFirstnameAsc(String lastname); List<Person> findByLastnameOrderByFirstnameDesc(String lastname); }
以上可以看到,SQL中的AND, OR, ASC, DESC, ORDER BY, IGNORE CASE, ALL IGNORE CASE, DISTINCT都可用。
例二
//如果Person有Address属性,而Address有ZipCode属性,那么以下方法名仍能生成你心里想着的query。过程如下: //1.Spring在Person里找AddressZipCode属性,没找到 //2.Spring按驼峰从右往左分割,第一次,它分割为AddressZip和Code,但还是没找到AddressZip属性。 //3.Spring将分割点左移,分割为Address和ZipCode,它在Person找到了Address属性,又在Address中找到了ZipCode属性,成功。 List<Person> findByAddressZipCode(ZipCode zipCode); //以上仍可能出错,例如Person有Address,AddressZip属性,而Address有ZipCode属性,AddressZip没有Code属性,那么Spring匹配进AddressZip里边,结果没找到Code,就失败。 //更好的方法是用下划线,下划线被Spring保留为分隔符,Address_ZipCode直接被分割成Address和ZipCode,绝不会被分割成Address_Zip和Code。 //既然如此,也要求我们在定义Person,Address类时,属性名不要使用下划线,而使用纯正的驼峰命名。 List<Person> findByAddress_ZipCode(ZipCode zipCode);
例三
Page<User> findByLastname(String lastname, Pageable pageable); Slice<User> findByLastname(String lastname, Pageable pageable); List<User> findByLastname(String lastname, Sort sort); List<User> findByLastname(String lastname, Pageable pageable);
由于我不完全懂Pageable在此的用法,所以只能直译一段原文说明:
第一个方法允许你向query方法中传入一个org.springframework.data.domain.Pageable实例,以动态地向你静态定义的query中添加分页(paging)。一个Page知道available的元素和业的总数。它能做到,是通过infrastructure生成一个计数query,来计算总数。基于所用的存储,这可能成本高,此时可以使用Slice。Slice只知道是不是有下一个Slice,这在遍历一个大结果集时已足够。
不过在返回List时使用Sort和Pageable的区别我暂不清楚。
返回Page接口、Slice接口、List三种接口有哪些显著的利弊呢?这里只介绍一下三者的关系吧:
Slice继承了Iterable,Page继承了Slice。
Slice: A slice of data that indicates whether there’s a next or previous slice available. Allows to obtain a Pageable to request a previous or next Slice.
Page: A page is a sublist of a list of objects. It allows gain information about the position of it in the containing entire list.
Page有三个新方法,getTotalElements()返回元素总数,getTotalPages()返回总页数。可以感到,Page像是个容器,而Slice像只是个迭代器。
例四:
//Frist和Top是一个意思,如果不填数字,就是1 //虽然OrderBy里也有By,但Spring只找到第一个By,然后去掉 User findFirstByOrderByLastnameAsc(); User findTopByOrderByAgeDesc(); Page<User> queryFirst10ByLastname(String lastname, Pageable pageable); Slice<User> findTop3ByLastname(String lastname, Pageable pageable); List<User> findFirst10ByLastname(String lastname, Sort sort); List<User> findTop10ByLastname(String lastname, Pageable pageable);
例五
@Async Future<User> findByFirstname(String firstname); 1 @Async CompletableFuture<User> findOneByFirstname(String firstname); 2 @Async ListenableFuture<User> findOneByLastname(String lastname);
哈!多线程中。Spring的Repository query有异步执行的能力。 此时,query方法被调用后会立刻返回,但是实际的query执行发生在一个Spring TaskExecutor里,此query任务已被提交给它。一个Spring TaskExecutor么,就是一个线程。
相关文章推荐
- 一个jar包里的网站
- 一个jar包里的网站之文件上传
- 一个jar包里的网站之返回对媒体类型
- Spring和ThreadLocal
- Spring Boot 开发微服务
- Spring AOP动态代理-切面
- Spring整合Quartz(JobDetailBean方式)
- Spring整合Quartz(JobDetailBean方式)
- 模拟Spring的简单实现
- Spring整合WebSocket应用示例(上)
- spring+html5实现安全传输随机数字密码键盘
- Spring中属性注入详解
- 监听器获取Spring配置文件的方法
- Java利用Sping框架编写RPC远程过程调用服务的教程
- springmvc 发送ajax出现中文乱码的解决方法汇总
- SpringMVC框架下JQuery传递并解析Json格式的数据是如何实现的
- 详解Java的MyBatis框架和Spring框架的整合运用
- struts2 spring整合fieldError问题
- spring的jdbctemplate的crud的基类dao