5SpringBoot五spring data jpa的使用Word文档格式.docx
《5SpringBoot五spring data jpa的使用Word文档格式.docx》由会员分享,可在线阅读,更多相关《5SpringBoot五spring data jpa的使用Word文档格式.docx(7页珍藏版)》请在冰豆网上搜索。
{}
2使用默认方法
@TestpublicvoidtestBaseQuery()throwsException{
Useruser=newUser();
userRepository.findAll();
userRepository.findOne(1l);
userRepository.save(user);
userRepository.delete(user);
userRepository.count();
userRepository.exists(1l);
//...}
就不解释了根据方法名就看出意思来
自定义简单查询
自定义的简单查询就是根据方法名来自动生成SQL,主要的语法是findXXBy,readAXXBy,queryXXBy,countXXBy,getXXBy后面跟属性名称:
UserfindByUserName(StringuserName);
也使用一些加一些关键字And、
Or
UserfindByUserNameOrEmail(Stringusername,Stringemail);
修改、删除、统计也是类似语法
LongdeleteById(Longid);
LongcountByUserName(StringuserName)
基本上SQL体系中的关键词都可以使用,例如:
LIKE、
IgnoreCase、
OrderBy。
List<
User>
findByEmailLike(Stringemail);
UserfindByUserNameIgnoreCase(StringuserName);
List<
findByUserNameOrderByEmailDesc(Stringemail);
具体的关键字,使用方法和生产成SQL如下表所示
Keyword
Sample
JPQLsnippet
And
findByLastnameAndFirstname
…wherex.lastname=?
1andx.firstname=?
2
findByLastnameOrFirstname
1orx.firstname=?
Is,Equals
findByFirstnameIs,findByFirstnameEquals
…wherex.firstname=?
1
Between
findByStartDateBetween
…wherex.startDatebetween?
1and?
LessThan
findByAgeLessThan
…wherex.age<
?
LessThanEqual
findByAgeLessThanEqual
…wherex.age⇐?
GreaterThan
findByAgeGreaterThan
…wherex.age>
GreaterThanEqual
findByAgeGreaterThanEqual
=?
After
findByStartDateAfter
…wherex.startDate>
Before
findByStartDateBefore
…wherex.startDate<
IsNull
findByAgeIsNull
…wherex.ageisnull
IsNotNull,NotNull
findByAge(Is)NotNull
…wherex.agenotnull
Like
findByFirstnameLike
…wherex.firstnamelike?
NotLike
findByFirstnameNotLike
…wherex.firstnamenotlike?
StartingWith
findByFirstnameStartingWith
1
(parameterboundwithappended
%)
EndingWith
findByFirstnameEndingWith
(parameterboundwithprepended
Containing
findByFirstnameContaining
(parameterboundwrappedin
OrderBy
findByAgeOrderByLastnameDesc
…wherex.age=?
1orderbyx.lastnamedesc
Not
findByLastnameNot
…wherex.lastname<
>
In
findByAgeIn(Collection
ages)
…wherex.agein?
NotIn
findByAgeNotIn(Collection
age)
…wherex.agenotin?
TRUE
findByActiveTrue()
…wherex.active=true
FALSE
findByActiveFalse()
…wherex.active=false
IgnoreCase
findByFirstnameIgnoreCase
…whereUPPER(x.firstame)=UPPER(?
1)
复杂查询
在实际的开发中我们需要用到分页、删选、连表等查询的时候就需要特殊的方法或者自定义SQL
分页查询
分页查询在实际使用中非常普遍了,springdatajpa已经帮我们实现了分页的功能,在查询的方法中,需要传入参数Pageable
当查询中有多个参数的时候Pageable建议做为最后一个参数传入
Page<
findALL(Pageablepageable);
Page<
findByUserName(StringuserName,Pageablepageable);
Pageable
是spring封装的分页实现类,使用的时候需要传入页数、每页条数和排序规则
@TestpublicvoidtestPageQuery()throwsException{
intpage=1,size=10;
Sortsort=newSort(Direction.DESC,"
id"
);
Pageablepageable=newPageRequest(page,size,sort);
userRepository.findALL(pageable);
userRepository.findByUserName("
testName"
pageable);
}
限制查询
有时候我们只需要查询前N个元素,或者支取前一个实体。
serfindFirstByOrderByLastnameAsc();
UserfindTopByOrderByAgeDesc();
queryFirst10ByLastname(Stringlastname,Pageablepageable);
findFirst10ByLastname(Stringlastname,Sortsort);
findTop10ByLastname(Stringlastname,Pageablepageable);
自定义SQL查询
其实Springdata觉大部分的SQL都可以根据方法名定义的方式来实现,但是由于某些原因我们想使用自定义的SQL来查询,springdata也是完美支持的;
在SQL的查询方法上面使用@Query注解,如涉及到删除和修改在需要加上@Modifying.也可以根据需要添加
@Transactional
对事物的支持,查询超时的设置等
@Modifying@Query("
updateUserusetu.userName=?
1wherec.id=?
2"
)intmodifyByIdAndUserId(StringuserName,Longid);
@Transactional@Modifying@Query("
deletefromUserwhereid=?
1"
)voiddeleteByUserId(Longid);
@Transactional(timeout=10)@Query("
selectufromUseruwhereu.emailAddress=?
)
UserfindByEmailAddress(StringemailAddress);
多表查询
多表查询在springdatajpa中有两种实现方式,第一种是利用hibernate的级联查询来实现,第二种是创建一个结果集的接口来接收连表查询后的结果,这里主要第二种方式。
首先需要定义一个结果集的接口类。
publicinterfaceHotelSummary{
CitygetCity();
StringgetName();
DoublegetAverageRating();
defaultIntegergetAverageRatingRounded(){
returngetAverageRating()==null?
null:
(int)Math.round(getAverageRating());
}
查询的方法返回类型设置为新创建的接口
@Query("
selecth.cityascity,h.nameasname,avg(r.rating)asaverageRating"
-"
fromHotelhleftouterjoinh.reviewsrwhereh.city=?
1groupbyh"
)Page<
HotelSummary>
findByCity(Citycity,Pageablepageable);
selecth.nameasname,avg(r.rating)asaverageRating"
fromHotelhleftouterjoinh.reviewsrgroupbyh"
findByCity(Pageablepageable);
使用
hotels=this.hotelRepository.findByCity(newPageRequest(0,10,Direction.ASC,"
name"
));
for(HotelSummarysummay:
hotels){
System.out.println("
Name"
+summay.getName());
在运行中Spring会给接口(HotelSummary)自动生产一个代理类来接收返回的结果,代码汇总使用getXX的形式来获取
多数据源的支持
同源数据库的多源支持
日常项目中因为使用的分布式开发模式,不同的服务有不同的数据源,常常需要在一个项目中使用多个数据源,因此需要配置spingdatajpa对多数据源的使用,一般分一下为三步:
∙1配置多数据源
∙2不同源的实体类放入不同包路径
∙3声明不同的包路径下使用不同的数据源、事务支持
这里有一篇文章写的很清楚:
SpringBoot多数据源配置与使用
异构数据库多源支持
比如我们的项目中,即需要对mysql的支持,也需要对mongodb的查询等。
实体类声明@Entity
关系型数据库支持类型、声明@Document
为mongodb支持类型,不同的数据源使用不同的实体就可以了
interfacePersonRepositoryextendsRepository<
Person,Long>
{
…}
@EntitypublicclassPerson{
interfaceUserRepositoryextendsRepository<
@DocumentpublicclassUser{
但是,如果User用户既使用mysql也使用mongodb呢,也可以做混合使用
interfaceJpaPersonRepositoryextendsRepository<
interfaceMongoDBPersonRepositoryextendsRepository<
@Entity@DocumentpublicclassPerson{
也可以通过对不同的包路径进行声明,比如A包路径下使用mysql,B包路径下使用mongoDB
@EnableJpaRepositories(basePackages="
com.neo.repositories.jpa"
)@EnableMongoRepositories(basePackages="
com.neo.repositories.mongo"
)interfaceConfiguration{}
其它
使用枚举
使用枚举的时候,我们希望数据库中存储的是枚举对应的String类型,而不是枚举的索引值,需要在属性上面添加@Enumerated(EnumType.STRING)
注解
@Enumerated(EnumType.STRING)@Column(nullable=true)privateUserTypetype;
不需要和数据库映射的属性
正常情况下我们在实体类上加入注解@Entity,就会让实体类和表相关连如果其中某个属性我们不需要和数据库来关联只是在展示的时候做计算,只需要加上@Transient属性既可。
@TransientprivateStringuserName;
源码案例
这里有一个开源项目几乎使用了这里介绍的所有标签和布局,大家可以参考:
cloudfavorites
参考
SpringDataJPA-ReferenceDocumentation
SpringDataJPA——参考文档中文版