spring
1.IoC与DI与注解开发与spring整合mybatis
1.IoC与DI与spring的依赖注入
1.spring概述
作用:1.简化开发 2.框架整合,整合其他技术,提高开发的效率
简化开发:IoC AOP
-
Spring Framework: spring框架的底层。所有spring框架都基于他
-
pom.xml导入spring
-
<!--导入spring--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.10.RELEASE</version> </depenency>
2.IoC概述
-
IoC(Inversion of Control)(控制反转) :
思想:使用对象时,不用主动去new对象,这样不仅代码量多,而且代码耦 合度高,所以转化为外部提供对象
实现:spring实现了这个思想,spring提供了一个IoC容器,IoC容器就充当了思想中的外部。
所以,IoC容器负责对象的创建,初始化工作,被创建被管理的IoC容器被称为Bean
-
Hello 对象是谁创建的 ? hello 对象是由Spring创建的
-
Hello 对象的属性是怎么设置的 ? hello 对象的属性是由Spring容器设置的
这个过程就叫控制反转 :
- 控制 : 谁来控制对象的创建 , 传统应用程序的对象是由程序本身控制创建的 , 使用Spring后 , 对象是由Spring来创建的
- 反转 : 程序本身不创建对象 , 而变成被动的接收对象
3.DI,依赖注入
-
DI(Dependency Injection)依赖注入,实现IoC的方法
容器中bean与bean之间的依赖关系的整个过程,就是把容器中需要的两个对象绑定的过程,称为依赖注入:用标签
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl" scope="prototype"> <!-- property表示配置bean的属性--> <!-- name表示配置哪一个具体的属性--> <!-- ref表示参照哪一个bean--> <property name="bookDao" ref="bookDao"/>
-
测试:(这里为通过xml方式配置的bean的测试方法,与注解方式有点不同)
-
@Test public void test01(){
//解析applicationContext.xml的bean文件,生成管理的bean对象
-
ApplicationContext context = new ClassPathXmlApplicationContext(“applicationContext.xml”);
//getBean:获取bean,括号内的参数为spring配置文件中bean的id
-
Student student = (Student) context.getBean(“student”);
-
System.out.println(student.getName()); }
4.Set注入:
set 注入也叫设值注入,是指通过 setter 方法传入被调用者的实例。这种注入方式简单、直观,因而在 Spring 的依赖注入中大量使用。
根据属性的数据类型的不同,set注入又可以分为简单类型的set注入和引用类型的set注入。
5.Singleton(单例模式):
当一个bean的作用域为Singleton,那么Spring IoC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。Singleton是单例类型,就是在创建起容器时就同时自动创建了一个bean的对象,不管你是否使用,他都存在了,每次获取到的对象都是同一个对象。注意,Singleton作用域是Spring中的缺省作用域。要在XML中将bean定义成singleton,可以这样配置:
6.IoC容器中的依赖自动装配:
分为两种:
autowire byName (按名称自动装配)
autowire byType (按类型自动装配)
步骤:①:找到需要自动装配的对象,就是new对象时前半部分的那些字符,比如User user…
②:setter方法还是不能删
③:直接留一行就行,最常用为autowire=“byType” 按照类型
注意:用于引用类型,不能对简单类型进行操作
7.数据源对象管理:就是对别人的依赖进行导入配置 ,然后按照id和class中配置name和value
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
加载properties文件,例如jdbc的配置文件就是.properties的文件
8.总结
-
创建IoC容器的方式:两种:
①:常用:ApplicationContext cxt = new ClassPathXmlApplicationContext(“applicationContext.xml”);
②:不建议,路径使用绝对路径:FileSystemXmlApplicationContext fsxac = new FileSystemXmlApplicationContext(“D:\Java\workspace\spring_01_quickstart\src\main\resources\applicationContext.xml”);
-
获取bean的方式
BookService bookService = (BookService) cxt.getBean("bookService");
BookService bookService = cxt.getBean("bookService",BookService.class);
BookService bookService = cxt.getBean(BookService.class);
2.注解开发
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IOeIrJKb-1664441127262)(C:\Users\Administrator\Desktop\29F1DFA81BB6DCE580D60A1319749E50(1)].jpg)
注解开发:
①:定义bean时,一般在resources目录下的 applicationContext.xml,使用注解,直接在需要设置bean的类中,定义一个注解
@Component()不建议,:定义一个bean:@Controller 用于表现层的bean
@Service 用于业务层的bean @Repository 用于数据层的bean
因为这个还是要写applicationContext.xml文件 要写context:component-scan/ 后面写需要配置的路径
@Configuration
@ComponentScan(“com.itheima”):(常用) 括号内为需要定义bean的路径,为一个数组,可以定义多个({“com.itheima.Service”,“com.itheima.Dao”})
②:@Scope (“”) 设置是否为单例对象,属性为singleton为单例
③:@PostConstructor @PreDestroy bean的生命周期
④:@Autowired :设置依赖注入 @Value :基础类型的依赖注入
⑤:@bean : 配置第三方的bean
3.spring整合mybatis
1.导入spring整合jdbc的包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
2.导入spring整合mybatis的包
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
2.spring整合junit
2.AOP:面向切面编程:
AOP:需要实现的功能和作用:在不惊动原始设计的基础上为其进行功能增强
核心概念:
1.步骤:①:在pom.xml文件中导入坐标(两个)
第一个在导入spring坐标时已经导入了,不用再去导入
<!-- spring整合jdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<!--导入aop切面编程的坐标-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
1.代理设计模式: java里常用的设计模式
特点: 1.具体类和代理类有相同的接口或者共同的父类
2.代理类为具体类负责消息的处理,并将消息转发给具体类
3.代理类本身并不是真正的实现者,而是通过调研具体类的方法来实现的
2.按照代理类创建的时机,分两类:
1.静态代理: 是有我们程序员或者是特定的工具生成的
2.动态代理: 在程序运行期间,通过反射的方式动态的创建出来的
2.1: jdk动态代理(接口):
必须知道一个类和一个接口
InvocationHandler 只有一个方法
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable
proxy:代理类的对象
method: 被代理的方法
args:被代理的方法的参数列表
2.2: Proxy:类
3. aop: 1.Advice(增强代码功能的类)
2.织入(Weaving):对方法进行增强:
1.前置增强: 在目标方法前调用
2.后置增强: 在目标方法后调用
3.环绕增强、:可以把前置 后置 异常抛出增强、最终增强等合到一起
异常抛出增强、最终增强等类型
4.Pointcut(切入点): 就是带有通知的连接点,在程序里主要体现为书写切入点的表达式:
5.Join Point:(连接点):程序执行过程里明确的一个点,一般就是方法的调用
6.Aspect(切面): 通常指的是一个类(里面可以指定切入点和通知)
aop:好处:每个事物逻辑位于一个位置,代码不分散,便于维护和升级
业务模块更简洁了,只包含核心的业务代码
spring:spring里aop代理由spring的IOC容器负责生产,管理,其依赖关系由IOC容器负责管理,因此AOP代理可以直接使用容器里的其他bean 实例作为目标。
3.spring事务
4.springMVC
1.springMVC简介
1.简介:
springMVC技术与Servlet技术功能相同,都属于web层开发技术
springMVC可以代替Servlet,可以实现Servlet的所有功能
是一种表现层框架技术
本章目标:
1.掌握基于SpringMVC获取请求参数与响应json数据操作
2.熟练应用基于REST风格的请求路径设置与参数传递
3.能够根据实际业务建立前后端开发通信协议并进行实现
4.基于SSM整合技术开发任意业务模块功能
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nGOCuLN7-1664441127264)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220824200153192.png)]
springMVC的优点:1.使用简单,开发便捷 2.灵活性强
2.入门案列基本创建流程
(1)导入servlet,springmvc坐标,记住后面还有tomcat坐标
<dependencies>
<!-- 导入springmvc servlet坐标-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<!-- 这一行是为了防止xml文件配置的tomcat与插件有冲突-->
<scope>provided</scope>
</dependency>
<!-- springmvc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
</dependencies>
(2)建立controller层:com.itheima.controller.UserController.java,文件名自己定
(3)因为这是一个spring项目,要定义bean:@Component。但是@Component下有三个子目录,分别为@Controller,@Service,@Repository
这里因为在表现层,就直接用@Controller注解
(4)设置当前操作的访问路径:@RequestMapping(“/save”) 括号内为访问的路径
(5)设置当前操作的返回值类型:@ResponseBody
//1.定义Controller
//2.使用@Controller定义bean
//3.设置当前操作的访问路径
//4.设置当前操作的返回值类型
@Controller
public class UserController {
//设置当前操作的访问路径
@RequestMapping("/save")
//设置当前操作的返回值类型
@ResponseBody
public String save(){
System.out.println("user save...");
return "{'module':'springmvc'}";
}
}
(6)创建springmvc配置文件(重新建一个包,文件名自己定com.itheima.config.SpringMvcConfig.java),加载controller对应的bean
//做一个spring也可以叫springmvc的配置类,加载controller对应的bean
//做一个配置类,就用这个注解
@Configuration
//扫描对应的bean,用这个注解
@ComponentScan("com.itheima.controller")
public class SpringMvcConfig {
}
(7)创建一个servlet容器的配置类,在里面加载spring的配置(重新建一个包,文件名自己定 com.itheima.config.ServletContainConfig.java)
定义类,继承AbstractDispatcherServletInitializer,重写里面的三个方法,记住每个方法分别有什么作用
//定义一个servlet容器启动的配置类,在里面加载spring的配置
public class ServletContainConfig extends AbstractDispatcherServletInitializer {
//加载springMVC容器配置
@Override
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringMvcConfig.class);
return ctx;
}
//设置哪些请求归属springMVC处理
@Override
protected String[] getServletMappings() {
// return new String[0];
return new String[]{"/"};
}
//加载spring容器配置
@Override
protected WebApplicationContext createRootApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringConfig.class);
return ctx;
}
}
可以有简便方法
//定义一个servlet容器启动的配置类,在里面加载spring的配置
public class ServletContainConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
//注意这里面为spring的
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
//这里面为springMVC的
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
(8)删除web.xml,这个应该不是必须要,在pom.xml文件中配置tomcat,然后启动
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>80</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
3.SpringMVC的工作流程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LRgYP3N6-1664441127264)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220824211839684.png)]
4.bean的加载控制
springMVC相关的bean(表现层的bean)
spring控制的bean:
业务bean(Service)
功能bean (DataSource)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vqj1GaGv-1664441127264)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220825113038326.png)]
spring扫描包的时候,可能会把springMVC相关的bean一起扫描
因为spring扫描包的时候,可能是整个文件全部扫描,controller层属于整个包中,所依要将它排除掉。
基本都要扫描,防止技术更换,对程序有过大的影响
两种方法:
//第一种方式,指定那几个包,用{}括起来
@ComponentScan({"com.itheima.service","com.itheima.dao"})
//第二种方式,排除
@ComponentScan(value = "com.itheima",//扫描哪个包
excludeFilters = @ComponentScan.Filter(//排除规则
type = FilterType.ANNOTATION,//按照注解的方式排除
classes = Controller.class//这就是具体的注解类型
)
)
5.Postmam插件,可以模拟浏览器发送请求
浏览器发送get请求,只需要输入地址栏
浏览器发送post请求,要用表单实现
浏览器发送ajax请求,就更复杂
不要去写一系列代码,就能测试
2.请求与响应
1.请求:设置请求路径:@RequestMapping(“路径”)
作用:设置当前控制器的访问路径
可以设置在方法上,为全局路径,下面的路径就不用写第一层路径
不设置在方法上,就每个都要补全路径
@Controller
@RequestMapping("/user")
public class UserController {
//定义访问路径
// @RequestMapping("/user/save")
@RequestMapping("/save")
//定义返回值类型
@ResponseBody
public String save(){
System.out.println("springmvc...save");
return "{user save success}";
}
// @RequestMapping("/user/delete")
@RequestMapping("/delete")
@ResponseBody
public String delete(){
System.out.println("springmvc...delete");
return "{user delete success}";
}
}
2.五种参数传递的发送:
1.普通参数,
前端传到后端,在后端的接收方法上定义参数,可以直接传送到后端
http://localhost/user/save?name=zhangsan&age=15在路径中直接定义参数
直接方法接收
@RequestMapping("/save")
//定义返回值类型
@ResponseBody
public String save(String name, int age){
System.out.println("springmvc...save" +name);
System.out.println("springmvc...save" +age);
return "{user save success}";
}
2.发送一个实例对象,User user
结果:springmvc…deleteUser{name=‘zhangsan’, age=19}
若是实例对象User中有其他的实例对象,然后传参数是直接Book.name,然后也能直接传
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U5UADC8l-1664441127265)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220826141504067.png)]
// @RequestMapping("/user/delete")
@RequestMapping("/delete")
@ResponseBody
public String delete(User user){
System.out.println("springmvc...delete"+user);
return "{user delete success}";
}
3.接收数组:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yReo1Nt6-1664441127265)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220826143350252.png)]
// @RequestMapping("/user/hobby")
@RequestMapping("/hobby")
public String hobby(String[] likes){
System.out.println("接收的数组为"+ Arrays.toString(likes));
return "{user hobby success}";
}
4.接收数组:
//记得加上注解@RequestParam,不加注解就是会当成一个实例对象处理
// @RequestMapping("/user/list")
@RequestMapping("/list")
public String list(@RequestParam List<String> likes){
System.out.println("接收的集合为"+ likes);
return "{user list success}";
}
5.请求参数:json格式的参数(重要)
1.导入json坐标
<!--fast json-->
<!-- 实现java对象与json的互相转换,-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
<!--json坐标-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
2.发送json数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qg8nlEaT-1664441127266)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220830191953684.png)]
3.开启自动转换json数据的支持
在Config.SpringMvcConfig.java(这是上面创建mvc项目时创建的配置文件)文件下,加入一行@EnableWebMvc(可以开启自动转换json格式的支持,这个注释整合了多个注释,功能强大,这只是其中一点)
//bean的配置类
@Configuration
//扫描需要对应的bean
@ComponentScan("com.itheima.controller")
//自动转换json格式
@EnableWebMvc
public class SpringMvcConfig {
}
4.后端接收json数据(别忘了在参数部分加上注解@RequestBody)
注意json格式,什么格式的json,参数对应什么格式
@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson(@RequestBody List<String> likes){
System.out.println("list common(json)参数传递 list ==>"+likes);
return "{'module':'list common for json param'}";
}
6.以后开发中,会经常用到@requestBody注解。这是用来接收json格式的数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uRGBfuqg-1664441127266)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220830193051533.png)]
6.接收日期类型
默认类型为yyyy/MM/dd
其他类型要用 @DateTimeFormat(pattern=“yyyy-MM-dd”)
@DateTimeFormat(pattern = “yyyy/MM/dd HH:mm:ss”)
标签转换
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ldXxGxxS-1664441127266)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220830195316488.png)]
//转换日期型
@RequestMapping("/datetime")
@ResponseBody
public String datetime(Date date,
@DateTimeFormat(pattern="yyyy-MM-dd") Date date1,
@DateTimeFormat(pattern = "yyyy/MM/dd HH:mm:ss") Date date2){
System.out.println("date 参数传递==>"+date);
System.out.println("date1 参数传递@DateTimeFormat(pattern=\"yyyy-MM-dd\")==>"+date1);
System.out.println("date2 参数传递@DateTimeFormat(pattern = \"yyyy/MM/dd HH:mm:ss\")==>"+date2);
return "{'module':'list common for json param'}";
}
get请求:
post请求:
中文乱码问题:在Servlet配置文件中,重写设置一个过滤器
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
return new Filter[]{filter};
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6lNKx0ny-1664441127266)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220826103400770.png)]
3.REST风格
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V2zTiYRV-1664441127267)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220901170619321.png)]
4.SSM整合
1.大概的整合步骤:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QjS1Afh0-1664441127267)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220902095545884.png)]
2.具体整合步骤:
①:导入对应坐标(这个版本应该就是比较全的坐标版本)
<dependencies>
<!-- 导入springMvc servlet坐标,servlet,就是专门用来接收客户端的请求,专门接收客户端的请求数据,然后调用底层service处理数据并生成结果
浏览器http请-》tomcat服务器-》到达servlet-》执行doget,dopost方法-》返回数据-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<!-- 这一行是为了防止xml文件配置的tomcat与插件有冲突-->
<scope>provided</scope>
</dependency>
<!-- springMvc,里面有许多的常用的jar包,使用mvc框架的基础坐标,包括管理bean的context坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<!-- spring整合jdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<!-- spring整合Mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<!-- 导入mysql坐标,就是mysql使用必须导入-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- 导入mybatis框架坐标-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!-- 获取数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<!--fast json-->
<!-- 实现java对象与json的互相转换,-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
<!--json坐标-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<!-- @test测试类坐标-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<!-- 这里可以设置访问路径,这里设为默认的80坐标-->
<configuration>
<port>80</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
②:补全目录结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gYpST0gj-1664441127268)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220902141502845.png)]
3.补全各个目录的类:
1.config目录:
①:1.config目录下定义SpringConfig.calss文件(先定义1.2步骤,其他后面需要才加上)(2.先定义jdbc.properties文件(jdbc链接数据库最基本的配置文件),3.创建JdbcConfig文件(配置文件),4.创建MybatisConfig文件(配置文件),在实现第3.4步)
Jdbc.properties文件:
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm_db?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=123456
JdbcConfig文件:主要是定义数据源,就是把后端跟数据库相连。
package com.itheima.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;
/**
* @Description; Auther: Administrator
* Date:2022/9/2 14:26
*/
public class JdbcConfig {
@Value("${jdbc.driverClassName}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
//数据源
@Bean
public DataSource dataSource(){
DruidDataSource dataSource =new DruidDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
MybatisConfig文件(两个bean):
package com.itheima.config;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;
/**
* @Description; Auther: Administrator
* Date:2022/9/2 14:26
*/
public class MybatisConfig {
//创建sqlSessionFactory对象,工厂对象
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
//sqlSessionFactory工厂对象对应实现类
factoryBean.setTypeAliasesPackage("com.itheima.domain");
return factoryBean;
}
//扫描mapper,因为用mapper代理模式开发
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer msc = new MapperScannerConfigurer();
//mapper代理模式要对应dao层,就是接口层
msc.setBasePackage("com.itheima.dao");
return msc;
}
}
这里有个错误:classpath:jdbc.properties (这里要加classpath)
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [com.itheima.config.SpringConfig]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/jdbc.properties]
package com.itheima.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* @Description; Auther: Administrator
* Date:2022/9/2 14:18
*/
//1.把这个类定义为一个配置类
@Configuration
//2.设定配置文件的扫描路径,记得要与SpringMvc的配置的扫描区分开,需要添加就继续加。
//@ComponentScan({"com.itheima.service","com.itheima.controller"})
@ComponentScan({"com.itheima.service"})
//3.在jdbc.properties文件中,会加载一些文件中的属性jdbc.driverClassName,jdbc.url,jdbc.username,jdbc.password
@PropertySource("classpath:jdbc.properties")
//4.要在SpringConfig配置类文件中导入JdbcConfig,MybatisConfig配置类文件
@Import({JdbcConfig.class,MybatisConfig.class})
public class SpringConfig {
}
②:config目录下:spring整合mvc
1.创建web容器的配置类:ServletConfig配置类
package com.itheima.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
/**
* @Description; Auther: Administrator
* Date:2022/9/2 21:15
*/
public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
//这里加SpringConfig配置文件
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
//这里加SpringMvcConfig配置文件
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
//这里为接收的请求,这里为所有
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
//这里可以加过滤器
}
2.SpringMvcConfig配置类
package com.itheima.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
/**
* @Description; Auther: Administrator
* Date:2022/9/2 21:16
*/
//配置类
@Configuration
//扫描包
@ComponentScan("con.itheima.controller")
//这标签功能很强,
@EnableWebMvc
public class SpringMvcConfig {
}
2.其他目录:就是mybatis步骤
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7etWV5zI-1664441127268)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220902214207174.png)]
1.domain包下创建实体类:Book(这就不说了)
2.dao层:建立增删改查方法,并且使用注解开发
package com.itheima.dao;
import com.itheima.domain.Book;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
/**
* @Description; Auther: Administrator
* Date:2022/9/2 21:34
*/
public interface BookDao {
//增加
//@Insert("insert into tbl_book values(null,#{type},#{name},#{description})")
@Insert("insert into tbl_book(type,name,description) values(#{type},#{name},#{description})")
public void save(Book book);
@Update("update tbl_book set type = #{type},name = #{name},description = #{description} where id=#{id}")
public void update(Book book);
@Delete("delete from tbl_book where id = #{id}")
public void delete(Integer id);
@Select("select * from tbl_book where id=#{id}")
public Book getById(Integer id);
@Select("select * from tbl_book")
public List<Book> getAll();
}
3.Service层:
①:建立其中service层的接口BookService:接口还是定义增删改查方法
package com.itheima.service;
import com.itheima.domain.Book;
import java.util.List;
/**
* @Description; Auther: Administrator
* Date:2022/9/2 21:35
*/
public interface BookService {
/*
增加
*/
public boolean save(Book book);
/*
修改
*/
public boolean update(Book book);
/*
删除
*/
public boolean delete(Integer id);
/*
根据id查询
*/
public Book getById(Integer id);
/*
查询全部
*/
public List<Book> getAll();
}
②:在impl实现层里面定义实现方法BookServiceImpl
package com.itheima.service.impl;
import com.itheima.dao.BookDao;
import com.itheima.domain.Book;
import com.itheima.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Description; Auther: Administrator
* Date:2022/9/2 21:35
*/
@Service
public class BookServiceImpl implements BookService {
//这里可能爆红,直接把错误信息改为警告信息就行
@Autowired
private BookDao bookDao;
@Override
public boolean save(Book book) {
bookDao.save(book);
return true;
}
@Override
public boolean update(Book book) {
bookDao.update(book);
return true;
}
@Override
public boolean delete(Integer id) {
bookDao.delete(id);
return true;
}
@Override
public Book getById(Integer id) {
return bookDao.getById(id);
}
@Override
public List<Book> getAll() {
return bookDao.getAll();
}
}
4.comtroller层(这几层的重点)
package com.itheima.controller;
import com.itheima.domain.Book;
import com.itheima.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @Description; Auther: Administrator
* Date:2022/9/2 21:35
*/
//里面包含@Controller @ResponseBody等几个接口,controller层用这个代替就行
@RestController
//rest风格实现的结构,首先@RequestMapping("/books"),然后查询(GET)增加(Post)修改(Put)删除(Delete)
@RequestMapping("/books")
public class BookController {
@Autowired
private BookService bookService;
@PostMapping
public boolean save(@RequestBody Book book){
return bookService.save(book);
}
@PutMapping
public boolean update(@RequestBody Book book){
return bookService.update(book);
}
@DeleteMapping("/{id}")
public boolean delete(@PathVariable Integer id){
return bookService.delete(id);
}
@GetMapping("/{id}")
public Book getById(@PathVariable Integer id){
return bookService.getById(id);
}
@GetMapping
public List<Book> getAll(){
return bookService.getAll();
}
}
5.报错:
[WARNING] No mapping for POST /books
原因:是因为访问网页时,本来应该被tomcat处理的请求被SpringMvc拦截请求处理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-11kYd8Y2-1664441127269)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220903101304273.png)]
解决方法,在Config文件下创建一个SpringMvcSupport.java
package com.itheima.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
/**
* @Description; Auther: Administrator
* Date:2022/9/3 10:16
*/
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/books/**").addResourceLocations("/books/");
}
}
6.表现层与前端数据创术协议的定义
就是创建一个类,属性值为三个,,然后通过增删改查返回给前端,
格式统一方便前后端交流数据(因为这是前后端分离,数据交互写在controller层建类)
1.定义Result类:提供构造方法,可以提供任意参数的构造方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VKfbAmBI-1664441127269)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220903182359592.png)]
2.定义Code类
定义正确欣喜和错误信息,1代表正确,0代表错误
package com.itheima.controller;
/**
* @Description; Auther: Administrator
* Date:2022/9/6 15:27
*/
public class Code {
public static final Integer SAVE_OK=20011;
public static final Integer DELETE_OK=20011;
public static final Integer UPDATE_OK=20011;
public static final Integer GET_OK=20011;
public static final Integer SAVE_ERR=20010;
public static final Integer DELETE_ERR=20010;
public static final Integer UPDATE_ERR=20010;
public static final Integer GET_ERR=20010;
}
3.controller层就要改变了,返回前端数据的不是数据了,而是一个Result类型的数据
package com.itheima.controller;
import com.itheima.domain.Book;
import com.itheima.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
private BookService bookService;
@PostMapping
public Result save(@RequestBody Book book) {
boolean flag = bookService.save(book);
return new Result(flag? Code.SAVE_OK:Code.SAVE_ERR,flag);
}
@PutMapping
public Result update(@RequestBody Book book) {
boolean flag = bookService.update(book);
return new Result(flag? Code.UPDATE_OK:Code.UPDATE_ERR,flag);
}
@DeleteMapping("/{id}")
public Result delete(@PathVariable Integer id) {
boolean flag = bookService.delete(id);
return new Result(flag? Code.DELETE_OK:Code.DELETE_ERR,flag);
}
@GetMapping("/{id}")
public Result getById(@PathVariable Integer id) {
Book book = bookService.getById(id);
Integer code = book != null ? Code.GET_OK:Code.GET_ERR;
String msg = book != null ? "":"数据查询失败,请重试";
return new Result(code,book,msg);
}
@GetMapping
public Result getAll() {
List<Book> bookList = bookService.getAll();
Integer code = bookList != null ? Code.GET_OK:Code.GET_ERR;
String msg = bookList != null ? "":"数据查询失败,请重试";
return new Result(code,bookList,msg);
}
}
7.异常处理:(重要)
1.有非常多的异常,所有模块可能都有(后台异常)
2.处理方法:(分类处理,表现层处理,通过AOP处理)其他地方出现异常向上抛,统一抛到controller层处理,通过异常处理器处理。
3.在controller层处理,在controller层创建
一个处理异常的类(异常处理器)
package com.itheima.controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* @Description; Auther: Administrator
* Date:2022/9/6 16:02
*/
//1.声明这个类为异常处理器
@RestControllerAdvice
public class ProjectExceptionAdvice {
//3.拦截异常,注意要让SpringMvcConfig配置类扫描到
@ExceptionHandler(Exception.class)
//2.写一个方法处理异常
public Result doException(Exception ex){
System.out.println("异常,你那里跑");
return new Result(666,null);
}
}
4.项目异常:
生活中所有的异常,用户乱输入,停电…
解决办法:①:在创建包
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bhddRW1O-1664441127269)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220907173248736.png)]
package com.itheima.exception;
/**
* @Description; Auther: Administrator
* Date:2022/9/6 16:12
*/
//这个类可继承也不可继承,最好就是继承,可以不用在每个出异常的类下,写一些关于异常话
public class SystemException extends RuntimeException{
//声明一个异常出现的属性判断是出了什么异常,提供getter,setter方法
private Integer code;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public SystemException(Integer code) {
this.code = code;
}
public SystemException(Integer code,String message) {
super(message);
this.code = code;
}
public SystemException(Integer code,String message, Throwable cause ) {
super(message, cause);
this.code = code;
}
public SystemException(Throwable cause, Integer code) {
super(cause);
this.code = code;
}
public SystemException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, Integer code) {
super(message, cause, enableSuppression, writableStackTrace);
this.code = code;
}
}
package com.itheima.exception;
/**
* @Description; Auther: Administrator
* Date:2022/9/7 17:22
*/
public class BusinessException extends RuntimeException {
//声明一个异常出现的属性判断是出了什么异常,提供getter,setter方法
private Integer code;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public BusinessException(Integer code) {
this.code = code;
}
public BusinessException(Integer code,String message) {
super(message);
this.code = code;
}
public BusinessException(Integer code,String message, Throwable cause ) {
super(message, cause);
this.code = code;
}
public BusinessException(Throwable cause, Integer code) {
super(cause);
this.code = code;
}
public BusinessException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, Integer code) {
super(message, cause, enableSuppression, writableStackTrace);
this.code = code;
}
}
然后就可以在程序的任何地方模拟异常,所有的异常都会包装为SystemException类的异常,然后就可以抛出到表现层了
//异常模拟
if (id==1){
throw new BusinessException(666,"你填写的信息有误");
}
//模拟异常
try {
int i = 1/0;
} catch (Exception e) {
throw new SystemException(666,"服务器链接超时,请重试");
}
ocntroller层处理
package com.itheima.controller;
import com.itheima.exception.BusinessException;
import com.itheima.exception.SystemException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* @Description; Auther: Administrator
* Date:2022/9/6 16:02
*/
//1.声明这个类为异常处理器
@RestControllerAdvice
public class ProjectExceptionAdvice {
//4.处理项目异常
@ExceptionHandler(SystemException.class)
public Result doSystemException(SystemException ex){
//.记录日志
//.发送消息给运维
//.发送邮件给开发人员
return new Result(ex.getCode(),null,ex.getMessage());
}
//5.处理项目异常
@ExceptionHandler(BusinessException.class)
public Result doBusinessException(BusinessException ex){
//5.记录日志
//6.发送消息给运维
//7.发送邮件给开发人员
return new Result(ex.getCode(),null,ex.getMessage());
}
//3.拦截异常,注意要让SpringMvcConfig配置类扫描到
@ExceptionHandler(Exception.class)
//2.写一个方法处理异常
public Result doException(Exception ex){
return new Result(Code.SYSTEM_UNKNOWTIMEOUT_ERR,null,"系统繁忙,请稍后再试");
}
}
8.整合页面:
直接访问时,会出现这种错误,是因为路径本来应该通过tomcat去访问,但是被SpringMvc的配置类给拿去了,return new String[]{“/”};然后就要创建一个SpringMvcSupport的配置类去获取这些页面
(记得去在SpringMvc的配置类去扫描加载这个配置类)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Py5UWmqt-1664441127270)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220907224548297.png)]
package com.itheima.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
/**
* @Description; Auther: Administrator
* Date:2022/9/7 22:49
*/
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
}
}
前端ajax请求
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PwgZaMfS-1664441127270)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220908214219071.png)]
5.拦截器(了解)
6.分模块开发与设计
1.分模块的意义,就是把功能分为多个模块,单独设计
比如前期的网上购票系统,加上后来的手机上的购票系统
订单,商品模块
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9vLDO4wZ-1664441127270)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220905203346929.png)]
2.分模块的实现:
1.把原先项目的pojo实体类拿出,放在下一个项目中。
2.然后通过pom.xml文件引入下一个文件的坐标。
3.安装下一个文件的坐标
3.springboot
1.作用:简化spring开发的环境搭建以及开发过程
有了springboot配置类啥的都不需要
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hSunSCTh-1664441127271)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220908222631724.png)]
最基本的目录:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2qIqWImJ-1664441127271)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220908223309128.png)]
2.比较重要的东西,这两个继承了许多东西,也叫做起步依赖,还有个引导类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AMnjLz0r-1664441127271)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220908224037812.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fe5zAquZ-1664441127271)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220908224159113.png)]
cSupport的配置类去获取这些页面
(记得去在SpringMvc的配置类去扫描加载这个配置类)
[外链图片转存中…(img-Py5UWmqt-1664441127270)]
package com.itheima.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
/**
* @Description; Auther: Administrator
* Date:2022/9/7 22:49
*/
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
}
}
前端ajax请求
[外链图片转存中…(img-PwgZaMfS-1664441127270)]
5.拦截器(了解)
6.分模块开发与设计
1.分模块的意义,就是把功能分为多个模块,单独设计
比如前期的网上购票系统,加上后来的手机上的购票系统
订单,商品模块
[外链图片转存中…(img-9vLDO4wZ-1664441127270)]
2.分模块的实现:
1.把原先项目的pojo实体类拿出,放在下一个项目中。
2.然后通过pom.xml文件引入下一个文件的坐标。
3.安装下一个文件的坐标
3.springboot
1.作用:简化spring开发的环境搭建以及开发过程
有了springboot配置类啥的都不需要
[外链图片转存中…(img-hSunSCTh-1664441127271)]
最基本的目录:
[外链图片转存中…(img-2qIqWImJ-1664441127271)]
2.比较重要的东西,这两个继承了许多东西,也叫做起步依赖,还有个引导类
[外链图片转存中…(img-AMnjLz0r-1664441127271)]
[外链图片转存中…(img-fe5zAquZ-1664441127271)]