springboot2.0
springboot2.0
一、版本依赖(版本号引用父类的依赖,自动配置)
1.如果要进行单独升级的话,可以单独添加版本号version
Http请求配置注解:
@SpringBootApplication(注解中包含好多元注解):声明该类是springboot项目的启动类
@Configuration+@EnableAutoConfiguration+@ConmponentScan
@RestController and @RequestMapping是springMVC的注解,不是springboot特有的
@RestController = @Controller+@ResponseBody
Http请求的get请求
Restful风格
@RequestMapping(还需要配置请求方式)
@GetMapping(如果value值中参数是请求类型是“{xxx}/{xxx}”这种形式,则请求的url拼接参数方式是:/xxx/xxx)(如果value值中参数的请求类型为空,则url拼接参数的方式是:“?参数名=xx&参数名2=xx”) :默认请求方式是get
@RequestParam:接收带参数名的url请求方式的参数,可以通过defaultValue指定默认值,name指定参数名required指定参数是否必须。
@RequestBody(需要指定http的头为 content-type为application/json,使用body传输数据):接受一个对象
@RequestHeader:获取对应的请求头信息,比如在获取支付功能的令牌信息。
HttpRequest对象:用request.getParameter("xx")获取参数。
Http请求的post,put,delete请求
@PostMapping(一般提交保存信息)
@PutMapping(一般是更新某一个用户信息)
@DeleteMapping(一般是删除操作)
常用的json框架:JavaBean序列化为Json的性能:Jackson>Fastjson>Gson>Json-lib
jackson框架:1.可以在实体类里面加@JsonIgnore注解,使这个成员再返回给前台是被过滤掉,比如用户的密码这个字段,就不能直接返回给前台显示
2.@JsonFormat注解,可以对返回的日期格式进行制定
3.@JsonProperty可以制定别名
4.@JsonInclude:表示如果字段为空不会返回
springboot有默认的文件加载顺序,默认先从static文件下查找
springboot文件上传:@RequestMapping
参数接收File类型的参数,然后调用file.transTo()方法进行文件上传
对上传的文件进行非空,大小的判断
java -jar xxx 找不到入口,启动类(添加maven插件)
如果需要修改直接加到Application
配置实体类:可以通过@Value属性注入,需要注意的是启动类只能扫描同级包和子包。
Junit单元测试:
一、单元测试入门
1、在pom文件中导入junt依赖
2、在test包下新建一个class文件,加两个注解(@RunWith(SpringRunner.class),@SpringBootTest(classes=xxxx(启动类).class))
3、在该类中新建一个方法,声明@Test注解(加断言TestCase.assertEquals(xx,xx))
4、前置注解@Before,后置注解@After
5、要同时测试多个方法,则运行该类
二、MockMVC(一个Http的客户端)
1、除了单元测试的注解,还需要添加@AutoConfigureMockMVC
三、异常捕获:
1、全局异常:@RestControllerAdvice注解标记类,该类捕获到的是全局的异常,捕获处理异常,返回给前端友好的信息。
记录日志:private static final Logger log = LoggerFactory.getLogger(xxxx.class);
log.error("url {},msg {}",request.getRequestURL(),e.getMessage());记录日志
2、自定义异常:(1)、自定义异常界面的跳转
* 在pom中加入thymeleaf模版引擎依赖
* 建立一个自定义异常类,继承RuntimeException
* 定义异常属性(如code,message及其get和set方法)
* 方法上加@ExceptionHandler(value=自定义异常类.class):细分什么异常进什么方法进行处理
* 准备一个展示出异常的页面
* 在方法里通过modelAndView进行页面跳转
* 自定义异常也是可以返回json数据的
springboot项目打包到tomcat:
jar包方式启动:一、加maven插件,spring-boot-maven-plugin
war包方式启动:在pom里先配置打包方式:<packing>war</packing>,然后在<build>里面增加<filename>打包的项目名称</filename>,修改启动类。继承SpringBootServiceInitolizer,进行打包,然后将war包部署到tomcat的webapp目录下,启动tomcat就可以了
使用Jmter测试工具测试容器性能。QPS(每秒查询数),TPS(每秒输入数),RT(响应时间)
springBoot2.x过滤器Filter:
filter是什么:比如检票员,过滤掉没有买票的人,把有票的,也就是符合判断条件规则的人放过去。
1、springBoot启动时会加载一些默认过滤器。
characterEncodingFilter
hidedenHttpMethodFilter
httpPutFormContentFilter
requestContextFilter
2、springBoot过滤器的优先级
Ordered.HIGHEST_PRECEDENCE
Ordered.LOWEST_PRECEDENCE
低位值(数字越小)意味着更高的优先级
自定义filter时,要注意避免和默认的filter优先级一样,不然会冲突
3、自定义Filter
1)使用Servlet3.0的注解进行配置
2)启动类里面增加@ServletComponentScan,进行扫描
3)新建一个Filter类,implements Filter,并实现对应的接口
4)控制chain.doFilter的方法的调用,来实现是否通过放行
不放行,web应用resp.sendRedirect("/index.html");
场景:权限控制、用户登录(非前后端分离场景)等。
新建一个类,继承Filter,重写三个方法:
init:容器加载的时候调用
doFilter:请求被拦截的时候进行调用。可以在doFilter中通过获取HttpRequest来获得用户的信息,从而根据用户的信息进行判断,返回不同的结果
destroy:容器被销毁的时候被调用
记得加WebFilter(urlPatterns="/xxx/xxx/*",FilterNmae="xxx")注解,该注解是为了标记一个类为Filter
urlPatterns是拦截规则,支持正则。
4、自定义一个原生的Servlet实现小的需求
1)定义一个类,继承HttpServlet
2)在类上加注解@WebServlet(name="xxx",urlPatterns="/xx/xx")
3)重写doGet/doPost方法,在方法中进行业务处理。
4)在启动类上加注解@ServletCompnentScan,配合开启Servlet
5、SpringBoot的Listener
1)定义一个类,实现ServletRequestListener/ServletContextListener等
2)在类上加@WebListener注解
3)重写requestDestroyed和requestInitialized方法
4)执行顺序:先执行初始化方法,再执行controller方法,最后执行销毁方法
=========拦截器和过滤器的区别==========
1、使用范围不同:Filter是Servlet规范规定的,只能用于Web程序中,而拦截器既可以同于Web程序,也可以用于Application、Swing程序中。
2、规范不同:Filter实在Servlet规范中定义的,是Servlet容器支持的,而蓝假期是在Spring容器内的,是Spring框架支持的。
3、使用的资源不同:同其他的代码块一样,拦截器也是一个Spring的组件,归Spring管理,配置在Spring文件中,因此能使用Spring里的任何资源、对象,例如Service对象、数据源、事务管理等,通过IOC注入到拦截器即可,而Filter则不能。
4、深度不同:Filter在只在Servlet前后起作用,。而拦截器能够深入到方法前后、异常抛出前后等,因此拦截器的使用具有更大的弹性、
过滤器和拦截器的执行顺序:
1)Filter pre:进入过滤器,执行chain,doFilter(request,response)之前的逻辑。
2)service:SpringMVC的doService()方法,也即Service的service()方法。
3)dispatcher:SpringMVC的请求分发方法。
4)preHandle:进入拦截器,执行controller之前调用。
5)controller
6)postHandle:执行完controller逻辑,在controller的return ModelAndView之前执行,可以操控ModelAndView的值。
7)afterCompletion:Controller的return之后,但是在Filter返回给客户端之前执行。
8)FilterAfter:服务器端逻辑全部执行完成,返回给客户端之前的逻辑。
SpringBoot2.x拦截器
1、自定义一个拦截器
1)新建一个类,加注解@Configuration,实现WebMvcConfigurer,重写addInterceptor方法生成拦截器
2)新建一个类(拦截器),继承HandlerInterceptor(拦截器的业务类),重写方法
preHandle:进入controller方法之前,一般是用来做权限和登录校验的。
postHandle:调用完controller之后,视图渲染之前。
afterCompletion:整个完成之后,通常用于资源清理。
2、多个拦截器的执行顺序“包裹执行”
SpringBoot Starter起步依赖
SpringBoot模版引擎
静态页面渲染模版渲染
Freemaker不占用系统内存,因为他不是用java处理的
Thymeleaf(轻量级的模板引擎,不适合复杂的逻辑业务,因为解析DOM或者XML会占用多的内存)
SpringBoot整合Freemaker:
1、在pom文件中导入相关依赖包(spring-boot-starter-freemaker)
2、Freemaker的基础配置(参考相关文档)
3、新建一个包(路径),来存放模板,后缀是ftl
4、编写代码。返回页面
${setting.name},${value}等方式来取值
* 除此之外,还需要注意classpath的/问题,防止出现找不到返回界面问题
SpringBoot整合thymeleaf
1、在pom文件中导入相关依赖包(thymeleaf-spring5,thymeleaf-extras-java8time)
2、配置文件,主要配置路径和后缀名,将thymeleaf加载到静态资源文件中。
3、通过配置加载静态资源,可以在页面不通过controller直接访问页面。
SpringBoot持久化数据到数据库
一、常用的访问数据库的方式
1、原始sql
1)注册驱动/加载驱动
Class.forName("com.mysql.jdbc.Driver");
2)建立连接
Connection conn = DriverMannger.getConnection("jdbc:mysql://localhost:3306/dbname","root","root");
3)创建Statement
4)执行SQL语句
5)处理结果集
6)关闭连接,释放资源
2、apache dbutils框架
3、jpa框架
spring-data-jpa
jpa在复杂查询的时候性能不是很好
4、Hibernate 解释:ORM:对象关系映射Object Relational Mapping
企业大都喜欢使用hibernate
5、Mybatis框架
互联网行业通常使用mybatis
不提供对象和关系模型的直接映射,半ORM
二、SpringBoot整合Mybatis(注解方式)
1、使用startermybatis-spring-boot-starter
2、加入依赖:
1)引入starter:mybatis-spring-boot-starter
2)MySQL的JDBC驱动包:mysql-connector-java
3)引入第三方数据源:druid
3、配置文件,配置连接数据库的数据信息。
4、启动类增加Mapper扫描:@MapperScan
5、开发Mapper(推荐使用#{}取值,不要${},因为存在SQL注入的风险)
保存数据,获取自增id:@Options(useGeneratedKeys=true,keyProperty="id",keyColumn="_id")注解
可以切换数据源,控制台打印sql
三、SpringBoot整合mybatis之实操和控制台打印SQL
1、在配置文件中添加配置:mybatis.configuration.log.impl=org.apache.ibatis.logging.stdout.StdOutImpl
2、映射数据库字段名称与实体类成员变量:@Results{
@Result(column="xxx",property="xxx"),
@Result(column="xxx",property="xxx")
}
3、CRUD的实现,参数可以传数据,也可以传对象,只要sql语句中接受参数名字和参数名对应即可
4、一般对外提供接口的时候,名字改为小写。
四、事务的隔离级别和传播
1、分布式事务:
可以用消息队列
1)二次提交
2)最终一致性
2、隔离级别:
Serializable:串行化
Repeatable Read:可重复读
read committed:不可重复读
read uncommitted:读未提交
3、常见的事务的传播行为
PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务,最常见的选择。
PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY--支持当前事务,如果没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW--新建事务,如果当前没有事务,把当前事务挂起,两个事物之间没有关系,一个异常,一个提交,不会同时回滚。
PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
五、SpringBoot整合mybatis事务处理实操
1、@Transactional(propagetion=Propagation.REQUIRED,isolation=xxx)
SpringBoot整合Redis
一、分布式缓存Redis
1、流程请求 -> tomcat -> 缓存服务(redis,nosql,MV,mongodb,hive...)
-> mysql
二、SpringBoot整合Redis实战讲解:
1、导入pom文件依赖:spring-boot-starter-date-redis
2、配置相关的配置文件(参考文件),主要包含了spring.redis.database,spring.redis.host,spring.redis.port,spring.redis.timeout,spring.redis.pool.min-idle,spring.redis.pool.max-active,spring.redis.pool.max-wait等
3、建立一个controller,注入StringredisTemplate,来对redis中的数据进行操作。
4、redisTemplate的opsForValue是最常用的
5、通过redisTemplate可以对多种数据类型进行操作,opsForValue的get方法可以从redis中获取到之前存在redis中对应的数据。
三、操作redis的工具,redis可视化工具。(redis默认有16个库,可以在配置文件中配置操作的是哪一个库)
1、可以自己封装工具类,实现你想要的方法
SpringBoot整合定时任务和异步任务处理
一、定时任务的实现方式:
1、常见的定时任务 Java自带的java.util.Timer类
timer:配置比较麻烦,时间延后问题
timertask:不推荐
2、Quartz框架
配置更简单
xml或者注解
3、springBoot使用注解方式开启定时任务
@EnableScheduling开始定时任务,自动扫描
@Component被容器扫描
定时执行的方法加上注解@Scheduled(cron表达式)
二、常用定时任务配置实战
1、cron 定时任务表达式(* * * * * ?)
2、fixedRate:定时多久执行一次(上一次开始执行时间点后xx秒再次执行)
3、fixedDelay:上一次执行结束时间点后xx秒再次执行
4、fixedDelayString:字符串形式,可以通过配置文件指定。
5、fixedRateString:字符串形式,可以通过配置文件指定。
三、异步任务实战
1、什么是异步任务和使用场景:适用于处理log、发送邮件、短信等等
下单接口->查库存 100
余额校验 150
风控用户 100
。。。
2、启动类里面使用@EnableAsync注解开启功能,自动扫描。
3、定义异步任务类并使用@Component标记组件被容器扫描,异步方法加上@Async
注意点:
1)要把异步任务封装到类里面,不能直接写到controller
2)增加Future<String>返回结果AsyncResult<String>("task执行完成")
3)如果需要拿到结果,需要判断全部的task.isDone()
4、通过注入方式,注入到controller里面,如果测试前后区别则改为同步测试把Async注释掉
Logback日志框架介绍和SpringBoot整合
一、新日志框架LogBack
1、常用来处理java的日志组件 slf4j,log4g,logback,common-logging等。
2、logback:基于Log4j基础上大量改良,不能单独使用,推荐配合日志框架SLF4J来使用。
logback当前分为三个模块:logback-core,logback-classic和logback-access
logback-core是其他两个模块的基础模块。
3、logback的核心对象:
Logger:日志记录器
Appender:指定日志输出的目的地,目的地可以是控制台,文件
Layout:日志布局 格式化日志信息的输出
4、日志级别:DEBUG < INFO < WARN < ERROR
二、springBoot整合logback
1、创建日志文件logback-spring.xml。官方推荐 -spring.xml结尾
默认加载配置顺序 logback-spring.xml,logback-spring.groovy,logback.xml,or logback.grovy
注释:
<configuration> 子节点
<appender></appender> 输出目的
<logger></logger>
<root></root> 要加在最后
(具体配置参考文档)
SpringBoot整合ElasticSearch
一、搜索引擎知识和框架基本介绍:
1、elasticSearch的主要特点:
1)特点:全文检索、结构化检索,数据统计、分析,接近实时处理,分布式搜索(可部署数百台服务器),处理PB级别的数据,搜索纠错,自动完成自动提示。
2)使用场景:日志搜索,数据聚合,数据监控,爆表统计分析
3)国内外使用者:维基百科,Stack Overflow,GitHub
2、一个索引库中只能存在一个type,不再能在一个索引库中同时存在多个type。
ES是纯java开发的,springboot的使用5.6
3、配置ES出现问题处理
1)Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000c5330000,986513408,0) failed;error='Cannot allocate memory' (errno=12)
#
# There is insufficient memory for Java Runtime Environment to continue.
# Native memory allocation (mmap) failed to map 986513408 bytes for committing reserved memory.
# Anerror report file with more information is saved as:
# /usr/local/so.....
解决:改参数(jvm.option中的-Xms改为128M)或者内存不够,购买阿里云的机器可以动态增加内存
2) [root@Zwz95j86y235aroi85ht0Z bin]...
解决:用非root用户
添加用户:useradd -m 用户名 然后设置密码 passwd 用户名
3)./elasticsearch
Exception in thread "main" java.nio.file.Acc.......
解决:权限不够 chomd 777 - R 当前es目录
二、ES准备数据
1、利用postMan工具
1)查看集群状态:localhost:9200/_cat/health?v
2)查看节点次数:localhost:9200/_cat/nodes?v
3)查看索引:localhost:9200/_cat/indices?v
4)创建一个索引:PUT /customer?pretty
5)往索引中添加数据:PUT customer/external/1?pretty
{
"name":"John Doe"
}
三、Springboot整合ElasticSearch
1、添加maven依赖:spring-boot-starter-data-elasticsearch(客户端版本要和服务端版本对应)
2、接口继承ElasticSearchRepository,里面有很多默认实现
注意点:索引名称记得小写,类属性名称也要小写
1)新建实体对象article,加上注解@Document(indexName = "blog",type = "article")
2)新建一个接口,继承类ElasticSearchRepository,家注解@Component或者@Repository
3)配置文件:参考相关文档
ES集群的名称
节点数(IP+端口号)
数据仓库是否开启,true表示开启
4) 新建一个controller,进行数据处理。
SpringBoot整合消息队列和JMS
一、消息队列介绍
1、JMS介绍和使用场景及基础编程模型
1)什么是JMS:Java消息服务(Java Message Service),Java是、平台中关于面向消息中间件的接口
2)JMS是一种与厂商无关的API,用来访问消息收发系统消息,它类似于JDBC,这里,JDBC是可以用来访问许多不同关系数据库的API。
3)使用场景:
跨平台
多语言
多项目
解耦
分布式事务
流量控制
最终一致性
RPC调用
上下游对接,数据源变动->通知下载
4)概念
JMS提供者:Apache ActiveMQ、RabbitMQ、Kafka、Notify、MetaQ、RocketMQ
JMS生产者(Message Producer)
JMS消费者(Message Consumer)
JMS消息
JMS队列
JMS主题
JMS消息通常有两种类型:点对点模式、发布订阅这模式
5)编程模型:
MQ中需要用的一些类
ConnectionFactory:连接工厂,JMS用它创建连接
Connection :JMS 客户端到JMS Provider的连接
Session:一个发送或接受消息的线程
Destination:消息的目的地,消息发送给谁
MessageConsumer/MessageProducer:消息接受者,消费者
二、ActiveMQ消息队列基础介绍和安装
简介:
特点:
1)支持来自Java,C,C++,C#,Ruby,Perl,Python,PHP的各种跨语言客户端和协议
2)支持许多高级功能,如消息组,虚拟目标,通配符和符合目标。
3)完全支持JMS1.1和J2EE1.4,支持瞬态,持久,事务和XA消息
4)Spring支持,ActiveMQ可以轻松嵌入到Spring应用程序中,并使用Spring的XML配置机制进行配置
5)支持在流行的J2EE服务器(如TomEE,Geronimo,JBoss,GlassFish和WebLogic)中进行测试
6)使用JDBC和高性能日志支持非常快速的持久化
使用:
1)下载
2)解压
3)安装在Linux系统上,在bin目录里面启动,选择对应的系统版本和位数,activeMQ start 启动
4)启动后访问路径http://127.0.0.1:8161/
5)用户名和密码默认都是admin
三、SpringBoot整合ActiveMQ的点对点
1、在pom文件中引入依赖spring-boot-starter-activemq,activemq-pool
2、application.properties配置文件配置(参考相关文档)
1)配置activeMQ的地址(防火墙问题,关闭或者开放对应端口号)
2)adtiveMQ集群的配置
3)登录的账号名和密码
4)开启一个连接池,最大连接数
3、启动类添加注解@EnableJms
4、在启动类中写一个返回队列的方法(return new ActiveMQQueue),并添加注解@Bean,交给spring进行管理,方便后续进行注入。
5、写一个发送消息的服务,注入JmsMessagingTemplate和Queue,调用它的converAndSend(this.queue,message)方法,进行发送消息
6、写一个发送消息的controller,注入发送消息的service,在方法中定义一个队列名称,然后调用service的发送消息的方法
7、消费者:定义一个监听类,加注解@Component,定义监听方法,加注解@JmsListener(destination="xxx"),实时监听对应的队列
四、SpringBoot整合ActiveMQ的发布订阅模式
1、在pom中导入对应的依赖包,如上
2、配置配置文件,如上。底部新增配置:spring.jms.pub-sub-domain=true,支持发布订阅模型,否则默认只支持点对点模型
3、启动类添加注解@EnableJms
4、在启动类中添加一个topic(return new ActiveMQTopic),添加@Bean注解
5、定义一个发送消息的服务,注入JmsMessagingTemplate和Topic,调用它的converAndSend(this.topic,message)方法,进行发送消息
6、写一个发送消息的controller,注入发送消息的service,
7、定义一个消费者,定义一个监听类,加注解@Component,定义监听方法,加注解@JmsListener(destination="xxx"),实时监听对应的队列
注意点:
1)默认消费者并不会消费订阅发布类型的消息,这是由于springboot默认采用的是p2p模式进行消息的监听
修改配置:spring.jms.pub-sub-domain=true
2)@JmsListener如果不指定独立的containerFactory的话是只能消费queue消息
修改订阅者的container:containerFactory=“jmsListenerContainerTopic”
注释掉配置文件中的spring.jms.pub-sub-domain=true
//需要给topic定义独立的JmsListenerContainer
@Bean
public JmsListenerCOntainerFactory<?> jmsListenerContainerTopic(ConnectionFactory activeMQConnectionFactory){
DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
bean.setPubSubDomain(true);
bean.setConnectionFactory(activeMQConnectionFactory);
return bean;
}
将这个方法放入启动类
五、RocketMQ4.X消息队列
1、简介RocketMQ
(1)Apache RocketMQ作为阿里开源的一款高性能、高吞吐量的分布式消息中间件
(2)特点
1)在高压下1毫秒内响应延迟超过99.6%
2)适合金融类业务,高可用性跟踪和审计功能
3)支持发布订阅模型和点对点模型
4)支持拉pull和推push两种消息模式
5)单一队列百万消息
6)支持单master节点,多master节点,多master多slave节点
(3)概念
Producer:消息生产者
Producer Grop:消息生产组,发送同类消息的一个消息生产组
Consumer:消费者
Consumer Group:消费同个消息的多个实例
Tag:标签,子主题(二级分类),用于区分同一个主题下的不同业务的消息
Topic:主题
Message:消息
Broker:MQ程序,接收生产的消息,提供给消费者消费的程序
Name Server:给生产和消费者提供路由信息,提供轻量级的服务发现和路由
SpringBoot多环境配置
一、不同环境使用不同的配置
例如表数据库配置,在开发的时候,我们一般开发数据库,而在生产环境的时候,我们是用正式的数据
公司中的环境一般分为:开发环境DEV、测试环境TEST、预发布环境PRE、生产环境PRO
二、配置文件存放路径
1、classpath根目录的"/config"包下
classpath的根目录下
三、spring boot允许通过命名约定按照一定的格式(application-(profile).properties)来定义多个配置文件
SpringBoot响应式编程
一、SpringBoot响应式编程简介
1、基础理解。快速处理请求或者操作
依赖于事件驱动(Event-driven)
一系列事件称为“流”
异步
非阻塞
观察者模式
网上一个例子:
int a = b+c // 命令式编程后续b和c变化,都不影响a
int a = b+c // 响应式编程中,a的变化,会和b、c的变化而变化(事件驱动)
二、
spring data JPA
一、Spring data JPA是什么:
JPA(Java Persistence API)是官方提出的Java持久化规范。
注意:JPA是一套规范,而不是一套产品。比如Hibernate,TopLink这些产品实现了JPA规范,那么我们就可以叫他们为JPA的实现产品。
二、spring data jpa的基本查询
基本查询也分两种,一种是spring data默认已经实现,一种是根据查询的方法来自动解析成SQL。
1、预先生成方法(spring data jpa默认预先生成了一些基本的CRUD的方法,例如:增、删、改等等)
1)继承JpaRespository
public interface UserRepository extends JpaRepository<User,Long>{
}
2)使用默认方法
@Test
public void testBaseQuery() throws Exception{
User user = new User();
userRepository.findAll();
userRepository.findOne(1l);
userRepository.save(user);
userRepository.delete(user);
userRepository.count();
userRepository.exists(1l);
//...
}
根据方法名就可知道该方法的实现功能
2、自定义简单查询(自定义简单查询就是根据方法名来自动生成SQL,主要的语法是findXXBy,readXXBy,queryXXBy,countXXBy,getXXBy后面跟属性名称)
如User findByUserName(String userName);
1)也使用一些加一些关键字(And、Or)
User findByUserNameOrEmail(String userName,String email);
2)修改、删除、统计也是类似语法
Long deleteById(Long id);
Long countByUserName(String userName)
3)基本上SQL体系中的关键词都可以使用,例如:LIKE、IgnoreCase、OrderBy。
List<User> findByEmailLike(String email);
User findByUserNameIgnoreCase(String userName);
List<User> findByUserNameOrderByEmailDesc(String email);
4)具体的关键字可查询相关文档
3、复杂查询
分页查询
在查询的方法中,需要传入参数Pageable,当查询中有多个参数的时候,Pageable建议作为最后一个参数传入
Page<User> findAll(Pageable pageable);
PaGE<uSER> findByUserName(String userName,Pageable pageable);
Pageable是搜ring封装的分页实现类,使用的时候需要传入页数、每页条数和排序规则
@Test
public void testPageQuery() throws Exception{
int page = 1,size = 10;
Sort sort = new Sort(Direction.DESC,"id");
Pageable pageable = new PageRequest(page,size,sort);
userRepository.findAll(pageable);
userRepository.findByUserName("testName",pageable);
}
限制查询
有时候我们只需要查询前N个元素,或者支取前一个实体。
User findFirstByOrderByLastnameAsc();
User findTopByOrderByAgeDesc();
Page<User> queryFirst10ByLastname(Stirng lastname,Pageable pageable);
List<User> findFirst10ByLastname(Stirng lastname,Sort sort);
List<User> findTop10ByLastname(String lastname,Pageable pageable);
自定义SQL查询
其实Spring data 绝大部分的SQL都可以根据方法名定义的方式来实现,但是由于某些原因我们想要使用自定义的SQL来查询,spring data也是完美支持的;在SQL的查询方法上面使用@query注解,如涉及到删除和修改在需要加上@Modifying。也可以根据需要添加@Transactional对事物的支持,查询超时的设置等。
@Modifying
@Query("update User u set u.userName = ?1 where c.id = ?2")
int modifyByIdAndUserId(String userName,Long id);
@Transactional
@Modifying
@Query("delete from User where id = ?1")
void deleteByUserId(Long id);
@Transactional(timeout = 10)
@Query("select u from User u where u.emailAddresss = ?1")
User findByEmailAddress(String emailAddress);
多表查询
多表查询在spring dta jpa中有两种实现方式,第一种是利用hibernate的级联查询来实现,第二种是创建一个结果集的接口来接受连表查询后的结果,这里主要第二种方式。
1)首先需要定义一个结果集的接口类。
public interface HotelSummary {
City getCity();
String getName();
Double getAverageRating();
default Integer getAverageRatingRounded() {
return getAverageRating() == null ? null : (int) Math.round(getAverageRating());
}
}
2)查询的方法返回类型设置为新创建的接口
@Query("select h.city as city, h.name as name, avg(r.rating) as averageRating "
- "from Hotel h left outer join h.reviews r where h.city = ?1 group by h")
Page<HotelSummary> findByCity(City city, Pageable pageable);
@Query("select h.name as name, avg(r.rating) as averageRating "
- "from Hotel h left outer join h.reviews r group by h")
Page<HotelSummary> findByCity(Pageable pageable);
3)使用
Page<HotelSummary> hotels = this.hotelRepository.findByCity(new PageRequest(0, 10, Direction.ASC, "name"));
for(HotelSummary summay:hotels){
System.out.println("Name" +summay.getName());
}