整合mybatis
jdbc.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC
jdbc.username=root
jdbc.password=root
config包下的配置类
config.class
//使用此类以后相当于替换了配置文件,完全不使用配置文件的纯注解开发
@Configuration//相当于配置文件的外壳
@ComponentScan({"wwr"})
//可以配置多个扫描路径eg:
//@ComponentScan({"wwr.dao",“com.wwr”})
@EnableAspectJAutoProxy
//不支持*通配符,配置属性文件,其他地方使用时:@Value("${}")
@Import({JDBCConfig.class,MybatisConfig.class})
@PropertySource("classpath:jdbc.properties")
public class Config {
}
JDBCConfig.class
public class JDBCConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean("dataSource")//表示当前方法的返回值是一个bean
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(username);
ds.setPassword(password);
return ds;
}
}
这里没有写@Configuration,和@PropertySource(“classpath:jdbc.properties”)
是因为我在主config里面写了@Import({JDBCConfig.class,MybatisConfig.class})
MybatisConfig.java
相当于maybatis-config.xml文件
public class MybatisConfig {
/**
* 负责造sqlSession,给mapper搞出映射文件,相当于mybatisConfig.XML
* @param dataSource
* @return
*/
@Bean
public SqlSessionFactoryBean getSqlSessionFactory(DataSource dataSource){
SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
ssfb.setTypeAliasesPackage("wwr");
//起别名
ssfb.setDataSource(dataSource);
return ssfb;
}
/**
* 相当于mybatisconfig.xml中的最后一个标签
*
* <mappers>
* <package name="com.wwr.mapper"/>
* </mappers>
* @return
*/
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer msc = new MapperScannerConfigurer();
msc.setBasePackage("wwr");
//扫描映射包
return msc;
}
}
其他的dao,service和以前写的没区别,只是需要注意一点就是这个@Mapper和@Repository的使用,
贴一下我的目录,以防我下次又找不见我的文件
事务
要么全部执行要么全部回滚。
我们可以给spring给数据层或者业务层添加事务
方式:
NO1:
在你需要的接口上添加注解 @Transactional
咱这个注解一般写在业务层接口上而不是实现类上,目的是降低耦合
此注解不仅可以写在类上,也可以写在方法上,
No2:
/**
* 开启事务管理器
* @param dataSource
* @return
*/
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
No3:
在主配置类上添加@EnableTransactionManagement
//需要告诉spring我要开启事务
事务角色
事务管理员和事务协调员
spring开启的事务就是事务管理员
加入事务管理员的事务就是事务协调员
并不是所有的异常都在回滚,(比如,IOException)你需要通过事务配置异常,让他回滚
事务的传播行为配置
什么是事务传播行为?
事务协调员对事务管理员所携带事务的处理态度(加入还是不加入)
通过propagation进行配置
springmvc
Springmvc是一种基于java实现mvc模型的轻量级web框架
引入依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
配置文件
config.java
@Configuration
@ComponentScan(value = "wwr"
// excludeFilters = @ComponentScan.Filter(
// //过滤规则
// type= FilterType.ANNOTATION,//按照注解进行过滤
// classes = Controller.class//告诉他注解类型
// )
)
//初始化springMVC环境,设定springMVC加载对应的bean
//怎样避免spring和springmvc一起加载controller管理的bean呢?
/**
* 1.要么写两个配置类个配置个的
* 2.要么排除,
**/
@EnableWebMvc
//开启json
public class Config {
}
springservlet.java
public class SpringServlet extends AbstractDispatcherServletInitializer {
/**
* 把web容器交给Config
*
* @return
*/
@Override
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext acwac = new AnnotationConfigWebApplicationContext();
acwac.register(Config.class);//加载配置类
return acwac;
}
/**
* 所有请求交给Springmvc容器处理---我觉得就是tomcat
* @return
*/
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
@Override
protected WebApplicationContext createRootApplicationContext() {
return null;
}
}
上面这种方式还有另一种写法
public class SpringServlet2 extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{Config.class};
//加载spring配置环境
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringServlet.class};
//加载springmvc的配置环境
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
//设定请求路径
}
/**
* 解决乱码问题
* @return
*/
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
return new Filter[]{filter};
}
}
- 容器初始化过程
- 1.服务器启动,执行servletContainersInitConfig类,初始化web容器
- 2.执行createServletApplicationContext方法,创建了webApplicationContext对象
- 3.加载SpringMVCConfig----这里就是咱的Config
- 4.执行@ComponentScan加载对应的bean----就是拥有controller注解的bean
- 5.加载controller,每个@RequestMapping的名称对应的方法
- 6.执行getServletMappings方法,定义所有请求通过springmvc
- 单词请求执行:
- 1.发送localhost/save
- 2.web容器发现所有请求都经过SpringMVC,经请求交给springmvc处理
- 3.解析请求路径
- 4.有路径匹配对应的执行方法
- 5,。执行方法
- 6,检测到有@ResponseBody直接将方法的返回值作为相应的请求体返回给请求方
usercontroller.java
//@Controller
@RestController
//相当于@Controller和@ResponseBody的组合
//定义bean使之加入容器方便管理
@RequestMapping("/user")
//一般在类上定义模块请求路径
public class UserController {
//设置此方法的访问路径
@RequestMapping("/save")
//设置当前操作的返回值类型
@ResponseBody
public String save(@RequestParam("name") String username){
//@RequestParam("name")用来解决请求路径参数名称和形参名称不一致的问题
System.out.println("山鸟与鱼不同路");
return "{'userid':10}";
}
//REST风格:
//@RequestMapping(value = "save",method = RequestMethod.GET)
//url请求:http/localhost/save/lihua
//你的方法参数前需要加@PathVariable,表示从路径获取参数但是仅使用此注解是不够的,你还需要将参数的具体接收写到
//requestmapping里
@RequestMapping(value = "/select/{id}",method = RequestMethod.GET)
// @GetMapping是上面@RequestMapping(value = "/select/{id}",method = RequestMethod.GET)的快速写法
@ResponseBody
public String select(@PathVariable Integer id){
System.out.println(id);
return "{'userid':10}";
}
/**
* 当形参为实体类时,请求参数的参数名称要和实体属性一致时,会自动转换为对象,
* 请求为localhost/8080/login?username="李华"&age=15
* 如果对象中有引用类型的参数的话,请求参数需要这样写:class.name="",class.score=""
* 请求参数为数组:所有参数key都相同value可以不相同
* 请求参数为集合:需要在参数前面加一个@RequestParam,否则会报list<init>错误,这是没有构造函数的错误。
* 如果参数在请求体里面,需要使用@RequestBody
* @RequestParam和@RequestBody和@PathVariable的区别
* @RequestParam用于接收url地址传参,表单传参
* @RequestBody用于接收json数据-----更多地使用,把接受的参数封装成json传值
* @PathVariable用于接收路径参数,使用{参数名称}描述路径参数----用于参数比较少的参数时
* 请求参数的底层是按照,先创建引用类型的对象,然后将你的参数进行set之后传到后端,但是list是借口本身就没有构造方法、
* 所以需要@RequestParam告诉前面,直接传参就好不需要set内容,不需要创建对象
*
* 请求参数是日期的话需要进行格式化:@DateTimeFormat(patter="yyyy-MM-dd")
*/
@RequestMapping("/login")
public String login(User user){
System.out.println(user);
return "ok";
}
}
当形参为实体类时,请求参数的参数名称要和实体属性一致时,会自动转换为对象,
* 请求为localhost/8080/login?username=“李华”&age=15
* 如果对象中有引用类型的参数的话,请求参数需要这样写:class.name=“”,class.score=“”
* 请求参数为数组:所有参数key都相同value可以不相同
* 请求参数为集合:需要在参数前面加一个@RequestParam,否则会报list错误,这是没有构造函数的错误。
* 如果参数在请求体里面,需要使用@RequestBody
* @RequestParam和@RequestBody和@PathVariable的区别
* @RequestParam用于接收url地址传参,表单传参
* @RequestBody用于接收json数据-----更多地使用,把接受的参数封装成json传值
* @PathVariable用于接收路径参数,使用{参数名称}描述路径参数----用于参数比较少的参数时
* 请求参数的底层是按照,先创建引用类型的对象,然后将你的参数进行set之后传到后端,但是list是借口本身就没有构造方法、
* 所以需要@RequestParam告诉前面,直接传参就好不需要set内容,不需要创建对象
*
* 请求参数是日期的话需要进行格式化:@DateTimeFormat(patter=“yyyy-MM-dd”)
SpringMVC的执行流程
1.客户端向服务器端发送一次请求,这个请求会先到前置控制器(DispacherServlet,也叫中央控制器,负责调度)
2.DispacherServlet接收请求后会调用HandlerMapping处理器映射器,得到由那个Controller来处理,处理器映射器返回一个执行链
3.DispacherServlet调用HandlerAdapter处理器适配器,告诉适配器应该去执行那个Controller
4,HandlerAdapter适配器去执行Controller,然后controller返回一个modelandView对象给上级,知道返回给DispacherServlet。
5.DispacherServlet将modelandView交给ViewReslover视图解析器解析,返回真正的视图。
6.DispacherServlet将结果响应给客户端