# myssm **Repository Path**: xfanonymous/myssm ## Basic Information - **Project Name**: myssm - **Description**: SSM(Spring+SpringMVC+MyBatis)项目笔记,包括SpringFramework、SpringMVC、SpringBoot、MyBatis、MyBatisPlus。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-11-30 - **Last Updated**: 2024-04-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README [toc] # SSM 1. ssm-spring-part:Spring框架 2. ssm-mybatis-part: MyBatis框架 3. ssm-springmvc-part:SpringMVC框架 4. ssm-integration-part:Spring+SpringMVC+MyBatis框架整合 5. springboot-part:SpringBoot框架 6. mybatis-plus-part: MyBatis-Plus框架 # ssm-spring-part 1. ssm-spring-part 为父工程,修改 pom.xml 2. 创建子模块 spring-ioc-xml-01,修改 pom.xml 3. 新建 resources 配置文件 Spring Config ## spring-ioc-xml-01 1. ssm.spring.ioc_01 配置组件到IOC容器,XML配置文件, 无参构造函数、静态工厂方法、非静态工厂方法 2. ssm.spring.ioc_02 组件依赖注入(DI), 有参构造函数(单参数、多参数)、setter方法 3. ssm.spring.ioc_03 通过IOC容器获取IOC组件,读取配置文件,实例化组件 4. ssm.spring.ioc_04 周期方法、单例多例 5. ssm.spring.ioc_05 FactoryBean实现引用三方复杂类的实例化 ## spring-ioc-xml-practice-02 1. ssm.spring.jdbc JdbcTemplate的基本使用 2. spring.ioc.xml.* 三层架构搭建和实现 ## spring-ioc-annotation-03 1. ssm.spring.ioc_01 Bean注解标注、指定IoC扫描路径 2. ssm.spring.ioc_02 组件生命周期方法、组件作用域注解 3. ssm.spring.ioc_03 @Autowired+@Qualifier、@Resource 4. ssm.spring.ioc_04 @Value读取外部配置文件属性值 ## spring-ioc-annotation-05 1. 注解+XML 方式完成三层架构搭建和实现 ## spring-ioc-java-06 1. 完全注解开发 2. @Configuration 标注当前类是配置类,替代application.xml 3. @ComponentScan(value = {"",""}) 指定包扫描路径 4. @PropertySource("classpath:jdbc.properties") 指定外部配置文件 5. @Value(${}) 获取外部配置文件参数对属性赋值 6. @Bean 会将方法创建的组件保存到IOC容器,用于将第三方组件的实例化。 7. @Import 从另一个配置类加载 @Bean,简化了容器实例化导入。 ## spring-ioc-java-07 1. 全注解方式实现三层架构 ## spring-test-annotation-08 1. spring-test 搭建测试环境 2. @SpringJUnitConfig(value = {BeanConfig.class}) 指定配置类 3. 配置类指定扫描路径和外部配置文件,在测试方法可以直接使用IOC容器中的组件 ## spring-aop-annotation-09 1. 代理模式:静态代理、JDK动态代理实现 ## spring-aop-annotation-10 - AOP基本实现 1. 引入依赖:spring-aop、spring-aspects 2. 定义核心业务目标接口,定义核心方法 (Calculator) 3. 定义核心业务类,实现目标接口和方法,AOP只针对IOC容器中的组件,目标类要用 @Component 修饰 ( CalculatorPureImpl) 4. 定义切面实现AOP,定义增强方法,指定执行位置,指定插入方法 (LogAdvice) 1. 增强类本身要放到IOC容器,需要 @Component 修饰 2. 增强类要声明为切面使增强方法生效,需要 @Aspect 修饰 3. 要需要开启AspectJ注解,需要在在配置类中用 @EnableAspectJAutoProxy 修饰 4. 增强方法注解,指定触发时机 @Before @AfterReturning @AfterThrowing @After @Around 5. 切点表达式,指定插入位置 @Before(value = "execution(* spring.aop.service.impl.*.*(..))") 5. 定义配置类,替代配置文件 (JavaConfig) 1. 定义为配置类,用 @Configuration 修饰 2. 指定扫描路径,用 @ComponentScan("") 修饰,配置类、AOP切面所在路径都要扫 3. 开启AspectJ注解,用 @EnableAspectJAutoProxy 修饰 6. 定义测试类 (SpringAopTest) 1. 基于Spring测试框架,指定配置类 @SpringJUnitConfig(value = JavaConfig.class),即可在测试类中使用IOC容器及组件 2. 建议使用接口接从IOC容器中取出的组件,AOP在IOC容器中保存的是代理对象 3. AOP功能底层通过代理实现,目标类CalculatorPureImpl实现了接口,走JDK代理 4. JDK代理通过实现目标类的接口,创建代理对象,所以要使用接口接值 7. JoinPoint 获取插入方法信息 (MyAdvice) 8. 切点表达式复用 (MyPointCut、MyAdvice) 9. 环绕通知、切面优先级 (TxAroundAdvice、TxAdvice) 10. CGLIB动态代理验证 (CglibCalculatorPureImpl-CGLIB、CalculatorPureImpl-JDK) ## spring-aop-xml-11 - Spring AOP基于XML方式实现(了解) ## spring-tx-annotation-12 1. Spring声明式事务对应依赖 1. spring-tx: 包含声明式事务实现的基本规范(事务管理器规范接口和事务增强等等) 2. spring-jdbc: 包含DataSource方式事务管理器实现类DataSourceTransactionManager 2. 配置类 (JavaConfig) 1. @EnableTransactionManagement 开启事务注解支持 2. 将事务实现类注入IOC容器 DataSourceTransactionManager 类用于JDBC方式连接数据库 3. 配置数据库连接池,事务操作类需要连接池执行数据库操作 3. 业务类 (StudentService) 1. @Transactional() 添加事务,一般统一添加到类上,类下的所有方法都有事务,再对方法单独添加注解指定属性,方法上的注解会覆盖类注解的效果。 2. 只读模式 @Transactional(readOnly = true) 3. 超时时间 @Transactional(timeout = 3) 4. 指定触发回滚的异常 @Transactional(rollbackFor = Exception.class) 5. 设置事务隔离级别 @Transactional(isolation = Isolation.READ_COMMITTED) 6. 设置事务传播行为 @Transactional(propagation = Propagation.REQUIRED) # ssm-mybatis-part - MyBatis 持久层框架 ## mybatis-base-quick-01 - MyBatis 框架基本使用 1. 依赖导入 1. mybatis、mysql-connector-java、junit-jupiter-api 2. 实体类 3. Mapper接口 1. 接口方法不能重载,XML映射文件根据方法名匹配,同名方法无法识别 4. XML映射文件 1. mapper namespace对应Mapper接口的全限定符 2. SQL语句id对应Mapper接口方法名 5. MyBatis配置文件 6. 功能测试 1. 读取外部配置文件(mybatis-config.xml) 2. 创建sqlSessionFactory 3. 根据sqlSessionFactory创建sqlSession (每次业务创建一个,用完就释放) 4. 获取接口的代理对象 (jdk代理技术)调用代理对象的方法,就会查找mapper接口的方法 5. sqlSession内部根据根据传入的接口自动生成代理对象,调用ibatis方法执行SQL 6. 提交事务(非DQL)和释放资源 7. ibatis方式(StudentMapper.xml) 1. 不要求写接口 2. 直接创建mapper.xml文件内部编写sql语句 3. namespace 没有任何要求,随意声明一个字符串即可 4. 内部通过crud标签声明sql语句即可 5. 无约束导致调用XML映射文件执行SQL语句时无法快速定位 6. 缺点:sql语句标签对应的字符串标识,容易出现错误、参数需要进行整合,只能传递一个、返回值不会自动报错 ## mybatis-base-param-input-02 - SQL语句输入参数 1. 动态参数获取 1. `#{key}` 占位符赋值,推荐,防止注入问题。用于接收动态列名、容器名、关键字等 2. `${key}` 字符串拼接,只用于接收动态值 3. 接收动态列名 ${columnName} = 动态值 #{columnValue} 2. 不同类型参数获取 1. 场景1:接口方法传入单个简单类型参数,`#{key}` key 随便写,一般情况下推荐使用参数名 2. 场景2:接口方法传入实体对象参数,`#{key}` 使用类的属性名 3. 场景3:接口方法传入多个简单类型数据参数,推荐在Mapper接口通过 @Param("value") value 注解指定形参接收 4. 场景4:接口方法传入Map类型参数,`#{key}` 使用map的key名接收 ## mybatis-base-result-output-03 - SQL语句输出 1. 返回单个简单类型,指定resultType 1. resultType 类的全限定符号 2. resultType 别名 1. mybatis提供了72种默认的别名,包括常用的Java数据类型:基本数据类型、包装数据类型、集合容器类型 2. mybatis-config.xml 给类、包下所有类单独定义别名,别名是类的首字母小写 2. 返回单个自定义类类型 1. resultType 返回自定义类 2. 默认要求列名和属性名一致 3. mybatis-config.xml 设置支持驼峰式自动映射 3. 返回map 1. 当没有实体类可以使用接值时,可以使用map接收数据 2. key -> 查询的列,value -> 查询的值 4. 返回集合类型 1. resultType不需要指定集合类型,只需要指定集合内的类型 ### 事务提交 1. 事务提交:获取SqlSession对象时,可以指定是否开启事务自动提交 1. sqlSessionFactory.openSession(); 自动开启事务,不会自动提交,需要手动调用 sqlSession.commit(); 2. sqlSessionFactory.openSession(true); 自动开启事务,自动提交事务,不需要sqlSession.commit(); ### 主键回显 1. 自增长主键回显,通过属性指定 1. `` 2. useGeneratedKeys="true" 开启获取自增主键值 3. keyColumn="emp_id" 数据库主键列的值 4. keyProperty="empId" 接收主键列值的类属性 2. 非自增主键回显,自定义主键值 1. 调动时通过 `UUID.randomUUID().toString().replaceAll("-", "");` 生成唯一数,去除中划线 2. XML文件定义,执行插入语句之前通过属性生成主键 1. order="before|after" 在SQL语句执行前|后生成主键 2. resultType = 返回值类型 3. keyProperty = 查询结果赋值给哪个属性 ### 数据库列名和类属性名不一致 1. SQL语句中起别名:`select t_id tId , t_name tName from teacher where t_id = #{tId}` 2. 开启驼峰式自动映射设置:`` 3. resultMap 自定义映射 1. resultType 按照规则自动映射属性和列名,只能映射一层结构。多表查询结果无法映射。 2. resultMap 标签,自定义映射关系,可以深层次可以单层次 3. resultMap 标签属性: id 标识,type 返回值类型(集合写集合内的类型) 4. resultMap 标签内容: id 主键映射关系,result 普通列的映射关系 ## mybatis-base-crud-04 1. 单表 CRUD 练习,XML映射文件。 2. lombok 插件使用 3. Junit 测试工具使用,测试方法上添加注解,@BeforeEach 执行测试方法之前先执行、@AfterEach 执行测试方法后再执行 ## mybatis-high-multi-table-05 - 多表查询 1. 多表查询实体类设计原则 1. 只有多表查询真实需求时,才需要设计和修改实体类,否则实体类默认只提供基本属性和方法 2. 无论多少张表联查,实体类设计都是两两考虑 3. 查询映射时,只关注本次查询相关的属性 2. 多表查询关系 1. 当前类对一关系,当前类定义中将对方对象类型作为属性 1. 一个订单(Order)对应一个客户信息(Customer) 2. 将Customer作为属性添加到Order中 3. Mapper接口方法查询订单信息和对应的客户信息,返回的订单对象中包含客户对象 4. XML映射文件,使用resultType只能映射订单号等属性,无法将SQL语句查询的客户信息映射到客户对象 5. XML映射文件,使用resultMap自定义复杂关系映射 1. `` 主键 2. `` 基本属性 3. `` 对象属性 1. property 对象属性名 2. javaType 对象类型 2. 当前类对多关系,当前类定义中将对方对象类型集合作为属性 1. 一个客户(Customer)对应多个订单信息(Order) 2. 将Order集合作为属性添加到Customer 3. Mapper接口方法查询客户和对应的订单信息,返回的客户对象中包含订单集合 4. XML映射文件,使用resultMap自定义复杂关系映射 1. `` 主键 2. `` 基本属性 3. `` 集合类型属性 1. property 对象属性名 2. ofType 集合内对象类型 4. Order中包含的上次Customer属性是其他查询操作引入,无需赋值 3. 优化多表查询 1. MyBatis配置,开启驼峰命名自动映射 `` 2. resultMap 默认情况下会自动完成单层映射(基本属性),要求列名和属性名相同、或开启驼峰式映射,只需要写``,无需写`` 3. 嵌套了对象或集合类型的属性``不会自动映射, 需要手动写`` 4. MyBatis配置,开启复杂嵌套属性的``标签自动映射 `` 5. 开启自动映射后,单层属性、嵌套属性都只需要写``,无需写`` ## mybatis-high-dynsql-06 - 动态SQL语句查询 1. if 1. 根据test属性判断条件是否满足,true拼接标签内的sql语句,false不拼接 2. 防止误识别比较符,推荐使用 `>` 替换 `>`,`<` 替换 `<` 2. where 1. 当标签内有任何一个if满足,自动对SQL语句添加 where 关键字 2. 当标签内if都不满足,不添加 where 关键字 3. 自动去掉SQL语句多余的 and 和 or 关键字 3. sql、include 1. ``声明SQL语句片段 2. `` 引用SQL语句片段 4. set 1. 自动去掉SQL语句中多余的逗号`,` 2. 自动在SQL语句中添加set关键字 3. 要保证set标签中,至少有一个if条件满足 5. trim(了解),可以通过属性实现 where 和 set 标签的功能 6. choose、when、otherwise 1. 在多个分支条件中,仅执行一个。 2. 从上到下依次执行条件判断 3. 遇到的第一个满足条件的分支会被采纳 4. 被采纳分支后面的分支都将不被考虑 5. 如果所有的when分支都不满足,那么就执行otherwise分支 7. foreach 1. Mapper接口的集合参数要添加 @Param("name") 修饰指定映射的参数名 2. collection 要遍历的集合名,用@Param指定的参数名,或直接使用 "list" 3. open 遍历之前要追加的字符串 4. close 遍历结束需要添加的字符串 5. separator 每次遍历的分割符号 6. item 指定遍历项名 7. 标签内部使用`#{"item 指定的遍历项名"}` 8. 如果一个标签涉及多个语句,需要设置数据库允许指定多语句,在url拼接 ?allowMultiQueries=true 9. `` ## mybatis-other-extend-07 ### Mapper包路径注册 - mybatis-config.xml 核心配置文件Mapper注册 1. Mapper注册 1. 指定XML映射文件的位置 2. `` 标签 1. ``配置一个具体的Mapper映射文件 2. resource 属性指定XML映射文件位置 3. Maven工程,resources目录下的内容会直接放入类路径,可以填写以resources为基准的相对路径 4. `` 3. `` 指定映射文件所在包路径 1. 要求Mapper接口文件和XML映射文件的命名必须相同 2. 要求Mapper接口文件和XML映射文件的包路径必须相同,保证打包后的位置一致 3. `` ### PageHelper分页插件 1. SQL语句 limit x, y ; x = (pageNo - 1) * pageSize , y = pageSize 2. PageHelper分页插件 1. 使用插件会自动在SQL语句后拼接 limit x,y 2. SQL语句后不能写 ; 3. PageHelper插件使用 1. 依赖 ```xml com.github.pagehelper pagehelper 5.1.11 ``` 2. Mybatis配置插件,拦截SQL语句 ```xml ``` 3. XML映射文件编写SQL,不添加 limit x,y; 4. 调用Mapper接口方法前,先设置分页数据 (当前是第几页,每页显示多少个) 5. `PageHelper.startPage(2,2);` 6. 调用Mapper接口方法后,将查询结果封装到一个PageInfo的分页实体类 7. 通过PageInfo获取分页的数据信息 ### 逆向工程和MyBatisX插件 - MyBatis 是半自动ORM(Object-Relational Mapping,对象-关系映射)框架,提供CRUD方法,需要编写SQL语句 - 逆向工程:半自动ORM框架自动生成单表CRUD,向全自动迈进 - 使用 MyBatisPlus 时,利用 MyBatisX 插件,可以在Mapper接口定义操作方法后,自动生成SQL语句 # ssm-springmvc-part 1. 父工程 pom.xml 打包方式:pom 2. 父工程 pom.xml 引入依赖:Web项目需要 servlet,springIOC 需要 spring-context,mvc需要 spring-mvc 3. 父工程 pom.xml 对应依赖:jakarta.jakartaee-web-api、spring-context、spring-webmvc ## springmvc-base-quick-01 - SpringMVC基本流程实现 1. 表述层 (HelloController) 1. 定义Handler方法,响应前端请求并相应。Handler,即Controller中的方法。 2. @Controller,标识为Controller组件,组件扫描时将此类注入IOC容器 3. @RequestMapping("") 接收前端请求,注册Handler方法到 HandlerMapping 4. @ResponseBody 表示响应直接返回字符串,不需要视图解析器 2. 配置类 (MvcConfig) 1. 将Controller(Handler)、 HandlerMapping、HandlerAdapter 注册到IOC容器。 2. @Configuration 配置类注册到IOC容器 3. @ComponentScan("") 类路径扫描,将Controller类注册到IOC容器 4. @Bean 方法返回的对象注册到IOC容器,完成 HandlerMapping、HandlerAdapter 注册 3. SpringMVC初始化配置类 (SpringMvcInit) 1. 通过实现固定接口,SpringMVC会自动完成IOC容器创建,AbstractAnnotationConfigDispatcherServletInitializer 2. 会自动被Web项目加载,完成IOC容器初始化,配置DispatchServlet地址 3. 方法 getServletConfigClasses() 中返回配置文件 4. 方法 getServletMappings() 中返回SpringMVC的Servlet的访问地址或拦截路径,"/"表示拦截所有请求 4. Tomcat配置 1. Tomcat版本需要为10+,才支持jakarta.jakartaee-web-api 2. Edit Configuration,添加Tomcat,Fix,添加 war exploded artifact 3. 配置根路径为 /,浏览器访问 http://localhost:8080/springmvc/hello ## springmvc-base-input-02 - 获取前端参数 1. URL拦截路径 @RequestMapping() (UserController) 1. @RequestMapping() 修饰方法,用于将 Handler 注册到 HandlerMapping 2. @RequestMapping("路径不强制要求使用/开头"), @WebServlet("必须使用 /开头") 3. @RequestMapping()支持拦截一个或多个精准地址, @RequestMapping("/user/login“),@RequestMapping({"login", "logout"}) 4. 支持路径模糊匹配,`*` 表示匹配任意一层字符串,`**` 表示任意层任意字符串 5. @RequestMapping 修饰类,表示类中所有方法的公共访问路径,最终访问路径=类地址 + 方法地址。 6. 如果方法上的 @RequestMapping 不跟路径,则默认为类注解标识的公共访问路径。但方法只有加 @RequestMapping 注解,才能拦截访问。 7. @RequestMapping() 限制客户端访问方式 get、post、put、delete,默认情况下只要访问地址正确,任何请求方式都可以访问 8. 通过 `method = {RequestMethod.GET,RequestMethod.POST}` 指定请求方式,不符合的请求方式会出现405异常 9. 进阶注解 @GetMapping、@PostMapping、@PupMapping、@DeleteMapping 等效于 @RequestMapping(xxx,method=xxx) 2. 获取URL的param参数 @RequestParam() (ParamController) 1. 直接接值,在Handler的形参列表,直接填写URL中对应的参数名,要求名称相同,int 类型参数必须传值 2. 注解 @RequestParam 用于方法的形参列表中,指定URL请求参数名、要求参数是否必须传递、不必须传参赋默认值 1. value 指定URL中的参数名,可以与方法的形参名不一致 @RequestParam(value="account") String userid,如果一致可以省略 2. required 指定URL中的参数是否必须,默认为 true,不传报错400。必须和 defaultValue 一起使用 3. defaultValue 当URL中的参数为非必须时,设置默认值。@RequestParam(required=false, defaultValue="18") int age 3. 集合接值 1. URL中存在相同的参数名,但对应多个不同值时,方法的形参使用集合进行接值 2. 形参为集合时,必须使用 @RequestParam 修饰,否则会直接将URL中的一个参数赋值给集合形参,导致类型异常报错 4. 实体类接值 1. 实体类中的属性名必须和URL中的参数名一致 2. 实体类中的属性必须有get、set方法,可以引入 lombok 依赖,通过 @Data 注解修饰类,自动设置 3. 实体类中可以对属性赋默认值,不强制要求URL中的参数必须传值 3. 获取URL的路径参数 (PathController) 1. 场景:URL路径参数直接通过 / 拼接到路径中,没有使用 ?key=value 形式的param传值 2. 需要在注解中设置动态路径 @RequestMapping("{account}/{password}") 3. 方法中设置形参 @PathVariable(value="account"),属性和 @RequestParam() 一致 4. 只有添加 @PathVariable 才会从路径中取值,否则默认从 param中取值 4. 获取POST请求体中JSON格式参数 (JsonController) 1. 接收POST请求体中的JSON数据 2. 在Postman中测试,发送POST请求,请求体选择raw json格式 3. 方法形参使用 实体类 接值,用 @RequestBody 修饰形参,接收JSON格式请求体 4. 问题:Java原生的API,只支持路径参数和param参数,不支持JSON格式,会报错 415 不支持数据类型 5. 原因:JSON 是 JavaScript Object Notation 前端数据交换格式 6. 解决:导入jackson-databind依赖,在配置类中添加注解@EnableWebMVC,添加JSON格式解析能力 7. @EnableWebMvc 会自动添加 handlerMapping、handlerAdapter、JSON解析器,无需在配置类中再手动编写@Bean 5. 获取前端传递的Cookie值 (CookieController) 1. cookie 是kv格式,通过 HttpServletResponse 添加后返回给客户端 2. @CookieValue 修饰形参,指定获取的cookie的key 6. 获取前端请求头 1. @RequestHeader("Host") 接收请求头参数 7. 获取原生API对象 (ApiController) 1. 原生API可以直接调用 2. 可以直接全局声明ServletContext对象,用@Autowired 直接从ioc容器获取对应类型实体对象(组件) 并自动装配 3. 可以在形参中直接调用 HttpServletResponse、HttpServletRequest、HttpSession 8. 获取共享域对象 (ShareController) 1. 共享域,用于不同Servlet间传递数据 2. request 用于一次请求的多个方法间共享数据 3. session 用于一次会话,一个浏览器的多次请求间共享数据 4. servletContext 用于整个项目中共享数据,是最大的共享域。 ## springmvc-base-output-03 1. 页面跳转控制 1. 视图解析器 1. 在webapp/WEB-INF文件夹下创建jsp文件,WEB-INF目录下的文件外部无法直接访问 2. jsp文件中动态获取 request 共享域中的数据进行展示 3. 定义配置文件 MvcConfig,实现 WebMvcConfigurer 接口方法 configureViewResolvers(),在方法中指定匹配视图文件的前后缀路径,实现视图解析能力 4. 定义表示层 JsonController,Handler 方法根据指定路径的前后缀匹配视图JSP文件 5. 方法的返回值是字符串类型,返回值为对应视图文件的名称,前后缀路径信息在MvcConfig中已经指定 6. 方法不能添加@ResponseBody,否则会直接返回给字符串给浏览器,不找视图,不走视图解析器 7. 方法添加前端路径映射 @GetMapping("") 8. 在 request 共享域中添加数据,用于jsp文件动态获取 2. 转发(JspController) 1. 方法返回值类型是字符串,返回新的访问路径 2. 返回值通过 forward:/转发地址 前缀表示进行转发,否则默认返回的是视图文件 3. 不能添加@ResponseBody 4. 转发只能是项目下的资源,返回的转发路径可以忽略Tomcat部署配置的Application Context(/springmvc),直接返回 /jsp/index 3. 重定向 1. 方法返回值类型是字符串,返回新的访问路径 2. 返回值通过 redirect/重定向的地址 前缀表示进行重定向 3. 不能添加@ResponseBody 4. 重定向资源可以是项目外的转发路径,属于二次请求 5. 如果不使用SpringMVC语法格式 redirect/重定向地址,项目外的返回全路径,项目下的不能忽略Application Context(/springmvc)返回根路径 /springmvc/jsp/index 6. 如果使用 SpringMVC语法格式 redirect/重定向地址,项目下的可以忽略Application Context(/springmvc),直接返回 /jsp/index 2. 返回JSON数据 1. 前后端分离模式,Handler接收前端JSON数据 @RequestBody,返回JSON数据 @ResponseBody 2. Handler方法接收前端请求,注解 @Controller @RequestMapping() @GetMapping() 3. @ResponseBody 直接将方法结果数据放入响应体返回,不会走视图解析器,转发和重定向都不生效 4. 方法返回的类对象,会由HandlerAdapter自动转为Json后返回 5. 对象转为JSON格式 {"name":"two dogs!","age":3},集合转为JSON格式 [{"name":"two dogs!","age":3}] 6. @RestController = @RequestBody + @Controller 3. 返回静态资源 1. 在webapp下添加静态资源,不能放到WEB-INF下,否则外部无法直接访问 2. 直接在浏览器输入静态资源路径同样无法直接打开图片,因为 servlet 只寻找匹配的 HandlerMapping 3. 静态资源查找,在配置文件 MvcConfig 实现 WebMvcConfigurer 接口的 configureDefaultServletHandling 方法实现 4. 开启后 configurer.enable(); 可以通过 /images/mi.png 直接访问图片 5. 原理:DispatchServlet 会从 HandlerMapping(保存Handler和路径)寻找匹配的 Handler 6. 如果没有对应的 Handler,会转发给方法创建的 DefaultServletHandler 中匹配静态资源 ## springmvc-base-restful-04 - RESTFul 设计实战 1. 每个资源都应该有一个唯一的标识符,URI(Uniform Resource Identifiers,统一资源标识符)URL(Uniform Resource Locator,统一资源定位符)。 2. 每个 URI(Uniform Resource Identifiers,统一资源标识符)用名词代表资源。 3. 客户端使用 `GET、POST、PUT、DELETE` 请求方式对服务端资源进行操作:GET 获取资源,POST 保存资源,PUT 更新资源,DELETE 删除资源。 4. GET、DELETE:没有请求体,单一资源的查询使用 / 路径传参,多条件模糊查询使用 ?param 传参。 5. POST、PUT :有请求体,使用JSON请求体传参。 6. @RestController = @Controller + @ResponseBody 7. @RequestParam: 接收 ?param 传参,指定是否必须和默认值 8. @RequestBody: 接收 JSON 数据,将 JSON 格式转为类对象 9. @PathVariable: 接收 / 路径传参,默认必须传参 10. @GetMapping、@PostMapping、@PutMapping、@DeleteMapping ## springmvc-high-other-05 1. 声明式异常处理 (UserController、GlobalExceptionHandler) 1. @ControllerAdvice 拦截全局异常,交由类中的Handler处理,可以返回逻辑视图,转发和重定向 2. @RestControllerAdvice = @ResponseBody + @ControllerAdvice 直接返回json字符串 3. @ExceptionHandler 指定可以处理异常的Handler,精准匹配或匹配异常的父类 2. 拦截器 (MyInterceptor) 1. 实现接口 HandlerInterceptor 2. 方法 preHandle() 执行Handler之前调用的方法,用于设置编码格式、登录保护、权限处理等。返回 true 放行,false 拦截。 3. 方法 postHandle() Handler执行完毕后调用的方法,用于对结果处理、敏感词汇检查。 4. 方法 afterCompletion() 整体处理完毕后执行,渲染视图之后执行,一定执行 5. 拦截器注册,配置类 MvcConfig 实现 SpringMVC 标准化配置接口 WebMvcConfigurer 6. 重写方法 addInterceptors,添加拦截器类 MyInterceptor,默认拦截所有请求 7. 指定拦截的路径,通过方法 .addPathPatterns("") 实现 8. 在指定拦截路径中,排除特定路径,通过方法 .addPathPatterns("").excludePathPatterns("") 实现 9. 拦截器执行顺序:先调用的优先级高,包住后调用的 10. 拦截器的执行流程在 DispatcherServlet 源码中 3. 参数校验 1. 引入参数校验依赖,jakarta、hibernate 2. 创建实体类,根据需求添加参数校验注解 1. 字符串不为空 @NotBlank,集合不为空 @NotEmpty,包装不为空 @NotNull 2. 长度限制 @Length(min) 3. 最小值 @Min() 4. 邮箱 @Email 5. 过去时间 @Past 3. Controller定义Handler方法 1. 接收有参数校验注解标识的实体类,使用 @Validated 注解使参数校验生效 2. 如果传参是 json 格式,形参添加 @RequestBody 注解 3. 不符合校验规则,默认直接向前端抛出异常 4. 通过 'BindingResult result' 接收错误信息,可以自定义报错时的返回结果 5. handler(@Validated 实体类 对象, BindingResult result) BindingResult 必须紧挨校验对象 6. 捕获异常可以通过 Map 返回 # ssm-integration-part ## ssm-integration-01 - SSM整合步骤 ### 依赖 pom.xml - 父工程依赖,ssm整合所需所有依赖项 ### 配置文件 resources 1. 日志配置 logback.xml,固定写法,用于mybaits、程序日志 2. JDBC配置 jdbc.properties,固定写法,连接数据库 3. MyBatis核心配置文件 mybatis-config.xml 不推荐,推荐使用注解方式 ### 控制层配置类 1. 控制层的配置类(WebMvcJavaConfig),用于SpringMVC组件配置 1. @Configuration 声明配置类 2. @EnableWebMvc 添加 handlerMapping、handlerAdapter,添加 JSON解析器 3. @ComponentScan("") 类路径扫描,将 Controller、ExceptionHandler添加到IOC容器 4. 实现SpringMVC组件声明标准化接口 `WebMvcConfigurer` 简化SpringMVC组件配置 5. 重写方法 `configureDefaultServletHandling` 用于生成默认 Handler 做静态资源响应 6. 重写方法 `configureViewResolvers` 配置视图解析处理器,用于混合开发模式匹配前端页面 7. 重写方法 `addInterceptors` 添加拦截路径 ### 业务层配置类 1. 业务层配置类(ServiceJavaConfig),用于service、aop、tx 1. @Configuration 声明配置类 2. @ComponentScan("") 类路径扫描,将 Service 添加到IOC容器 3. @EnableAspectJAutoProxy 开启AOP注解支持(@Before @After @AfterReturning @AfterThrowing @Around @Aspect @Order) 4. @EnableTransactionManagement 开启事务注解支持(@Transactional) 5. 事务管理器 `DataSourceTransactionManager` 整合了Mybatis方式事务管理器实现 6. @Bean 将事务管理器注入IOC容器 ### Mybatis整合 1. MyBatis核心操作步骤 1. 创建 MyBatis 配置文件 mybatis-config.xml 2. InputStream 读取外部配置文件 3. 根据配置文件创建 SqlSessionFactory 4. 通过 SqlSessionFactory 创建 SqlSession 5. 通过 SqlSession 获取 Mapper 接口的代理对象 6. 根据代理对象执行数据库操作CRUD 2. 整合方式一:保留 MyBatis 配置文件方式,不推荐 1. 创建 MyBatis 配置文件 mybatis-config.xml 2. 创建 MyBatis 配置类 MapperJavaConfig 1. @Configuration 声明配置类 2. @PropertySource(“classpath:jdbc.properties”) 读取外部配置文件 3. @Value("${}") 读取配置文件字段信息 4. @Bean 将数据库连接池DataSource放入IOC容器 5. @Bean 将MyBatis自带的SqlSessionFactoryBean注入IOC容器,用于创建SqlSessionFactory 6. @Bean 将设置SqlSessionFactory配置信息 7. @Bean 将Mapper代理对象MapperScannerConfigurer注入IOC容器,通过扫描指定路径下的Mapper接口,生成代理对象。 8. 问题:不能将 DataSource 和 MyBatis组件 SqlSessionFactoryBean、MapperScannerConfigurer 配置文件写到一起 9. 原因:MyBatis组件加载优先于 @Value("${}") 读取配置文件字段信息,导致@Value注解不生效 10. 解决:分开配置,写到不同的类,将 DataSource 的配置单独写到 DataSourceJavaConfig 配置类 3. 单独创建数据库连接池的配置类 DataSourceJavaConfig 1. @Configuration 声明配置类 2. @PropertySource(“classpath:jdbc.properties”) 读取外部配置文件 3. @Value("${}") 读取配置文件字段信息 4. @Bean 将数据库连接池DataSource放入IOC容器 3. 整合方式二:MyBatis 完全配置类方式 1. 创建MyBatis完全配置类 MapperJavaConfigNew,除配置文件导入部分代码,其他保留 2. 保留数据库连接池的配置类 DataSourceJavaConfig 3. 保留MyBatis组件 SqlSessionFactoryBean 创建 SqlSessionFactoryBean 4. 保留MyBatis组件 MapperScannerConfigurer 创建 Mapper 代理对象 5. 通过 SqlSessionFactoryBean 的方法指定MyBatis配置,替换 mybatis-config.xml文件功能 ### Spring容器初始化配置类 1. Spring容器初始化配置类(SpringIoCInit) 继承 AbstractAnnotationConfigDispatcherServletInitializer 2. 重写方法 getRootConfigClasses() 返回 rootIoC 容器的配置类(服务层、持久层) 3. 重写方法 getServletConfigClasses() 返回 webIoC 容器的配置类(表述层) 4. 重写方法 getServletMappings() 返回 DispatcherServlet 的拦截路径 ### SSM业务功能测试 1. 创建实体类(Employee) 2. 创建Mapper接口(EmployeeMapper),定义CRUD方法。(由MapperJavaConfigNew创建了Mapper代理对象) 3. 创建Mapper xml文件(EmployeeMapper.xml) 编写SQL语句。(通过namespace和id与Mapper接口关联) 4. 创建业务接口(EmployeeService),定义业务执行方法,用于 Controller 调用。 5. 创建业务实现类(EmployeeServiceImpl) 实现业务层接口,调用 DAO 层执行操作。(由ServiceJavaConfig指定类路径扫描到IOC容器) 1. @Service 将业务层实现类注入IOC容器 2. @Autowired 匹配Mapper接口,Mapper接口由持久层配置类 MapperJavaConfigNew 注册到IOC容器 3. 实现业务接口方法,调用 Mapper 接口方法执行数据库操作 6. 创建表述层(EmployeeController)。(由WebMvcJavaConfig指定类路径扫描到IOC容器) 1. @RestController = @ResponseBody + @Controller 2. @RequestMapping("") 定义拦截路径 3. @GetMapping("") 指定拦截路径和访问方式 4. @Autowired 调用业务层接口 5. 执行业务层方法 ## ssm-integration-todolist-02 - 前后端分离项目实战 - 后端项目管理工具 Maven,后端部署工具 Tomcat - 前端包管理工具 npm,前端部署工具 Node ### 框架准备 1. 配置文件:日志配置 logback.xml,JDBC配置 jdbc.properties 2. 配置类:控制层配置类 WebMvcJavaConfig,业务层配置类 ServiceJavaConfig,持久层配置类 MapperJavaConfigNew,数据库连接池 DataSourceJavaConfig 3. Spring容器配置类: SpringIoCInit 4. 实体类:Schedule 5. 结果模板类:响应结果类 R,分页查询结果类 PageBean ### 功能实现 1. 控制层(ScheduleController) 1. @RestController = @ResponseBody + @Controller 返回JSON格式 2. @RequestMapping("") 类公共访问路径 3. @GetMapping("") 根据需求描述,指定访问路径和请求方式。路径参数接值 `/{}`,实现分页查询。 4. @PathVariable 接收路径参数 5. @Autowired 从IOC容器调用Service层,要用接口接值,用实现类无法接值 6. 调用Service层接口方法,返回结果模板 R 7. @Slf4j 使用日志接口,logback.xml 是日志实现,会根据xml配置的日志格式进行输出。日志 {} 为占位符。 8. @Validated 启动参数校验 9. @RequestBody 接收消息体的JSON格式数据 10. @PutMapping 指定请求方式,做修改操作 11. @CrossOrigin 防止浏览器做同源策略的访问限制,允许前后端联调时访问后端 2. 业务层(接口 ScheduleService、实现类 ScheduleServiceImpl) 1. 业务层接口定义执行方法 2. 业务层实现类 1. @Service 类路径扫描标识,添加到IOC容器 2. 实现业务层接口方法 3. 分页插件 PageHelper 进行分页查询,`PageHelper.startPage(currentPage, pageSize);` 会自动在SQL语句执行limit操作。 4. @Autowired 调用Mapper接口执行查询操作,方法实现查询,由分页插件自动做分页处理 5. 分页插件 PageHelper 用 PageInfo 接收查询结果 6. 装配结果模板类 PageBean、R 3. 持久层(Mapper接口ScheduleMapper、xml文件ScheduleMapper.xml) 1. Mapper接口定义数据库操作方法 2. xml文件实心具体SQL语句,不要加分号`;`,由分页插件自动执行 limit 操作 ### 前后端联调 1. 同源策略:比较访问方和被访问方的协议、IP、端口,三项相同是同源,非同源无法访问。 2. 在控制层添加注解 @CrossOrigin 防止浏览器做同源策略的访问限制,允许前后端联调时访问后端 # springboot-part ## springboot-base-quick-01 1. 依赖管理(pom.xml) 1. 指定`spring-boot-starter-parent`为父工程,所有springboot项目都必须继承自 spring-boot-starter-parent。 2. springboot 作为父工程会对依赖项做统一版本管理,只需声明依赖项坐标,无需指定具体版本 3. 启动器 `springboot-starter` 会自动配置依赖 4. 指定`spring-boot-starter-web`,会自动导入web项目的所有依赖和配置,无需手动导入(spring-webmvc/servlet/jackson) 2. 启动类(Main) 1. `@SpringBootApplication` 标记为启动类 ,作为Spring Boot应用程序的入口。 2. `@SpringBootApplication = @SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan` 3. `@SpringBootConfiguration` 标记为配置类 `@Configuration`,可以配置Bean组件,通过 @Bean 将方法创建的组件导入IOC容器。 4. `@EnableAutoConfiguration` 启用Spring Boot的自动配置机制,根据类路径、注解、配置属性自动加载配置。 5. `@ComponentScan` 类路径扫描,自动扫描并加载应用程序中的组件,默认扫描启动类所在包和子包中注解的组件 6. `SpringApplication.run(Main.class, args);` 固定写法,自动创建ioc容器,加载配置。启动内置的web服务器tomcat 3. 控制类(HelloController) 1. 只要保证当前类在主启动类所在的根包路径下,就会自动扫描到IOC容器 2. @RestController = @ResponseBody + @Controller 3. @RequestMapping("") 4. @Value("${}") 读取配置文件 application.properties 配置参数值 4. 配置文件(application.properties) 1. 统一进行配置管理 2. 使用springboot提供的配置,key固定,修改参数值 3. 使用自定义配置,指定 key-value ## springboot-base-application-02 1. application.properties 配置文件格式 1. 使用 `key = value` 格式 2. 所有框架统一设置配置参数,要求key值唯一 3. 通过对key设置多层命名保证唯一性 4. 导致多层命名繁琐 2. application.yml 配置文件格式,推荐 1. 前缀必须使用 application,用中划线拼接描述 application-dev,后缀使用 .yml 或 .yaml 2. 使用缩进层次 `key:空格value` 格式 3. 多个value值时使用中划线 - 4. spring.profiles.active 用于激活其他 yml 配置文件 5. 外部配置key对应的value会覆盖内部同名key的值 3. 实体类(User) 1. @Value("${}") 读取配置文件的参数值,通过DI实现 1. 用于类的属性,读取配置参数 2. key值必须写全 3. 只能读取单个值 2. @ConfigurationProperties(prefix="") 1. 用于类,批量读取配置参数 2. prefix 指定配置文件的通用前缀 3. 类的属性名和配置文件参数最后一层key名相同 4. 可以给集合类型赋值 ## springboot-base-springmvc-03 - springboot 整合 SpringMVC 1. 依赖管理(pom.xml) 2. 启动类(Main) 3. 控制类(HelloController) 4. 配置文件(application.yml) 1. springmvc相关的web配置key为server 2. 静态资源配置,默认指定的目录下会静态资源会自动扫描,提供外部访问,如 classpath:resources/static 3. 可以通过 spring.web.resources.static-locations 指定静态资源路径,如 classpath:/webapp 4. 配置文件指定静态资源路径后,默认静态资源路径会失效 5. 当外部通过浏览器访问时,无需添加文件夹的路径,按项目访问路径访问即可 5. 拦截器(MyInterceptor)实现 HandlerInterceptor.preHandle() 方法 6. 配置类(WebMvcConfig) 1. @Configuration 与启动类同包下的配置类会自动被扫描到IOC容器 2. 实现 WebMvcConfigurer.addInterceptors() 注册拦截器 ## springboot-base-druid-04 - springboot 整合 Druid 1. 依赖管理 1. web应用 spring-boot-starter-web 2. 数据库jdbctemplate spring-boot-starter-jdbc 3. druid启动器 druid-spring-boot-3-starter 4. mysql驱动 mysql-connector-java 2. 配置文件 application.yml 3. 控制器,添加jdbc启动器starter,会自动将组件导入IOC容器 4. 启动类 5. 由于Druid和springboot3的兼容性问题,在 resources/META-INF/spring/ 下添加文件 ## springboot-base-mybatis-05 - springboot 整合 MyBatis 1. 依赖管理 2. 配置文件 application.yml 1. 完全去除 mybatis 配置文件 mybatis-config.xml 2. 指定 XML映射文件的路径 3. 启动类 1. @MapperScan("springboot.mybatis.mapper") 指定Mapper接口所在包路径 4. Mapper接口,定义查询方法 5. XML映射文件,编写具体SQL语句 6. 控制器 - springboot 整合事务 1. 业务层(UserService) 1. 声明式事务 @Transactional 用于方法,异常时自动回滚 2. 只要导入了 spring-boot-starter-jdbc 依赖,就可以直接使用注解完成事务控制 - springboot 整合AOP 1. 工具类(LogAdvice) 1. 只要导入了 spring-boot-starter-aop 依赖,就可以直接使用注解完成AOP 2. 声明切面 @Aspect 3. 指定切点 @Before() - springboot 打包 1. 导入打包插件 spring-boot-maven-plugin 2. Maven 打包 3. 通过 java -jar 运行 jar 包 # mybatis-plus-part ## mybatis-plus-base-quick-01 1. MybatisPlus使用 1. 接口继承`BaseMapper`,接口自动包含所有单表操作方法。只需自定义多表操作方法和对应XML映射文件。 2. 测试Mapper接口方法执行CRUD ## mybatis-plus-crud-mapper-02 1. 调用 MyBatisPlus 封装的方法执行 CRUD 操作 2. 使用 update 系列方法时(方法传入新创建的实体类对象,只对要修改的属性赋值),会自动过滤为空null的类属性,不做修改。 3. 因此在声明实体类属性时,属性均使用包装类Integer,默认初始化为null。(基本数据类型默认初始化为0,需要对传入的实体类所有属性赋值) ## mybatis-plus-crud-service-03 1. Service 层增强,简单的CRUD操作可以直接在本层完成,无需向后调用Mapper层 2. Service 层接口继承 `IService` 接口,提供了部分CRUD方法和实现 3. Service 层实现类继承`ServiceImpl, T>` 类,提供了另一部分CRUD方法和实现 ## mybatis-plus-other-04 ### 分页查询 1. MybatisPlus 自带方法 1. 主启动类添加插件集合`MybatisPlusInterceptor` 2. 向集合添加分页插件 `PaginationInnerInterceptor` 3. 调用CRUD方法,传入 `Page<>(页码,页容量)` 进行分页查询 4. 分页查询结果页通过 `Page` 获取 2. 自定义Mapper接口方法 1. MyBatisPlus 配置默认XML映射文件目录在 mapper 文件夹下 ### 条件构造器 1. `QueryWrapper` 用法 1. 创建 QueryWrapper 对象 2. 调用相关方法添加查询条件 3. 所有方法返回结果还是 QueryWrapper 对象,可以进行链式调用 4. 条件间默认使用 and 拼接,通过 `.or().` 拼接方法实现或语句,且只对紧跟的一个方法生效,后续拼接方法还是and 5. 问题:修改数据时,需要创建实体对象,将要修改的属性赋值;如果要将属性值为null,无法通过 QueryWrapper 实现,因为只有不为 null 的属性生效修改数据库 2. QueryWrapper 方法 1. `like(R column, Object val)` 2. `between(R column, Object val1, Object val2)` 3. `isNotNull(R column)` 4. `isNull(R column)` 5. `orderByDesc(R column)` 6. `orderByAsc(R column)` 7. `gt(R column, Object val)` 8. `select(String... columns)` 9. `eq(boolean condition, R column, Object val)` 10. 所有方法都提供了一个 boolean 类型入参, 3. `UpdateWrapper` 1. `set(R column, Object val)` 直接指定列名修改对应值 2. 可以将属性值赋值修改 null 4. `LambdaQueryWrapper` 1. 避免使用 QueryWrapper 填写类属性名时写错,提供了 lambda 表达式和方法引用类型参数 2. 将列名(类属性名)替换为方法引用,格式:`类名::方法名`,如:`between(User::getAge,20,30)` 5. `LambdaUpdateWrapper` ### @TableName 1. 用于实体类,不用注解时,默认使用类名作为表名,忽略大小写 2. 当数据库表名和实体类名不同时,通过 @TableName("table_name") 指定表名 3. 可以通过配置文件统一添加前缀 application.yml 配置 `mybatis-plus.global-config.db-config.table-prefix: xx_` ### @TableId 1. 用于类属性,设置主键自增长。要求MySQL数据库设置了数字类型的主键,且开启了自增长auto_increment 2. 执行插入数据操作时,生成的主键默认使用雪花算法,实体类生成Long类型数组,对应数据库bigint/varchar(64)。用于分布式或大量数据。 3. @TableId(type = IdType.AUTO) 4. 可以通过配置文件统一设置主键策略 application.yml 配置 `mybatis-plus.global-config.db-config.id-type: auto` ### @TableFiled 1. 用于标注类属性是否为数据库字段 2. `@TableField(value = "数据库字段名", exist = 是否为数据库字段)` ### 逻辑删除 @TableLogic 1. 数据库增加字段,表示数据是逻辑删除,不是真实删除 2. 实体类添加属性,表示数据是逻辑删除,不是真实删除 3. `@TableLogic` 用于类属性,标注对应的数据库字段为逻辑删除字段 4. 当执行删除操作后,自动变成修改此列的属性值,默认0表示未删除,1表示删除 5. 当执行查询操作时,默认只返回状态值为 0 的数据 6. 可以通过配置文件统一设置逻辑属性名 application.yml 配置 `mybatis-plus.global-config.db-config.logic-delete-field: deleted` 7. 设置逻辑删除字段、指定逻辑删除注解或配置后,执行查询操作时,会自动拼接 `where deleted = 0` ### 乐观锁 1. 版本号控制实现乐观锁,向插件集合中添加插件实现`OptimisticLockerInnerInterceptor` 2. 数据库增加字段,表示当前数据的版本号 3. 实体类添加属性,表示当前数据的版本号,`@Version` 用于类属性,标注对应的数据库字段为版本号字段 4. 当同时执行修改更新操作时,MyBatisPlus插件自动完成版本号对比和版本号更新,冲突时更新失败 ### 防止全表更新和删除 1. 向插件集合中添加 防止全表删除和更新的拦截器 `BlockAttackInnerInterceptor` 2. 执行无条件删除操作后,会报错`userMapper.delete(null);` 3. Error updating database. Cause: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Prohibition of table update operation