美文网首页
spring boot教程

spring boot教程

作者: 紫色红色黑色 | 来源:发表于2020-04-22 09:29 被阅读0次

    描述

    集成mybatis

    首先要引入mybatis依赖

    注解式开发

    编写dao层,在接口中使用注解开发。
    @Mapper是mybatis的注解,在service层@Autowired注入的时候爆红说该类没有初始化,可以使用@Resource注解替换。
    @Mapper也可以不用,改用springboot启动类上的注解@MapperScan

    @Mapper
    public interface StudentDao {
    
        @Select("select id,name,age,status,address from test")
        List<Student> queryList(StudentCondition condition);
    
        @Insert("insert into test (name,age,status,address) values (#{name},#{age},#{status},#{address})")
        void insert(StudentCondition condition);
    
        @Delete("delete from test where id=#{id}")
        void delete(int id);
    
        @Update("update test set name=#{name},age=#{age},status=#{status},address=#{address}")
        void update(StudentCondition condition);
    
        @Select("select id,name,age,status,address from test where id=#{id}")
            //@ResultMap("studentMap") 该注解需要xml中书写resultmap
        Student queryOne(int id);
    }
    

    配置式开发

    在springboot application.yml中指定mapper-config.xml和mapper文件的位置。然后编写mapper文件

    mybatis:
      config-location: classpath:mybatis/mybatis-config.xml
      mapper-locations: classpath:mybatis/mapper/*.xml
    

    mybatis-config.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    
    <configuration>
    
    </configuration>
    

    studentDao.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="com.redoor.springboot.demo.student.StudentXmlDao">
        
        <select id="queryList" resultType="com.redoor.springboot.demo.student.Student">
            select id,name,age,status,address from test
        </select>
        
        <select id="queryOne" resultType="com.redoor.springboot.demo.student.Student">
            select id,name,age,status,address from test
            <trim prefix="where" prefixOverrides="and | or">
                <if test="id!=null">
                    id=#{id}
                </if>
            </trim>
        </select>
        
        <delete id="delete" parameterType="int">
            delete from test where id=#{id}
        </delete>
    
        <insert id="insert" parameterType="com.redoor.springboot.demo.student.StudentCondition">
            insert into test (name, age, status, address)
            values (#{name}, #{age}, #{status}, #{address});
        </insert>
    
        <update id="update" parameterType="com.redoor.springboot.demo.student.StudentCondition">
            update test
            <trim prefix="set" suffixOverrides=",">
                <if test="name!=null">name=#{name}</if>
                <if test="age>0">age=#{age}</if>
                <if test="status>0">status=#{status}</if>
                <if test="address!=null">address=#{address}</if>
            </trim>
            where id=#{id}
        </update>
    </mapper>
    

    多数据源配置

    使用aop形式动态切换数据源
    1.pom中增加aop依赖组,application.yml中配置两个数据源

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    
    spring:
      db1:
        url: jdbc:mysql://127.0.0.1:3306/text?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
        username: root
        password: root
        driver-class-name: com.mysql.jdbc.Driver
      db2:
        url: jdbc:mysql://127.0.0.1:3306/text2?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
        username: root
        password: root
        driver-class-name: com.mysql.jdbc.Driver
    

    2.编写aop工具类

    • 自定义动态数据源类DynamicDataSource继承AbstractRoutingDataSource,实现determineCurrentLookupKey()数据源路由方法。
    public class DynamicDataSource extends AbstractRoutingDataSource {
    
        @Override
        protected Object determineCurrentLookupKey() {
            return DynamicDataSourceHolder.getDbName();
        }
    }
    
    • 自定义aop切面类DataSourceAspect,拦截dao层方法,并获取自定义注解值。
    @Component
    @Aspect
    @Slf4j
    public class DataSourceAspect {
    
        @Pointcut("execution(* com.redoor.springboot.demo.*.dao.*.*(..))")
        public void dynamicDbPointCut() {}
    
    
        @Before("dynamicDbPointCut()")
        public void before(JoinPoint jp) {
            try {
    
                Class<?>[] interfaces = jp.getTarget().getClass().getInterfaces();
                boolean classAnnotationPresent = interfaces[0].isAnnotationPresent(DbName.class);
    
                boolean dbNameAnnotation = classAnnotationPresent;
                String dbNameValue = null;
    
                if (classAnnotationPresent) {
                    dbNameValue = interfaces[0].getAnnotation(DbName.class).value();
                } else {
                    MethodSignature methodSignature = (MethodSignature) jp.getSignature();
                    Method method = methodSignature.getMethod();
                    boolean methodAnnotationPresent = method.isAnnotationPresent(DbName.class);
                    dbNameAnnotation = methodAnnotationPresent;
                    if (methodAnnotationPresent) {
                        dbNameValue = method.getAnnotation(DbName.class).value();
                    }
                }
                if (dbNameAnnotation && dbNameValue != null) {
                    DynamicDataSourceHolder.putDbName(dbNameValue);
                    log.info("aspect finished put" + dbNameValue);
                }
    
            } catch (Exception e) {
                log.error("aspect exception", e.getMessage());
            }
        }
    
        @After("dynamicDbPointCut()")
        public void after() {
            DynamicDataSourceHolder.removeDbName();
            log.info("aspect finished remove ");
    
        }
    
        @AfterThrowing("dynamicDbPointCut()")
        public void afterThrowing() {
            DynamicDataSourceHolder.removeDbName();
            log.info("aspect finished remove ");
        }
    
    }
    
    

    原理:数据源初始化时定义好数据源名称DbName。aop切面拦截到dao层注解并获取注解中DbName值,再将其写入到ThreadLocal中。然后后期使用数据源的时候先调用determineCurrentLookupKey()从ThreadLocal中取出DbName,在根据DbName取出对应的数据源。

    3.配置数据源工具类
    将多个数据源配置到DynamicDataSource中。

    
    @Configuration
    public class DataSourceConfig {
    
        @Bean
        @Primary
        @ConfigurationProperties(prefix = "spring.db1")
        DataSource db1() {
            return DataSourceBuilder.create().build();
        }
    
        @Bean
        @ConfigurationProperties(prefix = "spring.db2")
        DataSource db2() {
            return DataSourceBuilder.create().build();
        }
    
        @Bean
        public DynamicDataSource dynamicDataSource(@Qualifier("db1") DataSource db1, @Qualifier("db2") DataSource db2) {
    
            HashMap<Object, Object> map = new HashMap<>(2);
            map.put("db1", db1);
            map.put("db2", db2);
    
            DynamicDataSource dynamicDataSource = new DynamicDataSource();
            dynamicDataSource.setTargetDataSources(map);
            dynamicDataSource.setDefaultTargetDataSource(db1);
    
            return dynamicDataSource;
        }
    
        @Bean
        public DataSourceTransactionManager transactionManager(DynamicDataSource dynamicDataSource) {
            return new DataSourceTransactionManager(dynamicDataSource);
        }
    
        @Bean
        public SqlSessionFactory sqlSessionFactory(@Qualifier("dynamicDataSource") DataSource dataSource) throws Exception {
            SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
            factoryBean.setDataSource(dataSource);
            factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/*.xml"));
            return factoryBean.getObject();
        }
    }
    

    引用

    https://www.cnblogs.com/ityouknow/p/6037431.html
    https://juejin.im/post/5d830944f265da03963bd153
    http://tech.dianwoda.com/2018/03/28/spring-boot-aopfang-shi-shi-xian-duo-shu-ju-yuan-qie-huan/
    https://blog.51cto.com/lavasoft/172292

    引用

    http://www.spring4all.com/article/246
    这是一篇优雅的Springboot2.0使用手册

    相关文章

      网友评论

          本文标题:spring boot教程

          本文链接:https://www.haomeiwen.com/subject/vmoygctx.html