zoukankan      html  css  js  c++  java
  • 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 中。


     
  • 相关阅读:
    投资数据来源
    白酒
    医药
    农林牧渔
    软件IT
    基建
    ajax验证用户名 当用户名框的数据改变时 执行ajax方法
    jQuery load() 方法
    js各种验证文本框输入格式
    JAVASCRIPT技术 表达式验证
  • 原文地址:https://www.cnblogs.com/wangxiangstudy/p/13584027.html
Copyright © 2011-2022 走看看