MyBatis的几种使用形式。

一、概要

    下文意在描述MyBatis的几种使用方式,涵盖了如何使用xml配置的方式连接数据库,此外还有如何使用不包含xml配置的方式连接数据库,最后结合Spring来连接数据库。

二、缘由

    我个人认为还是有必要说下缘由的,不然单纯写一篇技术入门随笔简直是浪费时间,同时也是方便未来回忆场景。2020年的今天java体系内大多数公司都开始使用SpringBoot来开发项目,但是我手上还在维护一个老的SpringMVC+Mybatis的项目,基于公司内部技术统一的考虑,还有技术人耿直,我打算以最小的改动将项目迁到SpringBoot上,中间遇到了很多问题其中一项就是Mybatis的配置,使用习惯了spring-boot-start-*的便利,一时竟然搞不定这一堆繁琐的xml配置,于是决定重新梳理下MyBatis,以便迁移配置的时候有理有据不自乱阵脚。

三、Mybatis几种使用形式

1. 最原始的xml配置的形式。

XmlMain.java : 入口方法 

Blog.java : 数据库对应的实体类

BlogMapper.xml : xml 配置的sql

mybatis-config.xml :MyBatis的配置文件

public class XmlMain {
    public static void main(String[] args) {
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession session = sqlSessionFactory.openSession();
            
            Blog blog = (Blog) session.selectOne("com.wx.test.mybatis.mapper.BlogMapper.selectBlog", 1);
            System.out.println(blog.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
XmlMain.java
public class Blog {
    private Integer id;
    private String userName;
    private Timestamp date;
    private Integer score;
  
    //todo getter and setter  或者使用Lombok
}
Blog.java
<?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.wx.test.mybatis.mapper.BlogMapper">
    <resultMap id="blog" type="com.wx.test.mybatis.entity.Blog">
        <result property="id" column="ID"/>
        <result property="userName" column="username"/>
        <result property="date" column="date"/>
        <result property="score" column="score"/>
    </resultMap>

    <select id="selectBlog" resultMap="blog" parameterType="int">
    select * from a_user where id = #{id}
  </select>
</mapper>
BlogMapper.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>
    <properties>
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/order?allowMultiQueries=true"/>
        <property name="username" value="root"/>
        <property name="password" value="1234"/>
    </properties>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mapper/BlogMapper.xml"/>
    </mappers>
</configuration>
mybatis-config.xml

 

xml形式小结,这是MyBatis最开始设计的初衷。将sql编写抽离出来,在独立的一个xml文件中按一定格式编写,然后交由内部执行器执行。我个人认为上面最核心的代码 是  Blog blog = (Blog) session.selectOne("com.wx.test.mybatis.mapper.BlogMapper.selectBlog", 1);  (当然MyBatis官网认为SqlSessionFactory是最核心的)MyBatis内部会在恰当的时间将BlogMapper.xml 内的sql加载到内存中,并将每一个sql块以Statement保存起来。这行代码主要目的就是指定执行的Statement是哪一个,然后让session去执行。

 

2. 不以xml配置的方式

先说下我的理解:不以xml配置的方式就是去掉 mybatis-config.xml 和 BlogMapper.xml,用BlogMapper.java加上注解sql来替代。

理解的依据:我在官网上了解到只有两种形式构建SqlSessionFactory,一种是在mybatis-config.xml中配置好Configuration,然后通过流的方式读入配置文件,构建出SqlSessionFactory(即第一种方式);另一种是通过MyBatis提供的配置类自己实例化(这里涉及到BlogMapper.java,而非BlogMapper.xml) 。我没有找到仅去除mybatis-config.xml 而保留 BlogMapper.xml 的方式(这种方式我卡在了如何给Configuration设置xml路径的问题上,如果读者了解相关解法,欢迎指教)。

类文件说明:

MainTest.java : 入口文件

BlogMapper.java : 接口用来支撑注解sql

Blog.java : 实体同上

public class MainTest {
    public static void main(String[] args) {
        DataSource dataSource = getDataSource();
        TransactionFactory transactionFactory = new JdbcTransactionFactory();
        Environment environment = new Environment("development", transactionFactory, dataSource);
        Configuration configuration = new Configuration(environment);
        configuration.addMappers("com.wx.test.mybatis.mapper");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);

        try (SqlSession session = sqlSessionFactory.openSession()) {
            BlogMapper mapper = session.getMapper(BlogMapper.class);
            Blog blog = mapper.selectBlog(1);
            System.out.println("[RESULT]-------" + blog.toString());
        }
    }

    private static DataSource getDataSource() {
        Properties properties = new Properties();
        properties.put("driver", "com.mysql.jdbc.Driver");
        properties.put("url", "jdbc:mysql://localhost:3306/order?allowMultiQueries=true");
        properties.put("username", "root");
        properties.put("password", "1234");

        PooledDataSourceFactory pooledDataSourceFactory = new PooledDataSourceFactory();
        pooledDataSourceFactory.setProperties(properties);
        return pooledDataSourceFactory.getDataSource();
    }
}
MainTest.java
public interface BlogMapper {

    @Select("select * from a_user where id = 1")
    Blog selectBlog(int i);
}
BlogMapper.java

 

非xml形式小结: 这样下来三个文件就搞定了,纯java代码简洁了不少,不过似乎和我预想的还是不太一样,我印象中既可以用BeanMapper.java的反射特性,也可以同时结合xml的处理复杂sql的优势,那么是不是还有别的方式。

maven依赖说明:上面两种方式是只引入 mybatis.jar,主要的依赖如下

<dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.4</version>
</dependency>
<!-- 驱动 -->
<dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.17</version>
</dependency>
pom.xml

 

3. MyBatis-Spring 形式

 使用mybatis-spring-2.0.5.jar 我发现解决了我第二种方式的问题,既可以使用反射特性,又可以结合xml的sql配置文件解决复杂sql的优势,同时还去除了mybatis-confiration.xml的配置。

MainTest.java : 入口文件

DatabaseConfig.java : java注解配置文件

BlogService.java : 主要是用来注入 BlogMapper.java对象,方便测试

Blog.java : 实体(同上)

BlogMapper.java : 接口用来支撑注解sql或者映射xml中sql(同上)

BlogMapper.xml :xml sql(同上)

public class MainTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(DatabaseConfig.class);

        BlogService blogService = ctx.getBean(BlogService.class);
        blogService.test();
    }
}
MainTest.java
@Configuration
@MapperScan("com.wx.test.mybatis.mapper")
public class DatabaseConfig {

    @Bean
    public BlogService blogService() {
        return new BlogService();
    }

    @Bean
    public SqlSessionFactory sqlSessionFactoryBean() throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource());

        Resource[] mapperXml = new PathMatchingResourcePatternResolver().getResources(
                "classpath" + ":mapper/*.xml");
        factoryBean.setMapperLocations(mapperXml);

        return factoryBean.getObject();
    }

    private DataSource dataSource() {
        Properties properties = new Properties();
        properties.put("driver", "com.mysql.jdbc.Driver");
        properties.put("url", "jdbc:mysql://localhost:3306/order?allowMultiQueries=true");
        properties.put("username", "root");
        properties.put("password", "1234");

        PooledDataSourceFactory pooledDataSourceFactory = new PooledDataSourceFactory();
        pooledDataSourceFactory.setProperties(properties);
        return pooledDataSourceFactory.getDataSource();
    }
}
DatabaseConfig.java
@Component
public class BlogService {

    @Autowired
    private BlogMapper blogMapper;

    public void test() {
        Blog blog = blogMapper.selectBlog(1);
        System.out.println("[TEST]-------" + blog.toString());
    }
}
BlogService.java

 

说下maven依赖。因为引入了Spring的工厂,所以额外加入了Spring的包,我在里面没有标注,如果想要测试可以直接引入spring-context这个jar包就行。我是spring-boot工程,所以测试的是有用的是 spring-boot-start-web,这个看个人具体的使用的。

<dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>2.0.5</version>
</dependency>
<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.2.2.RELEASE</version>
</dependency>
pom.xml

 

四、总结

 到这里我已经清楚之前的项目是使用的第一种方式,和我预想的还是不太一样。后续我准备分两步去做。首先会先按照第一方式迁到spring-boot工程,之后在找时间改成maybatis-spring的形式。原因也很简单,第二种直接在mapper中注解的形式肯定是不满足业务的。第三种需要花时间去改造所有的BeanMapper.java,这个不太现实----懒(文中有什么不对的地方欢迎各路大神指正)。

 

五、番外篇---- mybatis-spring-boot

BlogMapper.xml (同上)

Blog.java (同上)

BlogMapper.java (同上)

@RestController
public class BlogController {

    @Autowired
    private BlogService blogService;

    @GetMapping("/test")
    public void test() {
        blogService.test();
    }
}
BlogController.java
@Service
public class BlogService {
    @Autowired
    private BlogMapper blogMapper;

    public void test() {
        Blog blog = blogMapper.selectBlog(1);
        System.out.println(blog.toString());
    }
}
BlogService.java
spring:
  application:
    name: mybatis-server
  datasource:
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/gemini_bet?allowMultiQueries=true&useUnicode=true&characterEncoding=utf8
    username: root
    password: 1234

server:
  port: 8081

mybatis:
  type-aliases-package: com.wx.entity
  mapper-locations: classpath:mapper/*.xml
application.yml
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.3.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
            <version>2.3.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.17</version>
        </dependency>
pom.xml

 

小结:mybatis-spring-boot-start 使用起来就超级简洁了,没有了之前xml或者java等一些列繁杂的SqlssessionFactory配置。直接在yml配置一些东西就好了,这就是大名鼎鼎的约定大于配置。其实配置还在,只不过通过自动装配的思想剥离到了mybatis-spring-boot-start 中。

 

 

 

 


 
posted @ 2020-08-30 11:31  小祥工作室  阅读(672)  评论(0编辑  收藏  举报