小言_互联网的博客

你确定会?Spring集成MyBatis | Spring系列第53篇

348人阅读  评论(0)

1、本文内容【文末送书】

本文主要介绍mybatis和spring集成的两种方式,对MyBatis不熟悉的,建议先看一下MyBatis高手系列

目前注解的方式我们用的比较多,所以主要介绍注解的方式,xml的方式这里就暂时不介绍了。

注解的方式mybatis集成spring主要有2种方式:

1、方式1:mapper xml文件放在resource目录,和Mapper接口不在一个目录的情况

2、方式2:mapper xml文件和Mapper接口在同一个目录

还会介绍另外一个点:多数据库的时候,如何配置?

2、案例代码


   
  1. git地址:
  2. https: //gitee.com/javacode2018/spring-series
  3. 方式 1源码:spring-series\lesson -005-mybatis
  4. 方式 2源码:spring-series\lesson -006-mybatis

3、准备db脚本


   
  1. /*创建数据库javacode2018*/
  2. DROP DATABASE IF EXISTS  `javacode2018`;
  3. CREATE DATABASE  `javacode2018`;
  4. USE  `javacode2018`;
  5. /*创建表结构*/
  6. DROP TABLE IF EXISTS  `t_user`;
  7. CREATE TABLE t_user (
  8.   id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT  '主键,用户id,自动增长',
  9.    `name` VARCHAR( 32) NOT NULL DEFAULT  '' COMMENT  '姓名'
  10. ) COMMENT  '用户表';
  11. SELECT * FROM t_user;

下面我们来通过mybatis对上面的表执行插入和查询的操作。

4、方式1

4.1、项目结构

这种方式,Mapper接口和mapper xml文件放在不同的位置,mapper xml文件放在resource/mapper目录,如下图

4.2、UserModel


   
  1. package com.javacode2018.mybatis.model;
  2. import lombok.*;
  3. /**
  4.  * 公众号:路人甲Java,工作10年的前阿里P7分享Java、算法、数据库方面的技术干货!
  5.  * <a href="http://www.itsoku.com">个人博客</a>
  6.  */
  7. @Getter
  8. @Setter
  9. @Builder
  10. @NoArgsConstructor
  11. @AllArgsConstructor
  12. @ToString
  13. public class UserModel {
  14.     private Long id;
  15.     private String name;
  16. }

4.3、UserMapper

这个是mapper接口,类上面需要添加**@Mapper注解**,用来标注这是一个Mapper接口


   
  1. package com.javacode2018.mapper;
  2. import com.javacode2018.mybatis.model.UserModel;
  3. import org.apache.ibatis.annotations.Mapper;
  4. import java.util.List;
  5. /**
  6.  * 公众号:路人甲Java,工作10年的前阿里P7分享Java、算法、数据库方面的技术干货!
  7.  * <a href="http://www.itsoku.com">个人博客</a>
  8.  */
  9. @Mapper
  10. public  interface UserMapper {
  11.     void insert(UserModel userModel);
  12.     List<UserModel> getList();
  13. }

4.4、UserMapper.xml

在spring-series\lesson-005-mybatis\src\main\resources\mapper中添加UserMapper.xml文件,这个文件名大家可以随意起名,不一定非要叫UserMapper,具体位置大家可以看看上面的项目结构图


   
  1. <?xml version= "1.0" encoding= "UTF-8" ?>
  2. <!DOCTYPE mapper PUBLIC  "-//mybatis.org//DTD Mapper 3.0//EN"
  3.          "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  4. <mapper namespace= "com.javacode2018.mapper.UserMapper">
  5.     <insert id= "insert" parameterType= "com.javacode2018.mybatis.model.UserModel" keyProperty= "id" useGeneratedKeys= "true">
  6.         <CDATA[ INSERT INTO  `t_user` (name) VALUES (#{name})]]>
  7.     </insert>
  8.     < select id= "getList" resultType= "com.javacode2018.mybatis.model.UserModel">
  9.         <CDATA[
  10.         SELECT id,name FROM t_user
  11.         ]]>
  12.     </ select>
  13. </mapper>

4.5、IUserService


   
  1. package com.javacode2018.service;
  2. import com.javacode2018.mybatis.model.UserModel;
  3. import java.util.List;
  4. /**
  5.  * 公众号:路人甲Java,工作10年的前阿里P7分享Java、算法、数据库方面的技术干货!
  6.  * <a href="http://www.itsoku.com">个人博客</a>
  7.  */
  8. public  interface IUserService {
  9.      /**
  10.      * 插入用户信息
  11.      *
  12.      * @param userModel
  13.      * @return
  14.      */
  15.     UserModel insert(UserModel userModel);
  16.      /**
  17.      * 查询用户所有记录
  18.      *
  19.      * @return
  20.      */
  21.     List<UserModel> getList();
  22. }

4.6、UserServiceImpl

IUserService的实现类,内部将Usermapper通过@Autowired注入进来,通过userMapper来访数据库,userMapper实际上是mybatis创建的一个代理对象。


   
  1. package com.javacode2018.service;
  2. import com.javacode2018.mapper.UserMapper;
  3. import com.javacode2018.mybatis.model.UserModel;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.stereotype.Service;
  6. import org.springframework.transaction.annotation.Propagation;
  7. import org.springframework.transaction.annotation.Transactional;
  8. import java.util.List;
  9. /**
  10.  * 公众号:路人甲Java,工作10年的前阿里P7分享Java、算法、数据库方面的技术干货!
  11.  * <a href="http://www.itsoku.com">个人博客</a>
  12.  */
  13. @Service
  14. public class UserServiceImpl implements IUserService {
  15.     @Autowired
  16.     private UserMapper userMapper;
  17.     @Transactional(rollbackFor = Exception.class)
  18.     @Override
  19.     public UserModel insert(UserModel userModel) {
  20.         userMapper.insert(userModel);
  21.          return userModel;
  22.     }
  23.     @Transactional(propagation = Propagation.SUPPORTS, readOnly =  true)
  24.     @Override
  25.     public List<UserModel> getList() {
  26.          return userMapper.getList();
  27.     }
  28. }

4.7、spring配置类MainConfig


   
  1. package com.javacode2018;
  2. import com.javacode2018.mapper.UserMapper;
  3. import org.apache.ibatis.annotations.Mapper;
  4. import org.mybatis.spring.SqlSessionFactoryBean;
  5. import org.mybatis.spring.annotation.MapperScan;
  6. import org.springframework.beans.factory.annotation.Qualifier;
  7. import org.springframework.context.annotation.Bean;
  8. import org.springframework.context.annotation.ComponentScan;
  9. import org.springframework.context.annotation.Configuration;
  10. import org.springframework.core.io.Resource;
  11. import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
  12. import org.springframework.jdbc.datasource.DataSourceTransactionManager;
  13. import org.springframework.transaction.PlatformTransactionManager;
  14. import org.springframework.transaction.TransactionManager;
  15. import org.springframework.transaction.annotation.EnableTransactionManagement;
  16. import javax.sql.DataSource;
  17. import java.io.IOException;
  18. /**
  19.  * 公众号:路人甲Java,工作10年的前阿里P7分享Java、算法、数据库方面的技术干货!
  20.  * <a href="http://www.itsoku.com">个人博客</a>
  21.  */
  22. @EnableTransactionManagement  //开启事务支持
  23. @ComponentScan
  24. @Configuration
  25. // @MapperScan这个注解是关键,会扫描标记有@Mapper注解的Mapper接口,将其注册到spring容器中
  26. @MapperScan(basePackageClasses = {UserMapper.class}, annotationClass = Mapper.class)
  27. public class MainConfig {
  28.      //定义数据源
  29.     @Bean
  30.     public DataSource dataSource() {
  31.         org.apache.tomcat.jdbc.pool.DataSource dataSource =  new org.apache.tomcat.jdbc.pool.DataSource();
  32.         dataSource.setDriverClassName( "com.mysql.jdbc.Driver");
  33.         dataSource.setUrl( "jdbc:mysql://localhost:3306/javacode2018?characterEncoding=UTF-8");
  34.         dataSource.setUsername( "root");
  35.         dataSource.setPassword( "root123");
  36.         dataSource.setInitialSize( 5);
  37.          return dataSource;
  38.     }
  39.      //定义事务管理器
  40.     @Bean
  41.     public TransactionManager transactionManager(DataSource dataSource) {
  42.          return  new DataSourceTransactionManager(dataSource);
  43.     }
  44.      //定义SqlSessionFactoryBean,用来创建SqlSessionFactory
  45.     @Bean
  46.     public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) throws IOException {
  47.         SqlSessionFactoryBean sqlSessionFactoryBean =  new SqlSessionFactoryBean();
  48.         sqlSessionFactoryBean.setDataSource(dataSource);
  49.          //获取所有mapper.xml文件
  50.         Resource[] resources =  new PathMatchingResourcePatternResolver().getResources( "classpath*:mapper/**/*.xml");
  51.         sqlSessionFactoryBean.setMapperLocations(resources);
  52.          return sqlSessionFactoryBean;
  53.     }
  54. }

这个类中有2个关键信息:

1、@MapperScan注解:这个注解是关键,会扫描标记有@Mapper注解的Mapper接口类,然后给Mapper接口生成代理对象,将其注册到spring容器中,这个注解有几个属性需要注意下

  • value或者basePackages:String类型的数组,用来指定扫描的包

  • basePackageClasses:可以指定一个类,扫描范围为这个类所在的包及其所有子包

  • sqlSessionFactoryRef:用来指定sqlSessionFactory的bean名称,当我们的系统中需要操作多个库的时候,每个库对应一个SqlSessionFactory,此时可以通过这个属性指定需要使用哪个SqlSessionFactory。

2、定义SqlSessionFactoryBean:通过名字大家可以看出,这个是用来生成SqlSessionFactory的,内部需要指定数据源和本地mapper xml的位置,我们将mapper xml文件放在resouce/mapper文件中,此处我们采用通配符的方式,加载classpath中mapper目录及子目录中的所有xml文件


   
  1. Resource[] resources =  new PathMatchingResourcePatternResolver().getResources( "classpath*:mapper/**/*.xml");
  2. sqlSessionFactoryBean.setMapperLocations(resources);

4.8、测试效果

来个测试类


   
  1. package com.javacode2018;
  2. import com.javacode2018.mybatis.model.UserModel;
  3. import com.javacode2018.service.IUserService;
  4. import org.junit.Test;
  5. import org.springframework.context.annotation.AnnotationConfigApplicationContext;
  6. import java.util.List;
  7. /**
  8.  * 公众号:路人甲Java,工作10年的前阿里P7分享Java、算法、数据库方面的技术干货!
  9.  * <a href="http://www.itsoku.com">个人博客</a>
  10.  */
  11. public class MybatisSpringTest {
  12.     @Test
  13.     public void insert() {
  14.         AnnotationConfigApplicationContext context =  new AnnotationConfigApplicationContext(MainConfig.class);
  15.         IUserService userService = context.getBean(IUserService.class);
  16.         UserModel userModel = UserModel.builder().name( "张三").build();
  17.         userService.insert(userModel);
  18.         System.out. println(userModel);
  19.     }
  20.     @Test
  21.     public void getList() {
  22.         AnnotationConfigApplicationContext context =  new AnnotationConfigApplicationContext(MainConfig.class);
  23.         IUserService userService = context.getBean(IUserService.class);
  24.         List<UserModel> userModelList = userService.getList();
  25.         System.out. println(userModelList);
  26.     }
  27. }

insert方法用来插入数据,执行输出

UserModel(id=1, name=张三)

getList方法用来查询表中所有数据,运行输出

[UserModel(id=1, name=张三)]

4.8、小结:回顾步骤

主要分为3步

1、Mapper接口上添加@Mapper注解


   
  1. @Mapper
  2. public  interface UserMapper

2、定义mapper xml文件,如将user.xml文件放在了spring-series\lesson-005-mybatis\src\main\resources\mapper目录

3、spring配置类中添加@MapperScan注解,用来扫描@Mapper标注的类,将其注册到spring容器中

@MapperScan(basePackageClasses = {UserMapper.class}, annotationClass = Mapper.class)

4、定义SqlSessionFactoryBean


   
  1. @Bean
  2. public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) throws IOException {
  3.     SqlSessionFactoryBean sqlSessionFactoryBean =  new SqlSessionFactoryBean();
  4.      //指定数据源
  5.     sqlSessionFactoryBean.setDataSource(dataSource);
  6.      //获取所有mapper.xml文件
  7.     Resource[] resources =  new PathMatchingResourcePatternResolver().getResources( "classpath*:mapper/**/*.xml");
  8.      //设置mapper的位置
  9.     sqlSessionFactoryBean.setMapperLocations(resources);
  10.      return sqlSessionFactoryBean;
  11. }

5、方式2

5.1、项目结构

这种方式,将mapper xml文件和mapper接口放在同一个目录,下面我们新建一个项目lesson-006-mybatis,结构如下

对比两个图,主要的区别:方式1中将UserMapper.xml文件放在了src\main\resources\mapper目录中,而这种将UserMapper.xml和UserMapper接口放在了同一个目录。

5.2、修改SqlSessionFactoryBean的定义

需要修改MainConfig中SqlSessionFactoryBean的定义,如下,更简洁了,不需要在指定mapper xml的位置了,这里需要注意一点,方式2中将mapper xml文件和mapper接口放在一个目录的时候,这2个文件的名字必须一样,这样在定义SqlSessionFactoryBean的时候才不需要指定mapper xml的位置。


   
  1. @Bean
  2. public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) throws IOException {
  3.     SqlSessionFactoryBean sqlSessionFactoryBean =  new SqlSessionFactoryBean();
  4.     sqlSessionFactoryBean.setDataSource(dataSource);
  5.      return sqlSessionFactoryBean;
  6. }

5.3、调整一下pom.xml配置

pom文件中需要加入下面配置,这样maven在打包的时候,才会将src/main/java目录中的xml打包目录目录中,否则打包之后这些xml都丢失了,这个一定要注意。


   
  1. <build>
  2.     <resources>
  3.         <resource>
  4.             <directory>${project.basedir}/src/main/java</directory>
  5.             <includes>
  6.                 <include>** /*.xml</include>
  7.             </includes>
  8.         </resource>
  9.         <resource>
  10.             <directory>${project.basedir}/src/main/resources</directory>
  11.             <includes>
  12.                 <include>**/*</include>
  13.             </includes>
  14.         </resource>
  15.     </resources>
  16. </build>

5.4、小结

如果使用方式2需要注意下面2点:

1、mapper接口和mapper xml必须同名,且放在同一个目录

2、需要在pom.xml文件中加入指定的配置,否则打包之后xml丢失了

6、集成多个数据源

有时候我们的系统中需要用到多个数据源,每个数据源对应一个SqlSessionFactory,@MapperScan注解中可以通过sqlSessionTemplateRef来指定SqlSessionFactory的bean名称。

6.1、多数据源开发步骤

1、步骤1:@MapperScan中指定SqlSessionFactory的bean名称

每个db对应一个模块,通过包区分不同的模块,每个模块中指定一个spring的配置类,配置类需配置3个bean:数据源、事务管理器、SqlSessionFactory,下面是一个模块的spring配置类,注意下面代码的@MapperScan注解,当系统中有多个sqlSessionFactory的时候需要用过sqlSessionFactoryRef属性指定了sqlSessionFactory的bean名称。

由于有多个数据源,所以代码中需要通过@Qualifier(DATASOURCE_BEAN_NAME)来限定注入的datasource的bean名称。


   
  1. package com.javacode2018.mybatis.module1;
  2. import org.apache.ibatis.annotations.Mapper;
  3. import org.mybatis.spring.SqlSessionFactoryBean;
  4. import org.mybatis.spring.annotation.MapperScan;
  5. import org.springframework.beans.factory.annotation.Qualifier;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.context.annotation.ComponentScan;
  8. import org.springframework.context.annotation.Configuration;
  9. import org.springframework.jdbc.datasource.DataSourceTransactionManager;
  10. import org.springframework.transaction.TransactionManager;
  11. import org.springframework.transaction.annotation.EnableTransactionManagement;
  12. import javax.sql.DataSource;
  13. import java.io.IOException;
  14. @Configuration
  15. @MapperScan(annotationClass = Mapper.class, sqlSessionFactoryRef = Module1SpringConfig.SQL_SESSION_FACTORY_BEAN_NAME)
  16. @ComponentScan
  17. @EnableTransactionManagement
  18. public class Module1SpringConfig {
  19.     public final static String DATASOURCE_BEAN_NAME =  "dataSourcemodule1";
  20.     public final static String TRANSACTION_MANAGER_BEAN_NAME =  "transactionManagermodule1";
  21.     public final static String SQL_SESSION_FACTORY_BEAN_NAME =  "sqlSessionFactorymodule1";
  22.      //定义数据源
  23.     @Bean
  24.     public DataSource dataSourcemodule1() {
  25.         org.apache.tomcat.jdbc.pool.DataSource dataSource =  new org.apache.tomcat.jdbc.pool.DataSource();
  26.         dataSource.setDriverClassName( "com.mysql.jdbc.Driver");
  27.         dataSource.setUrl( "jdbc:mysql://localhost:3306/module1?characterEncoding=UTF-8");
  28.         dataSource.setUsername( "root");
  29.         dataSource.setPassword( "root123");
  30.         dataSource.setInitialSize( 5);
  31.          return dataSource;
  32.     }
  33.      //定义事务管理器
  34.     @Bean
  35.     public TransactionManager transactionManagermodule1(@Qualifier(DATASOURCE_BEAN_NAME) DataSource dataSource) {
  36.          return  new DataSourceTransactionManager(dataSource);
  37.     }
  38.      //定义SqlSessionFactoryBean,用来创建SqlSessionFactory
  39.     @Bean
  40.     public SqlSessionFactoryBean sqlSessionFactorymodule1(@Qualifier(DATASOURCE_BEAN_NAME) DataSource dataSource) throws IOException {
  41.         SqlSessionFactoryBean sqlSessionFactoryBean =  new SqlSessionFactoryBean();
  42.         sqlSessionFactoryBean.setDataSource(dataSource);
  43.          return sqlSessionFactoryBean;
  44.     }
  45. }

2、步骤2:指定事务管理器

每个db对应一个datasource,每个datasource需要指定一个事务管理器,通过@Transaction注解的transactionManager属性指定事务管理器,如下

@Transactional(transactionManager = Module1SpringConfig.TRANSACTION_MANAGER_BEAN_NAME, rollbackFor = Exception.class)

6.2、案例

下面我们通过案例来感受一下多个db的时候如何实现的。

1、案例代码

spring-series\lesson-007-mybatis

2、项目结构图

  • 案例中我们准备了2个数据库:module1和module2,每个库中创建了一个t_user表

  • module1库对应的所有类放在com.javacode2018.mybatis.module1包中

  • module2库对应的所有类放在com.javacode2018.mybatis.module2包中

  • Module1SpringConfig是module1的spring配置类

  • Module2SpringConfig是module2的spring配置类

3、项目如何运行?

1、导入项目到idea中

2、执行sql脚本


   
  1. /*创建2个库:module1和module2,每个库中创建一个t_user表*/
  2. DROP DATABASE IF EXISTS  `module1`;
  3. CREATE DATABASE  `module1`;
  4. DROP DATABASE IF EXISTS  `module2`;
  5. CREATE DATABASE  `module2`;
  6. /*创建表结构*/
  7. DROP TABLE IF EXISTS module1.t_user;
  8. CREATE TABLE module1.t_user (
  9.   id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT  '主键,用户id,自动增长',
  10.    `name` VARCHAR( 32) NOT NULL DEFAULT  '' COMMENT  '姓名'
  11. ) COMMENT  '用户表';
  12. DROP TABLE IF EXISTS module2.t_user;
  13. CREATE TABLE module2.t_user (
  14.   id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT  '主键,用户id,自动增长',
  15.    `name` VARCHAR( 32) NOT NULL DEFAULT  '' COMMENT  '姓名'
  16. ) COMMENT  '用户表';
  17. SELECT * FROM module1.t_user;
  18. SELECT * FROM module2.t_user;

3、运行测试用例

com.javacode2018.mybatis.MybatisSpringTest

这个用例中有2个方法,大家可以运行一下,看看2个db的时候,效果如何。

6.3、小结

系统中集成多个数据源这种方式,大家作为了解就可以了,不建议这么使用,通常一个业务库对应一个module,模块与模块之间相互隔离,独立部署,便于维护扩展。

7、Spring集成MyBatis的原理

有些朋友可能想研究spring中是如何集成mybatis的,对这块比较感兴趣,这里我就不细说了,如果大家有兴趣的,可以先看一下我前面写的MyBatis高手系列,以及目前spring系列所有的文章,那么mybatis集成spring的原理,可以从@MapperScan注解下手,你会秒懂的!!!这里就留个大家去研究了。

再插2句,一直有很多粉丝说让我写springboot系列,为什么我要花这么多时间来写spring系列?写了这么多,用到的有多少?

大家如果将spring的原理吃透了,springboot不是小意思么,所以建议大家先把spring系列的所有文章吃透,那么springboot即使我还没写,你们自己去看一下源码也是很容易的懂了。看不懂是因为欠缺的太多,spring中的很多原理你还没有掌握,所以看springboot会懵逼,一点点来吧,先把基础打牢,基础ok了,后面学东西会很快的,慢就是快,细品!!!

8、总结

本文介绍了spring中集成mybatis的2种方式,2种方式的重点都在上面的小结中,相对来说还是挺简单的,具体用哪种方式,大家自由选择。

9、Spring系列

  1. Spring系列第1篇:为何要学spring?

  2. Spring系列第2篇:控制反转(IoC)与依赖注入(DI)

  3. Spring系列第3篇:Spring容器基本使用及原理

  4. Spring系列第4篇:xml中bean定义详解(-)

  5. Spring系列第5篇:创建bean实例这些方式你们都知道?

  6. Spring系列第6篇:玩转bean scope,避免跳坑里!

  7. Spring系列第7篇:依赖注入之手动注入

  8. Spring系列第8篇:自动注入(autowire)详解,高手在于坚持

  9. Spring系列第9篇:depend-on到底是干什么的?

  10. Spring系列第10篇:primary可以解决什么问题?

  11. Spring系列第11篇:bean中的autowire-candidate又是干什么的?

  12. Spring系列第12篇:lazy-init:bean延迟初始化

  13. Spring系列第13篇:使用继承简化bean配置(abstract & parent)

  14. Spring系列第14篇:lookup-method和replaced-method比较陌生,怎么玩的?

  15. Spring系列第15篇:代理详解(Java动态代理&cglib代理)?

  16. Spring系列第16篇:深入理解java注解及spring对注解的增强(预备知识)

  17. Spring系列第17篇:@Configration和@Bean注解详解(bean批量注册)

  18. Spring系列第18篇:@ComponentScan、@ComponentScans详解(bean批量注册)

  19. Spring系列第18篇:@import详解(bean批量注册)

  20. Spring系列第20篇:@Conditional通过条件来控制bean的注册

  21. Spring系列第21篇:注解实现依赖注入(@Autowired、@Resource、@Primary、@Qulifier)

  22. Spring系列第22篇:@Scope、@DependsOn、@ImportResource、@Lazy 详解

  23. Spring系列第23篇:Bean生命周期详解

  24. Spring系列第24篇:父子容器详解

  25. Spring系列第25篇:@Value【用法、数据来源、动态刷新】

  26. Spring系列第26篇:国际化详解

  27. Spring系列第27篇:spring事件机制详解

  28. Spring系列第28篇:Bean循环依赖详解

  29. Spring系列第29篇:BeanFactory扩展(BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor)

  30. Spring系列第30篇:jdk动态代理和cglib代理

  31. Spring系列第31篇:aop概念详解

  32. Spring系列第32篇:AOP核心源码、原理详解

  33. Spring系列第33篇:ProxyFactoryBean创建AOP代理

  34. Spring系列第34篇:@Aspect中@Pointcut 12种用法

  35. Spring系列第35篇:@Aspect中5中通知详解

  36. Spring系列第36篇:@EnableAspectJAutoProxy、@Aspect中通知顺序详解

  37. Spring系列第37篇:@EnableAsync & @Async 实现方法异步调用

  38. Spring系列第38篇:@Scheduled & @EnableScheduling定时器详解

  39. Spring系列第39篇:强大的Spel表达式

  40. Spring系列第40篇:缓存使用(@EnableCaching、@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig)

  41. Spring系列第41篇:@EnableCaching集成redis缓存

  42. Spring系列第42篇:玩转JdbcTemplate

  43. Spring系列第43篇:spring中编程式事务怎么用的?

  44. Spring系列第44篇:详解spring声明式事务(@Transactional)

  45. Spring系列第45篇:带你吃透Spring事务7种传播行为

  46. Spring系列第46篇:Spring如何管理多数据源事务?

  47. Spring系列第47篇:spring编程式事务源码解析

  48. Spring系列第48篇:@Transaction 事务源码解析

  49. Spring系列第49篇:通过Spring事务实现MQ中的事务消息

  50. Spring系列第50篇:spring事务拦截器顺序如何控制?

  51. Spring系列第51篇:导致 Spring 事务失效常见的几种情况

  52. Spring系列第52篇:Spring实现数据库读写分离

10、更多好文章

  1. Java高并发系列(共34篇)

  2. MySql高手系列(共27篇)

  3. Maven高手系列(共10篇)

  4. Mybatis系列(共12篇)

  5. 聊聊db和缓存一致性常见的实现方式

  6. 接口幂等性这么重要,它是什么?怎么实现?

  7. 泛型,有点难度,会让很多人懵逼,那是因为你没有看这篇文章!

11、福利

这边整理了几百本计算机相关的电子书,下面是部分截图,常见的基本上都有,获取方式,扫描文末二维码,发送:电子书


转载:https://blog.csdn.net/likun557/article/details/110211939
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场