zoukankan      html  css  js  c++  java
  • SpringBoot整合MyBatis

    1. SpringBoot整合MyBatis 【接口注解方式】

    仅做配置记录,方便以后快速搭建粘贴,没有任何营养价值

    1.0 创建表的Sql 脚本

    CREATE TABLE `User` (
      `id` bigint NOT NULL AUTO_INCREMENT,
      `name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL,
      `age` int DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
    

    1.1 需要Maven配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.3.4.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <groupId>com.plumblossom</groupId>
        <artifactId>springboot-transaction</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>springboot-transaction</name>
        <description>Spring Transaction Knowledge</description>
    
        <properties>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
    
            <!-- 配置MyBatis连接数据库,还需要配置 mysql驱动包-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.1.3</version>
            </dependency>
    
            <!--  配置驱动包-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
    
    		<!-- 为了简化Bean的Get Set 方法-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    

    1.2 Properties 配置文件内容

    # MyBatis 配置
    spring.datasource.url=jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF8&serverTimezone=UTC
    spring.datasource.username=root
    spring.datasource.password=123321
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    

    上述配置有两点需要说明:

    1. 配置spring.datasource.url 的时候需要配置下时区不然运行的时候会抛出异常
    2. spring.datasource.driver-class-name 这个是因为 默认使用的是mysql8 的连接驱动所以和传统的比较多了个cj

    1.3 User 对象的实体类

    package com.plumblossom.springboottransaction.bean;
    
    
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import lombok.ToString;
    
    @Data
    @ToString
    @NoArgsConstructor
    public class User {
    
        private Long id;
        private String name;
        private Integer age;
    
        public User(Long id, String name, Integer age) {
            this.id = id;
            this.name = name;
            this.age = age;
        }
    }
    

    1.4 UserMapper 数据化持久层

    package com.plumblossom.springboottransaction.mapper;
    
    import com.plumblossom.springboottransaction.bean.User;
    import org.apache.ibatis.annotations.Insert;
    import org.apache.ibatis.annotations.Mapper;
    import org.apache.ibatis.annotations.Param;
    import org.apache.ibatis.annotations.Select;
    
    @Mapper
    public interface UserMapper {
    
        // 查询指定姓名的用户
        @Select("select * from user where name=#{name}")
        User findUserByName(@Param("name") String n);
    
        // 向数据库中插入用户
        @Insert("insert into user(name,age) values(#{name},#{age})")
        int insertUser(@Param("name") String name, @Param("age") Integer age);
    
    }
    

    1.5 编写测试用例对上面这种方式进行测试

    package com.plumblossom.springboottransaction.mapper;
    
    import com.plumblossom.springboottransaction.bean.User;
    import lombok.extern.slf4j.Slf4j;
    import org.assertj.core.api.Assertions;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.annotation.Rollback;
    
    
    @Slf4j
    @SpringBootTest
    public class UserMapperTest {
    
        @Autowired
        private UserMapper userMapper;
    
        @Test
        @Rollback
        public void testUserMapperInsert(){
            userMapper.insertUser("张三", 23);
            User user = userMapper.findUserByName("张三");
            log.info(user.toString());
            Assertions.assertThat(user.getAge()).isEqualTo(23);
    
        }
    
    }
    

    执行代码日志打印结果

    2020-09-28 16:37:25.288  INFO 5344 --- [ main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
    2020-09-28 16:37:25.621  INFO 5344 --- [ main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
    2020-09-28 16:37:25.805  INFO 5344 --- [ main] c.p.s.mapper.UserMapperTest              : User(id=1, name=张三, age=23)
    

    可以看到成功的执行了,但是此处还有一个注意点:

    SpringBoot2.x 中默认使用的是hikari.HikariDataSource 数据源,SpringBoot1.x 网上说使用的是TomcatDataSource

    拓展思考点: 如何更换数据源,还有这个数据源是怎么被SpringBoot 管理的

    1. SpringBoot整合MyBatis 【xml 配置文件方式】

    2.1 application.properties 配置文件中的内容

    # MyBatis 配置
    mybatis.type-aliases-package=com.plumblossom.springboottransaction.bean
    # 指定Mybatis 配置文件,应该也可以使用Configuration 配置类的方式进行配置
    mybatis.config-location=classpath:mybatis/mybatis-config.xml
    # 指定Mapper配置文件的路径,也可以使用Configuration 配置类的方式进行配置
    mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
    
    
    # 数据库连接配置
    spring.datasource.url=jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF8&serverTimezone=UTC
    spring.datasource.username=root
    spring.datasource.password=123321
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    

    2.2 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>
        <typeAliases>
            <typeAlias alias="Integer" type="java.lang.Integer" />
            <typeAlias alias="Long" type="java.lang.Long" />
            <typeAlias alias="HashMap" type="java.util.HashMap" />
            <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" />
            <typeAlias alias="ArrayList" type="java.util.ArrayList" />
            <typeAlias alias="LinkedList" type="java.util.LinkedList" />
        </typeAliases>
    </configuration>
    

    2.3 UserMapper配置文件

    <?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.plumblossom.springboottransaction.mapper.UserMapper" >
    
        <resultMap id="BaseResultMap" type="com.plumblossom.springboottransaction.bean.User" >
            <id column="id" property="id" jdbcType="VARCHAR" />
            <result column="name" property="name" jdbcType="VARCHAR" />
            <result column="age" property="age" jdbcType="INTEGER" />
        </resultMap>
    
        <sql id="Base_Column_List" >
            id, name, age
        </sql>
    
    
        <select id="findUserByName" parameterType="java.lang.String" resultMap="BaseResultMap" >
            SELECT
            <include refid="Base_Column_List" />
            FROM
            user
            WHERE name = #{name}
        </select>
    
        <insert id="insertUser" >
    
            INSERT INTO
            user
            (name, age)
            VALUES
            ( #{name}, #{age})
        </insert>
    
    
    </mapper>
    

    2.4 UserMapper.Java的文件内容

    import com.plumblossom.springboottransaction.bean.User;
    import org.apache.ibatis.annotations.Mapper;
    import org.apache.ibatis.annotations.Param;
    
    
    @Mapper
    public interface UserMapper {
    
        User findUserByName(@Param("name") String n);
    
        int insertUser(@Param("name") String name, @Param("age") Integer age);
    
    }
    

    2.5 使用测试用例执行测试

    package com.plumblossom.springboottransaction.mapper;
    
    import com.plumblossom.springboottransaction.bean.User;
    import lombok.extern.slf4j.Slf4j;
    import org.assertj.core.api.Assertions;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.annotation.Rollback;
    
    @Slf4j
    @SpringBootTest
    public class UserMapperTest {
    
        @Autowired
        private UserMapper userMapper;
    
        @Test
        @Rollback
        public void testUserMapperInsert(){
            userMapper.insertUser("李四", 55);
            User user = userMapper.findUserByName("李四");
            log.info(user.toString());
            Assertions.assertThat(user.getAge()).isEqualTo(55);
    
        }
    
    }
    

    执行测试结果

    2020-09-28 17:20:28.254  INFO 17148 --- [main] com.zaxxer.hikari.HikariDataSource  : HikariPool-1 - Starting...
    2020-09-28 17:20:28.527  INFO 17148 --- [main] com.zaxxer.hikari.HikariDataSource  : HikariPool-1 - Start completed.
    2020-09-28 17:20:28.706  INFO 17148 --- [main] c.p.s.mapper.UserMapperTest : User(id=2, name=李四, age=55)
    

    注意点: 这两种Dao 数据持久层的接口,我都使用了@Mapper 这个注解,他的作用就是在代码编译过后会生成相应的接口实现类,这种方式是官方推荐的。这里只有一个接口文件,如果有非常多的接口,在每一个上面标注上这个注解,也是一件麻烦的事情。所以还有另一个注解@MapperScan(packageName) 在SpringBoot的启动类上标注上这个注解,就会直接扫描指定包下的接口并生成实现类。

    3 SpringBoot 整合MyBatis 原理

    3.1 SpringBoot 能够整合MyBatis的原因

    主要是org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration 这个类在起作用

    在以前学习spring整合与mybatis整合的时候,需要我们自己配置两个Bean 一个是sqlSessionFactoryBean,还有一个是MapperScanner,在Springboot中这两个Bean不需要我们提供了,但并不是意味着这两个Bean不需要了

    @Configuration
    @ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
    @ConditionalOnSingleCandidate(DataSource.class)
    @EnableConfigurationProperties({MybatisProperties.class})
    @AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class})
    public class MybatisAutoConfiguration implements InitializingBean {
        private static final Logger logger = LoggerFactory.getLogger(MybatisAutoConfiguration.class);
        private final MybatisProperties properties;
        private final Interceptor[] interceptors;
        private final TypeHandler[] typeHandlers;
        private final LanguageDriver[] languageDrivers;
        private final ResourceLoader resourceLoader;
        private final DatabaseIdProvider databaseIdProvider;
        private final List<ConfigurationCustomizer> configurationCustomizers;
    
      
    
        @Bean
        @ConditionalOnMissingBean
        public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
            SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
            factory.setDataSource(dataSource);
            factory.setVfs(SpringBootVFS.class);
            if (StringUtils.hasText(this.properties.getConfigLocation())) {
                factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
            }
    
            this.applyConfiguration(factory);
            if (this.properties.getConfigurationProperties() != null) {
                factory.setConfigurationProperties(this.properties.getConfigurationProperties());
            }
    
            if (!ObjectUtils.isEmpty(this.interceptors)) {
                factory.setPlugins(this.interceptors);
            }
    
            if (this.databaseIdProvider != null) {
                factory.setDatabaseIdProvider(this.databaseIdProvider);
            }
    
            if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
                factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
            }
    
            if (this.properties.getTypeAliasesSuperType() != null) {
                factory.setTypeAliasesSuperType(this.properties.getTypeAliasesSuperType());
            }
    
            if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
                factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
            }
    
            if (!ObjectUtils.isEmpty(this.typeHandlers)) {
                factory.setTypeHandlers(this.typeHandlers);
            }
    
            if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
                factory.setMapperLocations(this.properties.resolveMapperLocations());
            }
    
            Set<String> factoryPropertyNames = (Set)Stream.of((new BeanWrapperImpl(SqlSessionFactoryBean.class)).getPropertyDescriptors()).map(FeatureDescriptor::getName).collect(Collectors.toSet());
            Class<? extends LanguageDriver> defaultLanguageDriver = this.properties.getDefaultScriptingLanguageDriver();
            if (factoryPropertyNames.contains("scriptingLanguageDrivers") && !ObjectUtils.isEmpty(this.languageDrivers)) {
                factory.setScriptingLanguageDrivers(this.languageDrivers);
                if (defaultLanguageDriver == null && this.languageDrivers.length == 1) {
                    defaultLanguageDriver = this.languageDrivers[0].getClass();
                }
            }
    
            if (factoryPropertyNames.contains("defaultScriptingLanguageDriver")) {
                factory.setDefaultScriptingLanguageDriver(defaultLanguageDriver);
            }
    
            return factory.getObject();
        }
    
       
    
        @Bean
        @ConditionalOnMissingBean
        public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
            ExecutorType executorType = this.properties.getExecutorType();
            return executorType != null ? new SqlSessionTemplate(sqlSessionFactory, executorType) : new SqlSessionTemplate(sqlSessionFactory);
        }
    
        @Configuration
        @Import({MybatisAutoConfiguration.AutoConfiguredMapperScannerRegistrar.class})
        @ConditionalOnMissingBean({MapperFactoryBean.class, MapperScannerConfigurer.class})
        public static class MapperScannerRegistrarNotFoundConfiguration implements InitializingBean {
            public MapperScannerRegistrarNotFoundConfiguration() {
            }
    
            public void afterPropertiesSet() {
                MybatisAutoConfiguration.logger.debug("Not found configuration for registering mapper bean using @MapperScan, MapperFactoryBean and MapperScannerConfigurer.");
            }
        }
    
       
    }
    

    未完。

  • 相关阅读:
    翻译:让网络更快一些——最小化浏览器中的回流(reflow)
    ArcGIS API for flex 3.1离线文档
    innerHeight与clientHeight、innerWidth与clientWidth
    在Excel2010中输入身份证号
    JavaScript window.location对象
    Apache2.2+php5.2+the requested operation has failed
    Js中的window.parent ,window.top,window.self
    Mongoose 3.0 executable does not start
    Download ActionScript 3 reference files as a single zipActionScript 3 下载
    Flex 4.6 API 离线文档
  • 原文地址:https://www.cnblogs.com/kangxinxin/p/13747113.html
Copyright © 2011-2022 走看看