1.为什么要使用SpringBoot
因为Spring,SpringMVC需要大量的配置文件(xml文件)
还需要配置各种对象,把使用的对象放在spring容器当中去使用
需要去了解其他的框架配置原则
2.SpringBoot相当于不需要配置文件的Spring+SpringMVC
JavaConfig:使用java类作为xml配置文件的替代,可用使用java类来代替xml文件的方式
使用到了两个注解:
1)@Configuration:放在类的上面,表示这个类作为配置文件使用的
2)@Bean:声明对象,把对象注入到容器当中
crtl + H可以查看类的继承关系
ctrl + shift + / 可以进行文档注释
重要的是crtl + p可以看到类里面的方法的数值以及返回参数
配置类:
package com.bjpowernode.config;
import com.bjpowernode.pojo.Student;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
@Configurable
public class SpringConfig {
/**
* 创建方法方法的返回值是对象,在方法上面加上@Bean
* 方法的返回值就注入到对象当中了
* @Bean 将对象注入到Spring的容器当中,放在方法的上面
* @Bean 不指定名称默认方法值是id
*/
@Bean
public Student createStudent(){
Student student = new Student("wsy", 18, "nan");
return student;
}
@Bean(name = "wsy")
public Student openStudent(){
Student student = new Student("wsy", 18, "nan");
return student;
}
}
测试类:
package com.bjpowernode;
import com.bjpowernode.config.SpringConfig;
import com.bjpowernode.pojo.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class myTest {
@Test
public void test01(){
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationcontext.xml");
Student student = (Student) ac.getBean("student");
System.out.println(student);
}
@Test
public void test02(){
/* SpringConfig springConfig = new SpringConfig();
Student student = springConfig.createStudent();
System.out.println(student);*/
ApplicationContext ax = new AnnotationConfigApplicationContext(SpringConfig.class);
Student stu = (Student) ax.getBean("createStudent");
System.out.println(stu);
}
@Test
public void test03(){
ApplicationContext ax = new AnnotationConfigApplicationContext(SpringConfig.class);
Student wsy = (Student) ax.getBean("wsy");
System.out.println(wsy);
}
}
@ImportReasource 作用导入其他的xml的配置文件,等于xml
要在工具类上面去添加 @ImportResource(value = {“classpath:mycat.xml”,“classpath:applicationcontext.xml”})
package com.bjpowernode.config;
import com.bjpowernode.pojo.Student;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ImportResource;
@Configurable
@ImportResource(value = {"classpath:mycat.xml","classpath:applicationcontext.xml"})
public class SpringConfig {
/**
* 创建方法方法的返回值是对象,在方法上面加上@Bean
* 方法的返回值就注入到对象当中了
* @Bean 将对象注入到Spring的容器当中,放在方法的上面
* @Bean 不指定名称默认方法值是id
*/
@Bean
public Student createStudent(){
Student student = new Student("wsy", 18, "nan");
return student;
}
@Bean(name = "wsy")
public Student openStudent(){
Student student = new Student("wsy", 18, "nan");
return student;
}
}
@PropertyResource:读取properties的属性配置文件。使用属性配置文件可以实现外部化配置,在程序代码之外提供数据
步骤:
1.在resources目录下,创建properties文件,使用k=v的格式来提供数据
2.在PropertiesReasources下来指定properties的位置
3.使用@Value(value=“${key}”)
实体类:
package com.bjpowernode.pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Tiger {
@Value("${tiger.name}")
private String name;
@Value("${tiger.age}")
private Integer age;
public Tiger() {
}
public Tiger(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Tiger{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
配置类:
package com.bjpowernode.config;
import com.bjpowernode.pojo.Student;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.PropertySource;
@Configurable
@ImportResource(value = {"classpath:mycat.xml","classpath:applicationcontext.xml"})
@PropertySource(value = "classpath:config.properties")
@ComponentScan(basePackages = "com.bjpowernode.pojo")
public class SpringConfig {
/**
* 创建方法方法的返回值是对象,在方法上面加上@Bean
* 方法的返回值就注入到对象当中了
* @Bean 将对象注入到Spring的容器当中,放在方法的上面
* @Bean 不指定名称默认方法值是id
*/
@Bean
public Student createStudent(){
Student student = new Student("wsy", 18, "nan");
return student;
}
@Bean(name = "wsy")
public Student openStudent(){
Student student = new Student("wsy", 18, "nan");
return student;
}
}
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-du0lUN6N-1659271632023)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220718203500103.png)]](https://1000bd.com/contentImg/2022/08/03/105645693.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yoaDtcfJ-1659271632024)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220718204035526.png)]](https://1000bd.com/contentImg/2022/08/03/105645849.png)
●Create stand-alone Spring applications
创建spring应用
●Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)
内嵌的tomcat, jetty ,Undertow
●Provide opinionated ‘starter’ dependencies to simplify your build configuration
提供了starter起步依赖,简化应用的配置。
比如使用MyBatis框架,需要在Spring项目中 ,配置MyBatis的对象SqlSessionFactory,Dao的代理对象
在SpringBoot项目中,在pom.xml里面,加入-一个mybatis-spring boot-starter依赖
●Automatically configure Spring and 3rd party libraries whenever possible
尽可能去配置spring和第三方库。叫做自动配置(就是把spring中的,第三方库中的对象都创建好,放到容器
中,开发人员可以直接使用)
●Provide production-ready features such as metrics, health checks, and externalized configuration
提供了健康检查,统计,外部化配置
●Absolutely no code generation and no requirement for XML configuration
不用生成代码,不用使用xml ,做配置
使用的是https://start.spring.io
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nuj6suPY-1659271632025)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220720195430389.png)]](https://1000bd.com/contentImg/2022/08/03/105646134.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C0AZTF8N-1659271632026)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220720201432677.png)]](https://1000bd.com/contentImg/2022/08/03/105646296.png)
就是按部就班地进行创建,然后把这个依赖导入就可以了
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.7.1version>
<relativePath/>
parent>
这是一个复合注解,主要由这三个注解组成的
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
1.@SpringBootConfiguration
下面含有@Configuration 这个注解,说明可以去配置@Bean这个对象,注入到容器当中
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
@AliasFor(
annotation = Configuration.class
)
boolean proxyBeanMethods() default true;
}
2.@EnableAutoConfiguration
启用自动配置,可以把Java对象配置好,放入到容器当中,例如可以把mybatis的对象创建好,放入到容器当中
3.@ComponentScan
组件扫描器,可以配置pojo的类包进行扫描
默认扫描的包:@ComponentScan所在的包及其子包下面的
配置文件的名称:application
拓展名:properties(k=v);yml(k: (这里有一个空格的)v)
使用application.properties或者application.yml两种其中的一种就可以
使用application.properties设置端口和上下文
# 设置端口号
server.port = 8082
# 设置访问应用的上下文路径
server.servlet.context-path=/myboot
使用application.ym格式来设置端口和上下文
两个空格表示层级关系,冒号后面也必须要使用两个空格
server:
port: 8083
servlet:
context-path: /myboot2
这两个文件同时存在的时候,默认使用的是properties的文件
含有开发环境,测试环境,上线的环境,每个环境都含有不同的配置信息
配置信息像端口、上下文文件、url数据库、用户名、密码等
使用多环境配置文件,可以方便去切换不同的配置
使用方式:创建多个配置文件,名称规则application-环境名称.properties
开发的环境的配置:application-dev.properties
测试的环境的配置:application-test.properties
上线的环境的配置:application-online.properties
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Es69iASu-1659271632026)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220720223653483.png)]](https://1000bd.com/contentImg/2022/08/03/105646439.png)
通过下面的来进行指定 要运行的版本
spring.profiles.active=dev
[(73条消息) Spring boot @Value注解详解_wangooo的博客-CSDN博客_springboot value注解](https://blog.csdn.net/wangooo/article/details/114018690?ops_request_misc=%7B%22request%5Fid%22%3A%22165836776416782395319729%22%2C%22scm%22%3A%2220140713.130102334…%22%7D&request_id=165836776416782395319729&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-114018690-null-null.142v33pc_rank_34,185v2control&utm_term=SpringBoot %40VAlue&spm=1018.2226.3001.4187)
properties文件:
# 配置端口号
server.port=8083
# 配置上下文
server.servlet.context-path=/myboot4
# 自定义配置
school.name=动力节点
school.website=www.bjpowernode.com
school.address=北京大兴区
site=www.baidu.com
使用@Value注解
@Controller
public class MyController {
@Value("${server.port}")
private Integer port;
@Value("${server.servlet.context-path}")
private String path;
@Value("${school.website}")
private String name;
@Resource
School school;
@RequestMapping("/map")
@ResponseBody
public String queryData(){
return port+path+name+"学校是"+school;
}
}
但是使用properties可能会出现中文乱码的现象
现在使用的都是yml文件一般
# 配置端口号和路径
server:
port: 8083
servlet:
context-path: /myboot4
# 自定义配置
school:
name: 北京
website: www.bjpowernode.com
address: 动力节点
site: www.baidu.com
(73条消息) ConfigurationProperties注解详解_思维的深度的博客-CSDN博客_configurationproperties注解在方法上
package com.example._008springbootcustomyml.pojo;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "school")
public class School {
// school.name=动力节点
// school.website=www.bjpowernode.com
// school.address=北京大兴区
private String name;
private String website;
private String address;
public School(String name, String website, String address) {
this.name = name;
this.website = website;
this.address = address;
}
public School() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getWebsite() {
return website;
}
public void setWebsite(String website) {
this.website = website;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "School{" +
"name='" + name + '\'' +
", website='" + website + '\'' +
", address='" + address + '\'' +
'}';
}
}
报这个警告的意思是少一个配置项,需要去添加一个依赖,添加这个依赖之后,可以给出提示信息
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-configuration-processorartifactId>
<optional>trueoptional>
dependency>
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
方法的返回值是一个容器interface
public interface ConfigurableApplicationContext extends ApplicationContext
ConfigurableApplicationContext 是 ApplicationContext的子接口
可以通过容器对象拿到里面的Bean类
这两个接口都有一个run方法,执行时间都在容器创建好之后,自行去执行run方法
package org.springframework.boot;
@FunctionalInterface
public interface CommandLineRunner {
void run(String... args) throws Exception;
}
package org.springframework.boot;
@FunctionalInterface
public interface ApplicationRunner {
void run(ApplicationArguments args) throws Exception;
}
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9V86Mjxm-1659271632027)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220721105227684.png)]](https://1000bd.com/contentImg/2022/08/03/105646778.png)
这里是Spring的核心依赖
Application这个大类去implements这个接口,然后OverRide里面的方法,
容器创建好之后就会调用run里面的方法
@SpringBootApplication
public class Application implements CommandLineRunner {
public static void main(String[] args) {
System.out.println("开始创建容器");
SpringApplication.run(Application.class, args);
System.out.println("容器创建之后");
}
@Override
public void run(String... args) throws Exception {
System.out.println("容器创建好要执行的方法");
}
}
拦截器是SpringMVC的一种对象,可以去拦截对controller的请求
拦截器框架中有系统的拦截器,可以去自定义拦截器,实现对请求的预处理
原来springmvc实现自定义拦截器:
1.创建来来实现Springmvc框架的HandlerIntercep
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
2.需要在Springmvc的配置文件当中,去声明拦截器
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="url"/>
<bean class="拦截器类的全限定名称">bean>
mvc:interceptor>
mvc:interceptors>
重建一个项目 写一段拦截器的代码
拦截器的类实现接口
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("拦截器被执行了");
return true;
}
}
配置类:
这里必须使用配置类的注解
@Configuration
public class MyConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//这里add的path是要拦截的,excludePath是不需要去拦截的
String path [] = {"/user/**"};
String excludePath [] = {"/user/login"};
registry.addInterceptor(new LoginInterceptor()).addPathPatterns(path).excludePathPatterns(excludePath);
}
}
控制器的类
@Controller
public class MyController {
@RequestMapping("/user/login")
@ResponseBody
public String userLogin(){
return "111111111111111111111";
}
@RequestMapping("/user/else")
@ResponseBody
public String userElse(){
return "222222222222222";
}
}
Interceptor是拦截器 Filter是过滤器
在springBoot中去使用servlet
使用步骤:
1.创建类,去继承HttpServlet
2.注册servlet,让框架能找到servlet
servlet配置类
public class MyServelt extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 使用HttpServeletResponse输出数据,响应结果
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().print("nihaoyadasjiasdklfjasdwjasdlaskdj");
}
}
配置类:
@Configuration
public class MyConfig {
这里记得去添加@Bean注解
@Bean
public ServletRegistrationBean serveletRegistrationBean(){
ServletRegistrationBean servletServletRegistrationBean = new ServletRegistrationBean<>(new MyServelt(),"/ser","/insert");
// public ServletRegistrationBean(T servlet, String... urlMappings)
return servletServletRegistrationBean;
}
}
主要是调用了servletServletRegistrationBean这个类
@Bean详解回顾
(74条消息) Spring中@Bean (工厂 Bean)详解_兮赫的博客-CSDN博客
@Bean用于修饰方法:
1.将方法返回的对象注册到spring容器
2.向方法形参注入数据
Filter是Servlet中的过滤器,可以去请求处理,对请求的参数,属性去做调整。常常在过滤器当中处理字符编码
在框架中去使用过滤器的步骤是两步:
1.创建自定义过滤类
2.注册Filter
3.创建Controller
自定义的Filter过滤类:
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("执行了MyFilter");
filterChain.doFilter(servletRequest, servletResponse);
}
}
配置类:
@Configuration
public class MyConfig {
@Bean
public FilterRegistrationBean filterRegistrationBean(){
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new MyFilter());
注意这里的*只用写一个,写两个也是会有问题的
bean.addUrlPatterns("/user/*");
return bean;
}
}
CharacterEncodingFilter:解决post请求当中乱码的问题
在SpringMVC当中,在web.xml文件当中去注册这个类
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q8g7wP3n-1659271632028)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220722171120114.png)]](https://1000bd.com/contentImg/2022/08/03/105646906.png)
默认编码是8859-1
第一种方式:
使用步骤:
1.配置字符集过滤器
servlet配置类:
@Bean
public ServletRegistrationBean serveletRegistrationBean(){
ServletRegistrationBean<Servlet> servletServletRegistrationBean = new ServletRegistrationBean<>(new MyServelt(),"/ser","/insert");
// public ServletRegistrationBean(T servlet, String... urlMappings)
return servletServletRegistrationBean;
}
@Be
字符集过滤器配置类:
@Bean
public FilterRegistrationBean filterRegistrationBean(){
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("utf-8");
filter.setForceRequestEncoding(true);
filter.setForceResponseEncoding(true);
// private String encoding;
// private boolean forceRequestEncoding;
// private boolean forceResponseEncoding;
FilterRegistrationBean reg = new FilterRegistrationBean(filter,serveletRegistrationBean());
return reg;
}
2.必须修改application.properties文件,让自定义的过滤器起作用
#springboot已经配置好了CharacterEncodingFilter,默认是ISO-8859-1
#设置为false是关闭系统中配置好的过滤器
server.servlet.encoding.enabled=false
第二种方式:
直接去修改application.properties文件
#springboot已经配置好了CharacterEncodingFilter,默认是ISO-8859-1
#设置为false是关闭系统中配置好的过滤器
server.servlet.encoding.enabled=true
#指定使用的编码方式
server.servlet.encoding.charset=UTF-8
#强制request,response都去使用charset属性的值
server.servlet.encoding.force=true
Object Relation Mapping
通过SpringBoot+Mybatis来实现对数据库学生表的查询操作
使用步骤:
1.mybatis起步依赖:完成mybatis对象的自动配置,对象放在容器当中
2.pom.xml指定把src/main/java目录中的xml文件包含在classpath当中
3.创建实体类Student
4.创建Dao接口StudentDao,创建一个查询学生的方法
5.创建Dao接口对应的Mapper文件,XML文件,写SQL语句
6.创建Service层对象,创建StudentService和实现类,去调用dao对象的方法,完成数据库的操作
7.创建Controller对象,访问Service
8.写application.properties文件:
配置数据库的信息
第一种方式:@Mapper
@Mapper:放在dao接口的上面,每个接口都需要使用这个注解
package com.example._008springbootmybatis.dao;
import com.example._008springbootmybatis.pojo.Student;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* 告诉MyBatis这是dao接口,创建此接口的代理对象
*/
@Mapper
public interface StudentDao {
Student selectById(@Param("stuId") Integer id);
}
Mapper.xml的配置文件
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example._008springbootmybatis.dao.StudentDao">
<select id="selectById" parameterType="int" resultType="com.example._008springbootmybatis.pojo.Student">
select id,name,age from student where id=#{stuId}
</select>
</mapper>
StudentService接口:只需要实现功能就行,不需要注入什么东西
package com.example._008springbootmybatis.service;
import com.example._008springbootmybatis.dao.StudentDao;
import com.example._008springbootmybatis.pojo.Student;
import org.apache.ibatis.annotations.Param;
import javax.annotation.Resource;
public interface StudentService {
Student selectById (Integer id);
}
service实现类:
package com.example._008springbootmybatis.service;
import com.example._008springbootmybatis.dao.StudentDao;
import com.example._008springbootmybatis.pojo.Student;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class StudentServiceImp implements StudentService{
@Resource
StudentDao studentDao;
@Override
public Student selectById(Integer id) {
return studentDao.selectById(id);
}
}
controller实现类:
package com.example._008springbootmybatis.controller;
import com.example._008springbootmybatis.pojo.Student;
import com.example._008springbootmybatis.service.StudentService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
@Controller
public class StudentController {
@Resource
StudentService studentService;
@RequestMapping("/query")
@ResponseBody
public String selectStudentById(Integer id){
Student student=studentService.selectById(id);
return student.toString();
}
}
application.properties的配置类:mapper.xml是需要去配置的否则会出问题的
#新的驱动类
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=wsy
#配置mapper xml的路径
mybatis-plus.mapper-locations=classpath:com/example/_008springbootmybatis/dao/*.xml
@Param讲解:
1.在SSM框架中,@Param主要是用来注解dao类中方法的参数,便于在对应的dao.xml文件中引用
2.用来简化xml配置,@Param注解的作用:
(1)给参数命名,参数命名后就能根据名字得到参数值,正确的将参数传入sql语句中
(2)在方法参数的前面写上@Param(“参数名”),表示给参数命名,名称就是括号中的内容
(3)在不使用@Param注解的时候,在查询语句取值时只能用#{},所属的类必须为Javabean
(4)使用@Param注解则可以使用多个参数,在查询语句中使用时可以使用#{}或者${}
3.@Param注解应用实例:
(1)在方法参数的前面写上@Param(“参数名”),表示给参数命名,名称就是括号中的内容
public Student select(@Param(“aaaa”) String name,@Param(“bbbb”) int password );
(2)然后sql语句where条件:where name= #{aaaa} 就可以根据aaaa得到参数值了
select name,password from user where name=
a
a
a
a
a
n
d
p
a
s
s
w
o
r
d
=
{aaaa} and password=
aaaaandpassword={bbbb}
4.@Param注解在Mabatis ${}与#{}的模糊查询中的应用
(1)在方法参数的前面写上@Param(“参数名”),表示给参数命名,名称就是括号中的内容
public Student select(@Param(“aaaa”) String name );
(2)模糊查询:like
select name from user where name like concat(‘%’,#{aaaa},‘%’)
5.注意事项
(1)如果方法参数不使用@Param注解,那么sql语句中where条件语句中必须使用字段名
(2)使用模糊查询参数有两种方式:
<1>select * from user where name like ‘%
n
a
m
e
1
.
′
{name}%' 1.'%
name1.′{name}%’ 解析成:select * from user where name like ‘%yuan%’
<2>select * from user where name like ‘%#{name}%’
1.‘%#{name}%’ 解析成:select * from user where name like ‘%?%’
<3>但是 ‘%#{name}%’ 解析会发成运行错误
1.Error querying database.
2.可以看出’%#{name}%’ 是无法正确运行
3.但是使用
无法防止
s
q
l
注入(
3
)解决模糊查询传参方法如下:
<
1
>
方法参数前面使用注解
@
P
a
r
a
m
,然后
s
q
l
语句中
w
h
e
r
e
条件中就可以使用
{} 无法防止sql注入 (3)解决模糊查询传参方法如下: <1>方法参数前面使用注解@Param,然后sql语句中where条件中就可以使用
无法防止sql注入(3)解决模糊查询传参方法如下:<1>方法参数前面使用注解@Param,然后sql语句中where条件中就可以使用{}进行传参
<2>不使用注解@Param时,where条件使用#{}传参:使用concat()函数拼接:
select name from user where name like concat(‘%’,#{name},‘%’)
<3>使用concat()函数拼接可以避免直接使用’%#{}%',运行出错!
@Repository和@Mapper的区别
@Repository
@Repository 是 Spring 的注解,用于声明一个 Bean。@Repository单独使用没用。可以这样理解,注解放在接口上本来就没有意义,spring中在mapper接口上写一个@Repository注解,只是为了标识,要想真正是这个接口被扫描,必须使用@MapperScannerConfigurer
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.shenlei.mapper"/>
bean>
这段配置会扫描com.**.mapper包下所有的接口,然后创建各自的动态代理类。
与spring集成可分三个步骤:
1、把java类对应的Mapper接口类纳入spring总的IOC容器。
2、把Java类对应的XML命名空间添加到Mybatis中的Configuration类中的mapperRegistry(用于管理Mybatis的Mapper)
3、使用spring中的IOC容器拓展FactoryBean获取到Mapper的实例。(第一步纳入spring只是接口)
@Mapper
@Mapper是mybatis自身带的注解。在spring程序中,mybatis需要找到对应的mapper,在编译时生成动态代理类,与数据库进行交互,这时需要用到@Mapper注解,但是有时候当我们有很多mapper接口时,就需要写很多@Mapper注解,这样很麻烦,有一种简便的配置化方法便是在启动类上使用@MapperScan注解。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZSpvDCcP-1659271632029)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220726183035013.png)]](https://1000bd.com/contentImg/2022/08/03/105647036.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LJoQRGLD-1659271632029)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220726183110174.png)]](https://1000bd.com/contentImg/2022/08/03/105647190.png)
这样可以自动扫描包路径下所有的mapper接口,从而不用再在接口上添加任何注解。
3、区别
相同点:
@Mapper和@Repository都是作用在dao层接口,使得其生成代理对象bean,交给spring 容器管理
对于mybatis来说,都可以不用写mapper.xml文件
不同点:
(1)、@Mapper不需要配置扫描地址,可以单独使用,如果有多个mapper文件的话,可以在项目启动类中加入@MapperScan(“mapper文件所在包”)
(2)、@Repository不可以单独使用,否则会报错误,要想用,必须配置扫描地址(@MapperScannerConfigurer)
4、解决使用@mapper接口时,注入mapper爆红问题
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UCJjWlyH-1659271632030)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220725183616642.png)]](https://1000bd.com/contentImg/2022/08/03/105647348.png)
在idea中单独使用@Mapper注解,在@Autowired时,idea会提示找不到bean,但是不影响运行,如果想消除爆红,可以将@Mapper注解跟@Repository注解一起用,这样便可消除爆红
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EDCkMnU8-1659271632030)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220725183635841.png)]](https://1000bd.com/contentImg/2022/08/03/105647633.png)
第二种方式@MapperScan注解:
之前是,直接在Mapper类上面添加注解@Mapper,这种方式要求每一个mapper类都需要添加此注解,麻烦。
通过使用@MapperScan可以指定要扫描的Mapper类的包的路径,比如:
@SpringBootApplication
@MapperScan("com.lz.water.monitor.mapper")
// 添加对mapper包扫描
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
同时,使用@MapperScan注解多个包
@SpringBootApplication
@MapperScan({"com.kfit.demo","com.kfit.user"})
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
启动文件:
@MapperScan(basePackages = "com.example._008springbootmybatis.dao")
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
第三种方式:Mapper文件和Dao接口分开去管理
现在把Mapper文件放在resources目录下
1 )在resources目录中创建子目录(自定义的),例如mapper
2 )把mapper文件放到mapper目录中
3 )在application.properties文件中,指定mapper文件的目录
4)在pom文件当中指定resources目录中的文件,编译到目标目录当中
mapper.xml文件放置的位置:
<resources>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.xmlinclude>
<include>**/*.propertiesinclude>
includes>
resource>
<resource>
<directory>src/main/resourcesdirectory>
<includes>
<include>**/*.xmlinclude>
<include>**/*.propertiesinclude>
includes>
resource>
resources>
最好都放在resources目录之下:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qXzP1xIG-1659271632031)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220725203118399.png)]](https://1000bd.com/contentImg/2022/08/03/105647706.png)
并且在application.properties下面还需要写这样一行代码:
保证在classpath的目录下面可以找到文件
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis日志需要打开:
#配置日志
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HIoYwVP0-1659271632032)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220725203938313.png)]](https://1000bd.com/contentImg/2022/08/03/105647854.png)
Spring框架中的事务:
1)管理事务的对象:事务管理器(接口,接口有很多的实现类)
例如:使用Jdbc或mybatis访问数据库,使用的事务管理器: DataSourceTransactionManager
2)声明式事务:在xml配置文件或者使用注解说明事务控制的内容
控制事务:隔离级别,传播行为,超时时间
3)事务处理方式:
1.Spring框架中的@ Transactional
2.aspectj框架可以在xml配置文件中 ,声明事务控制的内容
SpringBoot中使用事务:上面的两种方式都可以。
1)在业务方法的上面加入@Transactional, 加入注解后,方法有事务功能了。
2)明确的在主启动类的上面, 加入@EnableTransactionManager
Generrator生成器配置:
pom文件:
<plugin>
<groupId>org.mybatis.generatorgroupId>
<artifactId>mybatis-generator-maven-pluginartifactId>
<version>1.3.6version>
<configuration>
<configurationFile>GeneratorMapper.xmlconfigurationFile>
<verbose>trueverbose>
<overwrite>trueoverwrite>
configuration>
plugin>
GeneratorMapper.xml配置文件要求放在根目录之下:
DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<classPathEntry location="D:\Program Files\Apache\maven\apache-maven-3.8.4-bin\apache-maven-3.8.4\maven-repo\mysql\mysql-connector-java\8.0.29\mysql-connector-java-8.0.29.jar"/>
<context id="tables" targetRuntime="MyBatis3">
<commentGenerator>
<property name="suppressAllComments" value="true" />
commentGenerator>
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8"
userId="root"
password="wsy">
jdbcConnection>
<javaModelGenerator targetPackage="com.example._009springboottrans.model"
targetProject="D:\JavaPractice\SpringBoot\springboot-pri\009-springboot-trans\src\main\java">
<property name="enableSubPackages" value="false" />
<property name="trimStrings" value="false" />
javaModelGenerator>
<sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources">
<property name="enableSubPackages" value="false" />
sqlMapGenerator>
<javaClientGenerator type="XMLMAPPER" targetPackage="com.example._009springboottrans.dao" targetProject="src/main/java">
<property name="enableSubPackages" value="false" />
javaClientGenerator>
<table tableName="student" domainObjectName="Student"
enableCountByExample="false"
enableUpdateByExample="false"
enableDeleteByExample="false"
enableSelectByExample="false"
selectByExampleQueryId="false"/>
context>
generatorConfiguration>
最终效果:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-is2L29Q7-1659271632032)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220726101127726.png)]](https://1000bd.com/contentImg/2022/08/03/105648061.png)
在service上面上面去添加事务的注解
/**
* @Transactional 表示方法有事务的支持
* 默认使用库的隔离级别,REQUIRED 传播行为:超时时间 -1
* 抛出运行时异常,回滚事务
* @param record
* @return rows
*/
@Transactional
@Override
public int insert(Student record) {
int rows = studentMapper.insert(record);
return rows;
}
在启动类上面去添加启动事务管理器的注解
/**
* 启用事务管理器
*/
@EnableTransactionManagement
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
1、对比事务加在service层与dao层
结合事务的四大特性(ACID),即可很好的解释为什么加在service层。首先,如果事务注解@Transactional加在dao层,那么只要与数据库做增删改,就需要提交一次事务;如此做事务的特性就发挥不出来,特别是事务的一致性,当出现并发问题时,从数据库查到的数据都有可能存在所偏差。
一般情况下,service层调用多个dao层的方法,只需要在service层的方法之上,加一个事务注解@Transactional即可;如此,使用一个事务处理多个数据库的请求,事务的特性也会充分的发挥出来。
2、各层加事务的区别
Spring事务为业务逻辑进行事务管理,保证业务逻辑上数据的原子性。
事务得根据项目性质来细分:事务可以设置到三个层面(dao层、service层和web层)。
第一:controller层事务
这一般是针对那些安全性要求较高的系统来说的。例如电子商务网站。粒度小,一般系统用不着这么细。
第二:service层事务
这是一常见的事务划分, 将事务设置在业务逻辑上,只要业务逻辑出错或异常就事务回滚。粒度较小,一般推荐这种方式。
第三:dao层数据务
也就是常说的数据库事务。这种事务在安全性方面要求低。就是给一个简单的增删改之类的操作增加事务操作。粒度大。
给Service层配置事务,因为一个Service层方法操作可以关联到多个DAO的操作。在Service层执行这些Dao操作,多DAO操作有失败全部回滚,成功则全部提交。
事务分为业务事务和系统事务,业务事务也就是业务逻辑上操作的一致性,系统事务自然就是指真正的数据库事务,
Spring配置事务的是为了什么进行管理,当然是为业务逻辑进行事务管理,保证业务逻辑上数据的原子性;
Dao层是什么,数据访问层,是不应该包含业务逻辑的,这就是和Service层的不同;
Service层就是业务逻辑层,事务的管理就是为Service层上的保证。
API介绍:
*API*全称(*Aplication* *Programming* *Interface*),一般来说就是 软件组件之间信息交互的桥梁。
Aplication(软件组件)
Protocol (协议):规定了各部分之间如何进行信息交互的规则和步骤
Interface(接口):我认为在API里的接口可以看做是一个接待窗口,对各个软件组件开、放,他们可以通过接口来实现与其他组件的信息交互。
Format(格式):要进行信息交互,我们又意识到交互双方语言必须相同呀,所以又引出了另一个概念 格式(format) ,在程序员的世界里,通用的格式包含XML和JSON。
在API术语里,API端点通常是指一个接口中提供特定功能的子集的服务提供者,不同的端点可以有不同的协议和不同的格式。
REST (英文: Representational State Transfer,简称REST)
表现层状态转移,也就是视图层状态转移,显示资源的,通过视图界面,jsp等来显示操作资源的结果。
一种互联网软件架构设计的风格,但它并不是标准,它只是提出了一组客户端和服务器交互时的架构理念和设计原则,基于这种理念和原则设计的接口可以更简洁,更有层次,REST这个词,是RoyThomasFielding在他2000年的博士论文中提出的。
任何的技术都可以实现这种理念,如果-一个架构符合REST原则,就称它为RESTFul架构
比如我们要访问一个http接口: http://localhost :8080/ boot/ order?id=102l&status=1
采用RESTFul风格则http地址为: http://localhost:8080/boot/ order/1021/1
使用RESTful操作资源
【GET】 /users # 查询用户信息列表
【GET】 /users/1001 # 查看某个用户信息
【POST】 /users # 新建用户信息
【PUT】 /users/1001 # 更新用户信息(全部字段)
【PATCH】 /users/1001 # 更新用户信息(部分字段)
【DELETE】 /users/1001 # 删除用户信息
RESTful架构风格
1)REST: ( 英文: Representational State Transfer ,中文:表现层状态转移)。
REST :是一种接口的架构风格和设计的理念,不是标准。
优点:更简洁,更有层次
2 ) REST中的要素:
用REST表示资源和对资源的操作。在互联网中 ,表示一个资源或者一个操作。
资源使用url表示的,在互联网,使用的图片,视频,文本,网页等等都是资源。
对资源:
查询资源:看,通过url找到资源。
创建资源:添加资源
更新资源:更新资源,编辑
删除资源:去除
资源使用url表示,通过名词表示资源。
使用http中的动作(请求方式),表示对资源的操作( CURD )
使用http中的动作(请求方式),表示对资源的操作( CURD )
GET:查询资源- sql select
查询单个学生
http://localhost:8080/myboot/student/1001
http://localhost:8080/myboot/student/1001/1
查询单个学生
http://localhost:8080/myboot/students/1001/1002
POST:创建资源- sql insert
http://localhost:8080/myboot/student
在post请求中传递数据
<form acti on="http://localhost:8080/myboot/student" method=" post">
姓名: <input type="text" name="name" />
年龄: <input type="text" name="age" />
form>
PUT:更新资源- sql update
姓名: 年龄:<input type="hidden" name="_method" value="PUT"/>
DELETE:删除资源-- sql delete
<a href="http://localhost:8080/myboot/student/1">删除1的数据a>
一句话来概括REST:使用url来表示资源,使用http动作来操作资源
@PathVariable
@PathVariable 映射 URL 绑定的占位符
通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过
@PathVariable(“xxx”) 绑定到操作方法的入参中。
一般与@RequestMapping(method = RequestMethod.GET)一起使用
1、若方法参数名称和需要绑定的url中变量名称一致时,可以简写:
@RequestMapping("/getUser/{name}")
public User getUser(@PathVariable String name){
return userService.selectUser(name);
}
2、若方法参数名称和需要绑定的url中变量名称不一致时,写成:
@RequestMapping("/getUserById/{name}")
public User getUser(@PathVariable("name") String userName){
return userService.selectUser(userName);
}
Spring的复杂性不是来自于它处理的对象,而是来自于自身,不断演进发展的Spring会带来时间维度上复杂性,比如SpringMVC以前版本的*@RequestMapping*,到了新版本被下面新注释替代,相当于增加的选项:
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
从命名约定我们可以看到每个注释都是为了处理各自的传入请求方法类型,即*@GetMapping用于处理请求方法的GET类型,@ PostMapping用于处理请求方法的POST*类型等。
如果我们想使用传统的*@RequestMapping*注释实现URL处理程序,那么它应该是这样的:
@RequestMapping(value = “/get/{id}”, method = RequestMethod.GET)
新方法可以简化为:
@GetMapping(“/get/{id}”)
@PathVariable:从url中获取数据
@GetMapping:支持的get请求方式 ,等同于@RequestMapping( method=RequestMethod.GET)
@PostMapping:支持post请求方式, 等同于@RequestMapping( method=RequestMethod.POST)
@PutMapping:支持put请求方式,等同于@RequestMapping( method=RequestMethod.PUT)
@DeleteMapping:支持delete请求方式,等同于 @RequestMapping( method=RequestMethod.DELETE)
@RestController:复合注解,是@Controller 和@ResponseBody组合。
在类的上面使用@RestController,表示当前类者的所有方法都加入了@ResponseBody
@PathVariable使用代码:
@RestController
public class MyRestController {
@GetMapping("/pop/{name}")
public String pop(@PathVariable String name){
return "这是"+name;
}
}
PostMan测试工具使用:
@RestController
public class MyRestController {
/**
* 创建资源GET请求
* @param name
* @return
*/
@GetMapping("/pop/{name}")
public String get(@PathVariable String name){
return "这是get"+name;
}
/**
* 创建post请求资源
* @param name
* @return
*/
@PostMapping("/pop/{name}")
public String post(@PathVariable String name){
return "这是post"+name;
}
/**
* 创建delete请求资源
* @param name
* @return
*/
@DeleteMapping("/pop/{name}")
public String delete(@PathVariable String name){
return "这是delete"+name;
}
/**
* 创建put请求资源
* @param name
* @return
*/
@PutMapping("/pop/{name}")
public String put(@PathVariable String name){
return "这是put"+name;
}
}
postman界面图:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RnM8Sh0K-1659271632033)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220726175950127.png)]](https://1000bd.com/contentImg/2022/08/03/105648195.png)
真实提交的场景:
前端代码 可以写个hidden标签将这个数据传上去
<body>
<form action="http://localhost:8080/pop/wsy" method="post">
<input type="hidden" name="_method" value="put">
<input type="submit" value="提交按钮">
form>
<form action="http://localhost:8080/pop/wsy" method="post">
<input type="hidden" name="_method" value="delete">
<input type="submit" value="提交按钮">
form>
body>
但是后端需要配置springmvc的一个过滤器才可以保证将类型进行转化
spring.mvc.hiddenmethod.filter.enabled=true
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AMhW0UIo-1659271632034)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220726182342901.png)]](https://1000bd.com/contentImg/2022/08/03/105648463.png)
这种路径可能会引起一定的歧义,所以最好不要这么去写
P67 - > Redis