第8章SpringBoot的数据访问_第1页
第8章SpringBoot的数据访问_第2页
第8章SpringBoot的数据访问_第3页
第8章SpringBoot的数据访问_第4页
第8章SpringBoot的数据访问_第5页
已阅读5页,还剩160页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第八章SpringBoot的数据访问授课教大连外国语大学本章目标掌握SpringDataJPA的解决方案掌握SpringBoot如何整合MyBatis了解SpringBoot如何整合REST了解SpringBoot如何整合MongoDB了解SpringBoot如何整合Redis理解数据缓存Cache的基本原理1本章内容28.1SpringDataJPA8.2SpringBoot整合MyBatis8.3REST8.4MongoDB8.5Redis8.6数据缓存Cache8.1SpringDataJPA8.1.1SpringBoot的支持8.1.2简单条件查询8.1.3关联查询8.1.4@8.1.5排序与分页查询3JPA(JaPersistenceAPI)是官方提出的Ja持久化规范。JPA通过注解或XML描述对象—关系(表)的映射关系,并将内存中的实体对象持久化到数据库。SpringDataJPA通过提供基于JPA的Repository极大地简化了JPA的写法,在几乎不写实现的情况下,实现数据库的访问和操作。使用SpringDataJPA建立数据访问层十分方便,只需要定义一个继承JpaRepository接口的接口即可。继承了JpaRepository接口的自定义数据访问接口,具有JpaRepository接口的所有数据访问操作方法。48.1SpringDataJPA8.1.1SpringBoot的支持在SpringBoot应用中,如果需要使用SpringDataJPA访问数据库,那么我们可以通过STS创建SpringBoot应用时选择SpringDataJPA模块依赖。51.JDBC的自动配置6spring-boot-starter-data-jpa依赖于spring-boot-starter-jdbc,而SpringBoot对spring-boot-starter-jdbc做了自动配置。JDBC自动配置源码位于org.springframework.boot.autoconfigure.jdbc包下。从该包的DataSourceProperties类可以看出,可以使用“spring.datasource”为前缀的属性在perties配置文件中配置datasource。2.JPA的自动配置SpringBoot对JPA的自动配置位于org.springframework.boot.autoconfigure.orm.jpa包下。从该包的HibernateJpaAutoConfiguration类可以看出,SpringBoot对JPA的默认实现是Hibernate;从该包的JpaProperties类可以看出,可以使用“spring.jpa”为前缀的属性在perties配置文件中配置JPA。73.SpringDataJPA的自动配置SpringBoot对SpringDataJPA的自动配置位于org.springframework.boot.autoconfigure.data.jpa包下。从该包的JpaRepositoriesAutoConfiguration类可以看出,JpaRepositoriesAutoConfiguration依赖于HibernateJpaAutoConfiguration配置;从该包的JpaRepositoriesRegistrar类可以看出,SpringBoot自动开启了对SpringData84.SpringBoot应用的SpringDataJPA从上述分析可知,在SpringBoot应用中使用SpringDataJPA访问数据库时,除了添加spring-boot-starter-data-jpa依赖外,只需定义DataSource、持久化实体类和数据访问层,并在需要使用数据访问的地方(如Service层)依赖注入数据访问层即可。98.1SpringDataJPA8.1.1SpringBoot的支持8.1.2简单条件查询8.1.3关联查询8.1.4@8.1.5排序与分页查询108.1.2简单条件查询只需定义一个继承JpaRepository接口的接口即可使用SpringDataJPA建立数据访问层。因此,自定义的数据访问接口完全继承了JpaRepository的接口方法。但更重要的是,在自定义的数据访问接口中可以根据查询关键字定义查询方法,这些查询方法需要符合它的命名规则,一般是根据持久化实体类的属性名来确定的。111.查询关键字12关键字示例JPQL代码段AndfindByLastnameAndFirstname…wherex.lastname=?1andx.firstname=?2OrfindByLastnameOrFirstname…wherex.lastname=?1orx.firstname=?2Is,EqualsfindByFirstname,findByFirstnameIs,findByFirstnameEquals…wherex.firstname=?1BetweenfindByStartDateBetween…wherex.startDatebetween?1and?2LessThanfindByAgeLessThan…wherex.age<?1LessThanEqualfindByAgeLessThanEqual…wherex.age<=?1GreaterThanfindByAgeGreaterThan…wherex.age>?1GreaterThanEqualfindByAgeGreaterThanEqual…wherex.age>=?1AfterfindByStartDateAfter…wherex.startDate>?1BeforefindByStartDateBefore…wherex.startDate<?1IsNullfindByAgeIsNull…wherex.ageisnullIsNotNull,NotNullfindByAge(Is)NotNull…wherex.agenotnullLikefindByFirstnameLike…wherex.firstnamelike?1NotLikefindByFirstnameNotLike…wherex.firstnamenotlike?1StartingWithfindByFirstnameStartingWith…wherex.firstnamelike?1参数后加%,即以参数开头的模糊查询EndingWithfindByFirstnameEndingWith…wherex.firstnamelike?1参数前加%,即以参数结尾的模糊查询ContainingfindByFirstnameContaining…wherex.firstnamelike?1参数两边加%,即包含参数的模糊查询OrderByfindByAgeOrderByLastnameDesc…wherex.age=?1orderbyx.lastnamedescNotfindByLastnameNot…wherex.lastname<>?1InfindByAgeIn(Collection<Age>ages)…wherex.agein?1NotInfindByAgeNotIn(Collection<Age>ages)…wherex.agenotin?1TruefindByActiveTrue()…wherex.active=trueFalsefindByActiveFalse()…wherex.active=falseIgnoreCasefindByFirstnameIgnoreCase…whereUPPER(x.firstame)=UPPER(?1)2.限制查询结果数量在SpringDataJPA中,使用Top和First关键字限制查询结果数量。13publicinterfaceUserRepositoryextendsJpaRepository<MyUser,Integer>{ /** *获得符合查询条件的前10条 */ publicList<MyUser>findTop10ByUnameLike(Stringuname); /** *获得符合查询条件的前15条 */ publicList<MyUser>findFirst15ByUnameLike(Stringuname);}3.简单条件查询示例【例8-1】使用SpringDataJPA进行简单条件查询。1)创建数据库本书采用的关系型数据库是MySQL5.x,我们为了演示本例,首先通过命令“CREATEDATABASEspringbootjpa;”创建名为springbootjpa的数据库。2)创建基于Thymeleaf和SpringDataJPA依赖的SpringBootWeb应用ch8_1143)修改pom.xml文件,添加MySQL依赖15<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-ja</artifactId> <version>5.1.45</version></dependency>4)设置Web应用ch8_1的上下文路径及数据源配置信息16server.servlet.context-path=/ch8_1spring.datasource.url=jdbc:#数据库MySQL为8.x时,url为#jdbc:#数据库用户名spring.datasource.username=root#数据库密码spring.datasource.password=root#数据库驱动spring.datasource.driver-class-name.mysql.jdbc.Driver#数据库MySQL为8.x时,驱动类.mysql.cj.jdbc.Driverspring.jpa.database=MYSQL#指定是否在日志中显示SQL语句spring.jpa.show-sql=true#不存在就创建对应的表spring.jpa.hibernate.ddl-auto=update#让控制器输出的JSON字符串格式更美观spring.jackson.serialization.indent-output=true5)创建持久化实体类MyUser17@Entity@Table(name="user_table")publicclassMyUserimplementsSerializable{ privatestaticfinallongserialVersionUID=1L;

@Id @GeneratedValue(strategy=GenerationType.IDENTITY) privateintid;//主键

*某省市略,默认为属性名小写,如果属性名是词组,将在中间加上“_”。 */ privateStringuname; privateStringusex; privateintage;某省市略get和set方法}@@GeneratedValue注解默认使用主键生成方式为自增,如果是MySQL、SQLServer等关系型数据库可映射成一个递增的主键,如果是Oracle等关系型数据库hibernate将自动生成一个名为HIBERNATE_SEQUENCE的序列。update表示如果数据库中存在持久化类对应的表就不创建,不存在就创建对应的表spring.jpa.hibernate.ddl-auto=update6)创建数据访问层18/****因为SpringBoot自动配置了JpaRepository*/publicinterfaceUserRepositoryextendsJpaRepository<MyUser,Integer>{ publicMyUserfindByUname(Stringuname); publicList<MyUser>findByUnameLike(Stringuname);}由于UserRepository接口继承了JpaRepository接口,因此UserRepository接口中除了上述自定义的两个接口方法外(方法名命名规范参照表8.1),还拥有JpaRepository的接口方法。7)创建业务层创建名.ch.ch8_1.service的包,并在该包中创建UserService接口和接口的实现类UserServiceImpl。198)创建控制器类UserTestController创建名.ch.ch8_1.controller的包,并在该包中创建名为UserTestController的控制器类。209)整理脚本样式静态文件JS脚本、CSS样式、图片等静态文件默认放置在src/main/resources/static目录下,ch8_1应用引入的BootStrap和jQuery与【例7-5】中的一样,不再赘述。2110)创建View视图页面在src/main/resources/templates目录下,创建视图页面showAll.html和showAuser.html。2211)运行首先,运行Ch81Application主类。然后,访问“通过访问“23通过访问“24通过访问“25通过访问“268.1SpringDataJPA8.1.1SpringBoot的支持8.1.2简单条件查询8.1.3关联查询8.1.4@8.1.5排序与分页查询278.1.3关联查询在SpringDataJPA中有一对一、一对多、多对多等关系映射。一对一关系,在现实生活中是十分常见的。比如一个大学生只有一通,一通只属于一个大学生。再比如人与身份证的关系也是一对一的关系。在SpringDataJPA中,可用两种方式描述一对一关系映射。一种是通过外键的方式(一个实体通过外键关联到另一个实体的主键);一种是通过一表来保存两个实体一对一的关系。【例8-2】使用SpringDataJPA实现人与身份证的一对一关系映射。28首先,为【例8-2】创建基于SpringDataJPA依赖的SpringBootWeb应用ch8_2。ch8_2应用的数据库、pom.xml以及perties与ch8_1应用基本一样,不再赘述。291)创建持久化实体类30

和mappedBy。targetEntity属性:class类型属性。定义关系类的类型,默认是该成员属性对应的类类型,所以通常不需要提供定义。cascade属性:CascadeType[]类型。该属性定义类和类之间的级联关系。定义的级联关系将被容器视为对当前类对象及其关联类对象采取相同的操作,而且这种关系是递归调用的。cascade的值只能从CascadeType.PERSIST(级联新建)、CascadeType.REMOVE(级联删除)、CascadeType.REFRESH(级联刷新)、CascadeType.MERGE(级联更新)中选择一个或多个。还有一个选择是使用CascadeType.ALL,表示选择全部四项。FetchType.LAZY:懒加载,加载一个实体时,定义懒加载的属性不会数据库中加载。FetchType.EAGER:急加载,加载一个实体时,定义急加载的属性会立即从数据库中加载。optional=true,表示idCard属性可以为null,也就是允身份证,如未成年人没有身份证。@2)创建数据访问层31publicinterfaceIdCardRepositoryextendsJpaRepository<IdCard,Integer>{ /** *根据人员ID查询身份信息(关联查询,根据person属性的id) *相当于JPQL语句:selecticfromIdCardicwhereic.person.id=?1 */ publicIdCardfindByPerson_id(Integerid); /** *根据地址和身份证号查询身份信息 *相当于JPQL语句:selecticfromIdCardicwhereic.address=?1andic.code=?2 */ publicList<IdCard>findByAddressAndCode(Stringaddress,Stringcode);}按照SpringDataJPA的规则,查询两个有关联关系的对象,可以通过方法名中的“_”下划线来标识。如根据人员ID查询身份信息findByPerson_id。JPQL(JaPersistenceQueryLanguage)是一种和SQL非常类似的中间性和对象化查询语言,它最终被编译成针对不同底层数据库的SQL查询,从而屏蔽不同数据库的差异。JPQL语句可以是select语句、update语句或delete语句,它们都通过Query接口封装执行。2)创建数据访问层32publicinterfacePersonRepositoryextendsJpaRepository<Person,Integer>{ /** *根据身份证ID查询人员信息(关联查询,根据idCard属性的id) *相当于JPQL语句:selectpfromPersonpwherep.idCard.id=?1 */ publicPersonfindByIdCard_id(Integerid); /** *根据人名和性别查询人员信息 *相当于JPQL语句:selectpfromPersonpwherep.pname=?1andp.psex=?2 */ publicList<Person>findByPnameAndPsex(Stringpname,Stringpsex);}3)创建业务层创建名.ch.ch8_2.service的包,并在该包中创建名为PersonAndIdCardService的接口和接口实现类PersonAndIdCardServiceImpl。334)创建控制器类创建名.ch.ch8_2.controller的包,并在该包中创建名为TestOneToOneController的控制器类。345)运行首先,运行Ch82Application主类。然后,访问““通过“355)运行通过“36@ManyToOne在SpringData@@ManyToOne。在JPA规范中,一对多的双向关系由多端(如Article)来维护。就是说多端为关系的维护端,负责关系的增删改查。一端则为关系的被维护端,不能维护关系。@@【例8-3】使用SpringDataJPA实现Author与Article的一对多关系映射。371)添加hibernate-validator依赖因为在持久化实体类中,使用hibernate-validator约束数据表,所以需要在ch8_2应用的pom.xml文件中添加hibernate-validator依赖。38<dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId></dependency>2)创建持久化实体类.ch.ch8_2.entity包中,创建名为Author和Article的持久化实体类。393)创建数据访问层40publicinterfaceAuthorRepositoryextendsJpaRepository<Author,Integer>{ /** *根据文章标题包含的内容,查询询) *相当于JPQL语句:selectafromAuthorainnerjoina.articleListtwheret.titlelike%?1% */ publicAuthorfindByArticleList_titleContaining(Stringtitle);}publicinterfaceArticleRepositoryextendsJpaRepository<Article,Integer>{ /** *根据文章信息(关联查询,根据author属性的id) *相当于JPQL语句:selectafromArticleawherea.author.id=?1 */ publicList<Article>findByAuthor_id(Integerid); /** *根据章信息(关联查询,根据author属性的aname) *相当于JPQL语句:selectafromArticleawherea.author.aname=?1 */ publicList<Article>findByAuthor_aname(Stringaname);}4)创建业务层.ch.ch8_2.service包中,创建名为AuthorAndArticleService的接口和接口实现类AuthorAndArticleServiceImpl。415)创建控制器类.ch.ch8_2.controller包中,创建名为TestOneToManyController的控制器类。426)运行首先,运行Ch82Application主类。然后,访问“通过“436)运行通过“446)运行通过“45在SpringData【例8-4】使用SpringDataJPA实现用户(User)与权限(Authority)的多对多关系映射。461)创建持久化实体类.ch.ch8_2.entity包中,创建名为User和Authority的持久化实体类。472)创建数据访问层48publicinterfaceUserRepositoryextendsJpaRepository<User,Integer>{ /** *根据权限id查询拥有该权限的用户(关联查询) *相当于JPQL语句:selectufromUseruinnerjoinu.authorityListawherea.id=?1 */ publicList<User>findByAuthorityList_id(intid); /** *根据权限名查询拥有该权限的用户(关联查询) *相当于JPQL语句:selectufromUseruinnerjoinu.authorityListawhere=?1 */ publicList<User>findByAuthorityList_name(Stringname);}publicinterfaceAuthorityRepositoryextendsJpaRepository<Authority,Integer>{ /** *根据用户id查询用户所拥有的权限(关联查询) *相当于JPQL语句:selectafromAuthorityainnerjoina.userListuwhereu.id=?1 */ publicList<Authority>findByUserList_id(intid); /** *根据用户名查询用户所拥有的权限(关联查询) *相当于JPQL语句:selectafromAuthorityainnerjoina.userListuwhereu.username=?1 */ publicList<Authority>findByUserList_Username(Stringusername);}3)创建业务层.ch.ch8_2.service包中,创建名为UserAndAuthorityService的接口和接口实现类UserAndAuthorityServiceImpl。494)创建控制器类.ch.ch8_2.controller包中,创建名为TestManyToManyController的控制器类。505)运行首先,运行Ch82Application主类。然后,访问“然后可以通过“51?请思考如何才能摆脱查询关键字和关联查询命名规范约束呢?8.1SpringDataJPA8.1.1SpringBoot的支持8.1.2简单条件查询8.1.3关联查询8.1.4@8.1.5排序与分页查询528.1.4@53publicinterfaceAuthorityRepositoryextendsJpaRepository<Authority,Integer>{ /** *根据用户名查询用户所拥有的权限(关联查询) */

@Query("selectafromAuthorityainnerjoina.userListuwhereu.username=?1") publicList<Authority>findByUserListUsername(Stringusername);}54/***根据文章信息(标题和内容)*/@Query("selectnewMap(a.titleastitle,a.contentascontent)fromArticleawherea.author.id=?1")publicList<Map<String,Object>>findTitleAndContentByAuthorId(Integerid);Object>>对象。/***根据id查询文章信息*/@Query("selectafromArticleawherea.author.aname=:aname1anda.author.id=:id1")publicList<Article>Stringaname,@Param("id1")Integerid);DataJPA还支持使用名称来获取参数值,使用格式为“:参数名称”。55/***根据作者*/@Transactional@Modifying@Query("deletefromAuthorawherea.id=?1")publicintdeleteAuthorByAuthorId(intid);@Query注解组合定义在数据访问接口方法上,进行更新查询操作

@Modifying注解的使用方法。

首先,为【例8-5】创建基于SpringDataJPA依赖的SpringBootWeb应用ch8_3。ch6_3应用的数据库、pom.xml以及perties与ch8_2应用基本一样,不再赘述。1)创建持久化实体类创建名.ch.ch8_3.entity的包,并在该包中创建名为Article和Author的持久化实体类。具体代码分别与ch8_2应用的Article和Author的代码一样,不再赘述。562)创建数据访问层57publicinterfaceArticleRepositoryextendsJpaRepository<Article,Integer>{ /** *根据文章信息(标题和内容) */

@Query("selectnewMap(a.titleastitle,a.contentascontent)fromArticleawherea.author.id=?1") publicList<Map<String,Object>>findTitleAndContentByAuthorId(Integerid); /** *根据id查询文章信息 */

@Query("selectafromArticleawherea.author.aname=:aname1anda.author.id=:id1") publicList<Article>Stringaname,@Param("id1")Integerid); /** *根据章 */ @Transactional

@Modifying @Query("deletefromArticleawherea.author.id=:id1") publicintIntegerid);}2)创建数据访问层58publicinterfaceAuthorRepositoryextendsJpaRepository<Author,Integer>{ /** *根据文章标题包含的内容,查询询) */

@Query("selectafromAuthorainnerjoina.articleListtwheret.titlelike%?1%") publicAuthorfindAuthorByArticleListtitleContaining(Stringtitle);}3)创建业务层创建名.ch.ch8_3.service的包,并在该包中创建名为AuthorAndArticleService的接口和接口实现类AuthorAndArticleServiceImpl。594)创建控制器类创.ch.ch8_3.controller的包,并在该包中创建名为TestOneToManyController的控制器类。605)运行首先,运行Ch83Application主类。然后,通过“618.1SpringDataJPA8.1.1SpringBoot的支持8.1.2简单条件查询8.1.3关联查询8.1.4@8.1.5排序与分页查询628.1.5排序与分页查询63publicinterfaceAuthorRepositoryextendsJpaRepository<Author,Integer>{ List<Author>findByAnameContaining(Stringaname,Sortsort);}publicList<Author>findByAnameContaining(Stringaname,StringsortColum){ //按sortColum降序排序 returnauthorRepository.findByAnameContaining(aname,Sort.by(Direction.DESC,sortColum));}Page<Author>pageData=authorRepository.findAll(PageRequest.of(1,size,Sort.by(Direction.DESC,"id")));//获得当前页面的记录List<Author>allAuthor=pageData.getContent();model.addAttribute("allAuthor",allAuthor);//获得总记录数model.addAttribute("totalCount",pageData.getTotalElements());//获得总页数model.addAttribute("totalPage",pageData.getTotalPages());8.1.5排序与分页查询【例8-6】排序与分页查询的使用方法。首先,为【例8-6】创建基于Thymeleaf和SpringDataJPA依赖的SpringBootWeb应用ch8_4。ch8_4应用的数据库、pom.xml、perties以及静态资源等内容与ch8_1应用基本一样,不再赘述。641.创建持久化实体类创建名.ch.ch8_4.entity的包,并在该包中创建名为Article和Author的持久化实体类。具体代码分别与ch8_2应用的Article和Author的代码一样,不再赘述。652.创建数据访问层66publicinterfaceAuthorRepositoryextendsJpaRepository<Author,Integer>{ /** *查询ame的排序 */ List<Author>findByAnameContaining(Stringaname,Sortsort);}3.创建业务层67@ServicepublicclassArticleAndAuthorServiceImplimplementsArticleAndAuthorService{ @Autowired privateAuthorRepositoryauthorRepository; @Override publicList<Author>findByAnameContaining(Stringaname,StringsortColum){ //按sortColum降序排序 returnauthorRepository.findByAnameContaining(aname,Sort.by(Direction.DESC,sortColum)); } @Override publicStringfindAllAuthorByPage(Integerpage,Modelmodel){ if(page==null){//第一次访问findAllAuthorByPage方法时 page=1; } intsize=2;//每页显示2条//分页查询,of方法的第一个参数代表第几页(比实际小1),第二个参数代表页面大小,第三个参数代表排序规则 Page<Author>pageData=

authorRepository.findAll(PageRequest.of(1,size,Sort.by(Direction.DESC,"id"))); //获得当前页面数据并转换成List<Author>,转发到视图页面显示 List<Author>allAuthor=pageData.getContent(); model.addAttribute("allAuthor",allAuthor); //共多少条记录 model.addAttribute("totalCount",pageData.getTotalElements()); //共多少页 model.addAttribute("totalPage",pageData.getTotalPages()); //当前页 model.addAttribute("page",page); return"index"; }}4.创建控制器类68@ControllerpublicclassTestSortAndPage{ @Autowired privateArticleAndAuthorServicearticleAndAuthorService; @RequestMapping("/findByAnameContaining") @ResponseBody publicList<Author>findByAnameContaining(Stringaname,StringsortColum){ returnarticleAndAuthorService.findByAnameContaining(aname,sortColum); } @RequestMapping("/findAllAuthorByPage") /** *@parampage第几页 */ publicStringfindAllAuthorByPage(Integerpage,Modelmodel){ returnarticleAndAuthorService.findAllAuthorByPage(page,model); }}5.创建View视图页面在src/main/resources/templates目录下,创建视图页面index.html。696.运行首先,运行Ch84Application主类。然后,通过“706.运行通过“71本章内容728.1SpringDataJPA8.2SpringBoot整合MyBatis8.3REST8.4MongoDB8.5Redis8.6数据缓存Cache8.2SpringBoot整合MyBatis我们在第三章已学习SSM框架整合开发的流程,那么SpringBoot如何整合MyBatis呢?【例8-7】在SpringBoot应用中使用MyBatis框架操作数据库(基于XML的映射配置)。731.创建SpringBootWeb应用在创建SpringBootWeb应用ch8_5时,选择MyBatisFramework依赖。742.修改pom.xml文件在pom.xml文件中添加MySQL连接器依赖。75<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-ja</artifactId> <version>5.1.45</version></dependency>3.设置Web应用ch8_5的上下文路径及数据源配置信息76server.servlet.context-path=/ch8_5#数据库地址spring.datasource.url=jdbc:#数据库用户名spring.datasource.username=root#数据库密码spring.datasource.password=root#数据库驱动spring.datasource.driver-class-name.mysql.jdbc.Driver#设置包别名(在Mapper映射文件中直接使用实体类名)mybatis.type-aliases-package.ch.ch8_5.entity#告诉系统在哪里去找mapper.xml文件(映射文件)mybatis.mapperLocations=classpath:mappers/*.xml#在控制台输出SQL语句日志logging.level.ch.ch8_5.repository=debug#让控制器输出的JSON字符串格式更美观spring.jackson.serialization.indent-output=true4.创建实体类77package.ch.ch8_5.entity;publicclassMyUser{ privateIntegerid; privateStringusername; privateStringpassword;某省市略get和set方法}5.创建数据访问接口78@RepositorypublicinterfaceMyUserRepository{ publicList<MyUser>findAll();}@@MapperScan注解,

@MapperScan两者用其一即可6.创建Mapper映射文件

79<mappernamespace=.ch.ch8_5.repository.MyUserRepository"> <selectid="findAll"resultType="MyUser"> select*fromuser </select></mapper>在src/main/resources目录下,创建名为mappers的包,并在该包中创建SQL映射文件MyUserMapper.xml7.创建业务层创建名.ch.ch8_5.service的包,并在该包中创建MyUserService接口和MyUserServiceImpl实现类。80@ServicepublicclassMyUserServiceImplimplementsMyUserService{ @Autowired privateMyUserRepositorymyUserRepository; @Override publicList<MyUser>findAll(){ returnmyUserRepository.findAll(); }}8.创建控制器类MyUserController创建名.ch.ch8_5.controller的包,并在该包中创建控制器类MyUserController。81@RestControllerpublicclassMyUserController{ @Autowired privateMyUserServicemyUserService; @RequestMapping("/findAll") publicList<MyUser>findAll(){ returnmyUserService.findAll(); }}9.在应用程序的主类中扫描Mapper接口82@SpringBootApplication//配置扫描MyBatis接口的包路径@MapperScan(basePackages={.ch.ch8_5.repository"})publicclassCh85Application{ publicstaticvoidmain(String[]args){ SpringApplication.run(Ch66Application.class,args); }}10.运行首先,运行Ch85Application主类。然后,访问“83本章内容848.1SpringDataJPA8.2SpringBoot整合MyBatis8.3REST8.4MongoDB8.5Redis8.6数据缓存Cache8.3REST8.3.1REST简介8.3.2SpringBoot整合REST8.3.3SpringDataREST8.3.4REST服务测试858.3.1REST简介REST是一组架构约束条件和原则。这些约束有:1.使用客户/服务器模型。客户和服务器之间通过一个统一的接口来互相通讯。2.层次化的系统。在一个REST系统中,客户端并不会固定地与一个服务器打交道。3.无状态。在一个REST系统中,服务端并不会保存有关客户的任何状态。也就是说,客户端自身负责用户状态的维持,并在每次发送请求时都需要提供足够的信息。4.可缓存。REST系统需要能够恰当地缓存请求,以尽量减少服务端和客户端之间的信息传输,以提高性能。5.统一的接口。一个REST系统需要使用一个统一的接口来完成子系统之间以及服务与用户之间的交互。这使得REST系统中的各个子系统可以独自完成演化。86满足这些约束条件和原则的应用程序或设计就是RESTful。需要注意的是,REST是设计风格而不是标准。REST通常基于HTTP、URI、XML以及HTML这些现有的广泛流行的协议和标准。资源(Resources)“表现层状态转化”中的“表现层”其实指的是“资源”的“表现层”。“资源”就是网络上的一个实体,或者说是网络上的一个具体信息。“资源”可以是一段文本、一、一段视频,总之就是一个具体的实体。我们可以使用一个URI(统一资源定位符)指向资源,每种资源对应一个特定的URI。我们需要获取资源时,访问它的URI即可,因此URI是每个资源的地址或独一无二的标识符。REST风格的Web服务,是通过一个简洁清晰的URI来提供资源链接,客户端通过对URI发送HTTP请求获得这些资源,而获取和处理资源的过程让客户端应用的状态发生改变。87表现层(Representation)“资源”是一种信息实体,可以有多种外在的表现形式。我们将“资源”呈现出来的形式称为它的“表现层”。例如,文本可以使用txt格式表现,也可以使用XML格式、JSON格式表现。88状态转化(StateTransfer)客户端访问一个网站,就代表了它和服务器的一个互动过程。在这个互动过程中,将涉及数据和状态的变化。我们知道HTTP协议是一个无状态的通信协议,这意味着所有状态都保存在服务器端。因此,如果客户端操作服务器,需要通过某种手段(如HTTP协议)让服务器端发生“状态变化”。而这种转化是建立在表现层之上的,所以就是“表现层状态转化”。89架构风格在流行的各种Web框架中,包括SpringBoot都支持REST开发。REST并不是一种技术或者规范,而是一种架构风格,包括了如何标识资源、如何标识操作接口及操作的版本、如何标识操作的结果等,主要内容如下:901.使用“api”作为上下文在REST架构中,建议使用“api”作为上下文,示例如下;2.增加一个版本标识在REST架构中,可以通过URL标识版本信息,示例如下:3.标识资源在REST架构中,可以将资源名称放到URL中,示例如下:4.确定HTTPMethodHTTP协议有5个常用的表示操作方式的动词:GET、POST、PUT、DELETE、PATCH。它们分别对应5种基本操作:GET用来获取资源,POST用来增加资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源,PATCH用来更新资源的部分属性。示例如下:911)新增用户POST2)查询id为123的用户GET3)更新id为123的用户PUT4)删除id为123的用户DELETE5.确定HTTPStatus92服务器向用户返回的状态码和提示信息,常用的如下:1)200OK-[GET]:服务器成功返回用户请求的数据。2)201CREATED-[POST/PUT/PATCH]:用户新建或修改数据成功。3)202Accepted-[*]:表示一个请求已经进入后台排队(异步任务)。4)204NOCONTENT-[DELETE]:用户删除数据成功。5)400INVALIDREQUEST-[POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作。6)401Unauthorized-[*]:表示用户没有权限(令牌、用户名、密码错误)。7)403Forbidden-[*]表示用户得到授权(与401错误相对),但是访问是被禁止的。8)404NOTFOUND-[*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作。9)406NotAcceptable-[GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。10)410Gone-[GET]:用户请求的资源被永久删除,且不会再得到的。11)422Unprocesableentity-[POST/PUT/PATCH]:当创建一个对象时,发生一个验证错误。

12)500INTERNALSERVERERROR-[*]:服务器发生错误,用户将无法判断发出的请求是否成功。8.3REST8.3.1REST简介8.3.2SpringBoot整合REST8.3.3SpringDataREST8.3.4REST服务测试938.3.2SpringBoot整合REST在SpringBoot的Web应用中,自动支持REST。也就是说,只要spring-boot-starter-web依赖在pom.xml中,就支持REST。【例8-8】一个RESTful应用示例假如,在ch8_2应用的控制器类TestOneToManyController中有如下处理方法:94@RequestMapping("/findArticleByAuthor_id1/{id}")publicList<Article>Integerid){ returnauthorAndArticleService.findByAuthor_id(id);}@@PathVariable不用指定名称。8.3REST8.3.1REST简介8.3.2SpringBoot整合REST8.3.3SpringDataREST8.3.4REST服务测试958.3.3SpringDataRESTSpringBoot对SpringDataREST的自动配置位于org.springframework.boot.autoconfigure.data.rest包中。通过SpringBootRepositoryRestConfigurer类的源码可以得出,SpringBoot已经自动配置了RepositoryRestConfiguration,所以在SpringBoot应用中使用SpringDataREST只需引入spring-boot-starter-data-rest的依赖即可使用。【例8-9】SpringDataREST的构建过程。96971.创建SpringBoot应用ch8_6创建SpringBoot应用ch8_6,依赖为SpringDataJPA和RestRepositories。2.修改pom.xml文件,添加MySQL依赖修改应用ch8_6的pom.xml文件,添加MySQL依赖。SpringDataREST的构建过程3.设置应用ch8_6的上下文路径及数据源配置信息98server.servlet.context-path=/api#数据库地址spring.datasource.url=jdbc:#数据库用户名spring.datasource.username=root#数据库密码spring.datasource.password=root#数据库驱动spring.datasource.driver-class-name.mysql.jdbc.Driver#指定数据库类型spring.jpa.database=MYSQL#指定是否在日志中显示SQL语句spring.jpa.show-sql=true#指定自动创建、更新数据库表等配置,update表示如果数据库中存在持久化类对应的表就不创建,不存在就创建对应的表spring.jpa.hibernate.ddl-auto=update#让控制器输出的JSON字符串格式更美观spring.jackson.serialization.indent-output=true4.创建持久化实体类Student99@Entity@Table(name="student_table")publicclassStudentimplementsSerializable{ privatestaticfinallongserialVersionUID=1L; @Id @GeneratedValue(strategy=GenerationType.IDENTITY) privateintid;//主键 privateStringsno; privateStringsname; privateStringssex; publicStudent(){ super(); }某省市略set和get方法}5.创建数据访问层100publicinterfaceStudentRepositoryextendsJpaRepository<Student,Integer>{ /** *自定义接口查询方法,暴露为REST资源 */

@RestResource(path="snameStartsWith",rel="snameStartsWith") List<Student>Stringsname);}至此,基于SpringData的REST资源服务已经构建完毕,接下来就是使用REST客户端测试此服务。8.3REST8.3.1REST简介8.3.2SpringBoot整合REST8.3.3SpringDataREST8.3.4REST服务测试1018.3.4REST服务测试在Web和某著名企业端开发时,常常会调用服务器端的RESTful接口进行数据请求,为了调试,一般会先用工具进行测试,通过测试后才开始在开发中使用。本节将介绍如何使用GoogleChrome的PostmanRESTClient进行8.3.3节的RESTful接口请求测试。1021.获得列表数据在RESTful架构中,每个rce),所以,而且所用的名词往往与实体名对应。一般来说,数据库中的表都是同种记录的“集合”(collection),所以API中的名词也应该使用复数,如students。运行ch8_6的主类Ch86Application后,我们手工在student_table添加几条学生信息后,在PostmanRESTClient中,使用GET方式访问“1031.获得列表数据1042.获得单一对象在PostmanRESTClient中,使用GET方式访问“1053.查询在PostmanRESTClient中,search调用自定义的接口查询方法。因此,可以使用GET访问“Stringsname)接口方法,获得姓名前缀为“陈”的学生信息。1064.分页查询在PostmanRESTClient中,使用GET方式访问“1075.排序在PostmanRESTClient中,使用GET方式访问“1086.保存在PostmanRESTClient中,发起POST方式请求109发起POST请求实现新增功能保存成功7.更新假如,我们需要更新新增的id为5的数据,可以在PostmanRESTClient中,使用PUT方式访问“110发起PUT请求实现更新功能更新成功8.删除假如,我们需要删除新增的id为5的数据,可以在PostmanRESTClient中,使用DELETE方式访问“111本章内容1128.1SpringDataJPA8.2SpringBoot整合MyBatis8.3REST8.4MongoDB8.5Redis8.6数据缓存Cache8.4MongoDB8.4.1安装MongoDB8.4.2SpringBoot整合MongoDB8.4.3增删改查1138.4.1安装MongoDB可以从官方网站可以使用MongoDB的图形界面管理工具MongoDBpass可视化操作MongoDB数据库。可以使用mongodb-win32-x86_64-2012plus-4.2.0-signed.msi自带的MongoDBpass,也可以从官方网站1148.4MongoDB8.4.1安装MongoDB8.4.2SpringBoot整合MongoDB8.4.3增删改查1158.4.2SpringBoot整合MongoDB1.Spring对MongoDB的支持Spring对MongoDB的支持主要是通过SpringDataMongoDB实现的,SpringDataMongoDB为我们提供了如下功能。1)对象/文档映射注解116注解含义@Document映射领域对象与MongoDB的一个文档@Id映射当前属性是文档对象ID@DBRef当前属性将参考其他文档@Field为文档的属性定义名称@Version将当前属性作为版本1.Spring对MongoDB的支持1172)MongoTemplate与JdbcTemplate一样,SpringDataMongoDB也提供了一个MongoTemplate,并提供了数据访问的方法。3)Repository类似于SpringDataJPA,SpringDataMongoDB也提供了Repository的支持,使用方式和SpringDataJPA一样,示例如下:publicinterfacePersonRepositoryextendsMongoRepository<Person,String>{}2.SpringBoot对MongoDB的支持SpringBoot对MongoDB的自动配置位于org.springframework.boot.autoconfigure.mongo包中。主要配置了数据库连接、MongoTemplate,我们可以在配置文件中使用以“spring.data.mongodb”为前缀的属性来配置MongoDB的相关信息。SpringBoot对MongoDB提供了一些默认属性,如默认端口号为27017、默认服务器为localhost、默认数据库为test、默认无用户名和无密码访问方式,并默认开启了对Repository的支持。因此,我们在SpringBoot应用中,只需引入spring-boot-starter-data-mongodb依赖即可按照默认配置操作MongoDB数据库。1188.4MongoDB8.4.1安装MongoDB8.4.2SpringBoot整合MongoDB8.4.3增删改查1198.4.3增删改查【例8-10】在SpringBoot应用中,对MongoDB数据库的增删改查。1201.创建基于spring-boot-starter-data-mongodb依赖的SpringBootWeb应用ch8_7创建基于spring-boot-starter-data-mongodb依赖的SpringBootWeb应用ch8_7。2.配置perties文件在应用ch8_7中,使用MongoDB的默认数据库连接。所以,不需要在perties文件中配置数据库连接信息。perties文件的其它内容配置如下:server.servlet.context-path=/ch8_7#让控制器输出的JSON字符串格式更美观spring.jackson.serialization.indent-output=true3.创建领域模型1214.创建数据访问接口创建名.ch.ch8

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论