2 minute read

在实际项目中,Mybatis通常是与Spring Boot相结合的,Spring Boot帮我们做了大量自动化配置。 这次我们仅仅使用maven来构建Mybatis项目,学习Mybatis的用法。

maven依赖

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.6</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.23</version>
</dependency>

配置XML

Mybatis的核心是SqlSessionFactory,而SqlSessionFactory是通过SqlSessionFactoryBuilder获得。 SqlSessionFactoryBuilder则需要从XML文件或Configuration实例中获得。我们选择使用XML。在resources目录下 创建mybatis-config.xml。driver里填入驱动,这边使用的是MySQL数据库,所以是com.mysql.cj.jdbc.Driver。url、username、password是数据库信息。

<?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>
  <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="com/hunter/mapper/ArticleMapper.xml"/>
  </mappers>
</configuration>

构建SqlSessionFactoryBuilder以及SqlSessionFactory

在项目下面建一个Main类

public class Main {
    public static void main(String[] args) throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //通过Builder获得Factory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //获得SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        ArticleMapper mapper = sqlSession.getMapper(ArticleMapper.class);
        List<Article> allArticles = mapper.getAllArticles();
        System.out.println(allArticles);
        sqlSession.close();
    }
}

Article类

public class Article {
    private Integer id;
    private String name;
    private Integer watch;
    private Boolean enabled;

    @Override
    public String toString() {
        return "Article{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", watch=" + watch +
                ", enabled=" + enabled +
                '}';
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getWatch() {
        return watch;
    }

    public void setWatch(Integer watch) {
        this.watch = watch;
    }

    public Boolean getEnabled() {
        return enabled;
    }

    public void setEnabled(Boolean enabled) {
        this.enabled = enabled;
    }
}

ArticleMapper

public interface ArticleMapper {
    List<Article> getAllArticles();
}

相应的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.hunter.mapper.ArticleMapper">
    <select id="getAllArticles" resultType="com.hunter.model.Article">
        select * from article
    </select>
</mapper>

启动项目,发现报错了。

https://www.hualigs.cn/image/6064284b5e426.jpg

这是一个新手非常容易犯的错误,问题不在于Mybatis而是Maven。可以看项目编译后的结果,配置的xml文件不见了, 因为默认Maven会过滤java包里的除java之外的文件。

QQ图片20210331155518.png

解决方法有2个

  1. 修改Maven配置
     <build>
         <resources>
             <resource>
                 <directory>src/main/java</directory>
                 <includes>
                     <include>**/*.xml</include>
                 </includes>
             </resource>
             <resource>
                 <directory>src/main/resources</directory>
             </resource>
         </resources>
     </build>
    

    OK,修改完之后发现可以查出结果了

    https://i.loli.net/2021/03/31/42icV5sCIjUkma8.png

  2. 把xml放到resources包下面,同时记得修改Mybatis配置文件的mapper位置

    https://i.loli.net/2021/03/31/dyNEIgKeBZo1FOu.png

    OK,发现也能查询出结果。

项目改进

接下来我们需要对项目进行改进

  1. 首先是配置,如果每次新增一个mapper都要在这里加,过于麻烦。

     <mappers>
       <mapper resource="com/hunter/mapper/ArticleMapper.xml"/>
     </mappers>
    

    我们采用统一的包扫描,这样只要在这个包下面新增mapper.xml,就会自动识别

     <mappers>
         <package name="com.hunter.mapper"/>
     </mappers>
    
  2. Factory是由Builder构造的,采用一个静态单例模式创造

     public class SqlSessionFactoryUtil {
         private static SqlSessionFactory FACTORY = null;
        
         public static SqlSessionFactory getInstance() {
             if (FACTORY == null) {
                 try {
                     return new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
                 } catch (IOException e) {
                     e.printStackTrace();
                 }
             }
             return FACTORY;
         }
     }
    

    这样我们的Main方法也变成了

     public class Main {
         public static void main(String[] args) throws IOException {
             SqlSessionFactory factory = SqlSessionFactoryUtil.getInstance();
             SqlSession sqlSession = factory.openSession();
             ArticleMapper mapper = sqlSession.getMapper(ArticleMapper.class);
             List<Article> allArticles = mapper.getAllArticles();
             System.out.println(allArticles);
             sqlSession.close();
         }
     }
    
  3. 把Sql语句打印到控制台,方便调试。加入log4j相关依赖

     <dependency>
         <groupId>org.apache.logging.log4j</groupId>
         <artifactId>log4j-api</artifactId>
         <version>2.14.1</version>
     </dependency>
     <dependency>
         <groupId>log4j</groupId>
         <artifactId>log4j</artifactId>
         <version>1.2.17</version>
     </dependency>
     <dependency>
         <groupId>org.slf4j</groupId>
         <artifactId>slf4j-log4j12</artifactId>
         <version>RELEASE</version>
     </dependency>
    

    配置log4j

     ### 设置###
     log4j.rootLogger = debug,stdout
     ### 输出信息到控制抬 ###
     log4j.appender.stdout = org.apache.log4j.ConsoleAppender
     log4j.appender.stdout.Target = System.out
     log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
     log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
    

    OK,现在可以在控制台看到相关SQL语句了。

  4. 取别名

    在mybatis配置文件里,可以对类取别名,如

     <typeAliases>
         <typeAlias alias="Article" type="com.hunter.model.Article"/>
     </typeAliases>
    

    这样查询的时候可以不用全部输入了

     <select id="getAllArticles" resultType="Article">
         select * from article
     </select>