一、Mybatis学习实践-搭建运行环境

仓库

文章涉及的代码都将统一存放到此仓库,文章涉及的案例代码存放在包:com.hzchendou.blog.demo.example下

代码地址:Gitee

分支:lesson1

涉及案例:Case1

 简介

Mybatis 是一款优秀的持久层框架,使用Mybatis框架,开发者只需要编写SQL语句以及POJO类,Mybatis将自动完成连接管理、事务管理、SQL操作、结果集映射(将ResultSet转化为Java对象)等操作,同时提供高级特性,如:插件、自定义驱动语言等。学习并掌握Mybatis将帮助我们编写高效运行的程序代码。为了更好的学习Mybatis,我们将搭建一个Mybatis项目,只提供Mybatis运行环境,同时使用嵌入式数据库SQLite(方便随时运行案例)。

基础配置

依赖配置

配置Pom文件,加入Mybatis依赖,配置如下:

<dependency>
   <groupId>org.mybatis</groupId>
   <artifactId>mybatis</artifactId>
   <version>3.5.10</version>
</dependency>

引入SQLIte驱动,配置如下:

<dependency>
   <groupId>org.xerial</groupId>
   <artifactId>sqlite-jdbc</artifactId>
   <version>3.21.0.1</version>
</dependency>

为了更加直观的展示结果,需要引入日志功能(方便打印SQL语句以及相关执行结果),根据官方描述,Mybatis支持以下日志组件:

  • SLF4J
  • Apache Commons Logging
  • Log4j 2
  • Log4j (3.5.9 起废弃)
  • JDK logging

我们采用SLF4j + Logback日志组合, 配置如下:

<dependency>
   <groupId>ch.qos.logback</groupId>
   <artifactId>logback-classic</artifactId>
   <version>${logback.version}</version>
</dependency>
<dependency>
   <groupId>ch.qos.logback</groupId>
   <artifactId>logback-core</artifactId>
   <version>${logback.version}</version>
</dependency>
<dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-api</artifactId>
   <version>${slf4j.version}</version>
</dependency>

博客案例

Mybatis 是持久层框架,提供数据库操作功能,我们将博客系统作为教学实践案例,后续文章也都围绕博客进行教学实践,博客主要功能是发表文章,文章包含以下两个基础内容:

  1. 文章
  2. 作者

文章包含以下属性(尽可能简化):

  • id
  • 文章标题
  • 文章作者
  • 文章标签
  • 文章状态

作者包含以下属性(尽可能简化):

  • id
  • 用户名
  • 备注

Mybatis博客配置

Mybatis配置文件

mybatis的配置文件功能强大,涉及的内容非常多,有兴趣的可以去官网了解各个配置信息,在此只提供基础配置,配置文件如下所示:

<?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="username" value=""/>
    <property name="password" value=""/>
    <property name="url" value="jdbc:sqlite:./src/main/resources/database/sqlite.db"/>
    <property name="driver" value="org.sqlite.JDBC"/>
  </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>
  <!-- mapper配置 -->
  <mappers>
    <mapper resource="mapper/BlogMapper.xml"/>
    <mapper resource="mapper/AuthorMapper.xml"/>
  </mappers>
</configuration>

数据库表配置

Mybatis是半自动ORM,需要开发者提供SQL语句。数据库中的每一张表对应Mybatis中的三个文件:

  • xxxxDO(数据模型,将表记录转化为POJO对象方便程序处理)
  • Mapper接口(为Java程序提供SQL操作接口,方便程序调用)
  • Mapper XML文件(与Mapper接口对应,为Mapper接口中的每一个方法提供对应的SQL语句)

现在以文章为例,定义DO模型如下:

/**
 * 博文DO
 */
@Data
public class BlogDO {

    /**
     * 文章ID
     */
    private Integer id;
    /**
     * 文章标题
     */
    private String title;
    /**
     * 文章作者Id
     */
    private Integer authorId;
    /**
     * 标签列表
     */
    private String tags;
    /**
     * 文章状态
     */
    private Integer status;
}

Mapper接口如下:

/**
 * 博文信息Mapper
 */
public interface BlogMapper {

    /**
     * 查询所有记录
     *
     * @return
     */
    List<BlogDO> selectAll();

    /**
     * 添加记录
     *
     * @param blogDO
     * @return
     */
    int insert(BlogDO blogDO);
}

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.hzchendou.blog.demo.mapper.BlogMapper">
  <resultMap id="blogDO" type="com.hzchendou.blog.demo.entity.BlogDO">
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="title" jdbcType="VARCHAR" property="title" />
    <result column="author_id" jdbcType="INTEGER" property="authorId" />
    <result column="tags" jdbcType="VARCHAR" property="tags" />
    <result column="status" jdbcType="INTEGER" property="status" />
  </resultMap>
  <sql id="blog_columns">
    id, `title`, `author_id`, `tags`, `status`
  </sql>

  <!-- 对应Mapp二接口中的 selectAll方法-->
  <select id="selectAll" resultMap="blogDO">
    SELECT <include refid="blog_columns"/> FROM blog
  </select>
  
  <!-- 对应Mapp二接口中的 insert-->
  <insert id="insert" parameterType="com.hzchendou.blog.demo.entity.BlogDO" useGeneratedKeys="true" keyProperty="id">
    insert into blog(`title`, `author_id`, `tags`, `status`)
    values (#{title,jdbcType=VARCHAR}, #{authorId,jdbcType=INTEGER}, #{tags,jdbcType=VARCHAR}, #{status,jdbcType=INTEGER})
  </insert>
</mapper>

程序运行

使用上述配置也就完成了Mybatis项目搭建,我们假设要在数据库中创建一篇文章,同时创建文章作者记录:

public void run() throws IOException {
    /// 读取配置文件,初始化mybatis
    String resource = "mybatis.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    /// 创建SqlSession工厂对象,方便后续创建SqlSession,使用SqlSession操作数据库
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    /// 使用Java 7提供的 try-with-resource写法,让JVM自动完成资源关闭操作
   try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
         获取Mapper接口示例(底层使用了JDK的Proxy.newProxyInstance方法创建代理)
        BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
         创建博文记录
        BlogDO blog = new BlogDO();
        blog.setTitle("时间海绵博文");
        blog.setAuthorId(1);
        blog.setTags("博文、时间海绵");
        blog.setStatus(1);
        int res = blogMapper.insert(blog);
        log.info("创建时间海绵博文结果: {}", res);
        /// 需要提交事务确保提交成功,只有提交了事务才能在数据库中正确插入数据
        sqlSession.commit();

         查询文章记录
        List<BlogDO> blogs = blogMapper.selectAll();
        log.info("博文信息列表: {}", blogs);

         获取Mapper接口示例(底层使用了JDK的Proxy.newProxyInstance方法创建代理)
        AuthorMapper authorMapper = sqlSession.getMapper(AuthorMapper.class);
        /// 创建文章作者记录
        AuthorDO authorDO = new AuthorDO();
        authorDO.setId(1);
        authorDO.setUsername("时间海绵");
        authorDO.setRemark("不知名博主");
        res = authorMapper.insert(authorDO);
        log.info("创建时间海绵作者结果: {}", res);
        /// 查询所有作者信息
        List<AuthorDO> authors = authorMapper.selectAll();
        log.info("作者信息列表: {}", authors);
        sqlSession.commit();
    }
}

运行上述程序,得到如下结果:

 使用Slf4j日志组件进行日志初始化,符合预期
15:34:10.195 [main] DEBUG org.apache.ibatis.logging.LogFactory - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
 使用数据库连接池方式管理连接
15:34:10.213 [main] DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
15:34:10.213 [main] DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
15:34:10.213 [main] DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
15:34:10.213 [main] DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
15:34:10.313 [main] DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction - Opening JDBC Connection
15:34:10.772 [main] DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - Created connection 1391942103.
 注意这里将 autocommit 设置为 false,因此程序中需要显示调用commit方法提交事务,否则SQL更新操作将不成功
15:34:10.772 [main] DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction - Setting autocommit to false on JDBC Connection [org.sqlite.SQLiteConnection@52f759d7]
 插入文章记录
15:34:10.774 [main] DEBUG com.hzchendou.blog.demo.mapper.BlogMapper.insert - ==>  Preparing: insert into blog(`title`, `author_id`, `tags`, `status`) values (?, ?, ?, ?)
15:34:10.790 [main] DEBUG com.hzchendou.blog.demo.mapper.BlogMapper.insert - ==> Parameters: 时间海绵博文(String), 1(Integer), 博文、时间海绵(String), 1(Integer)
15:34:10.791 [main] DEBUG com.hzchendou.blog.demo.mapper.BlogMapper.insert - <==    Updates: 1
15:34:10.794 [main] INFO com.hzchendou.blog.demo.example.Case1 - 创建时间海绵博文结果: 1
 提交事务,对应代码中的 sqlSession.commit()操作
15:34:10.795 [main] DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction - Committing JDBC Connection [org.sqlite.SQLiteConnection@52f759d7]
15:34:10.798 [main] DEBUG com.hzchendou.blog.demo.mapper.BlogMapper.selectAll - ==>  Preparing: SELECT id, `title`, `author_id`, `tags`, `status` FROM blog
15:34:10.798 [main] DEBUG com.hzchendou.blog.demo.mapper.BlogMapper.selectAll - ==> Parameters: 
15:34:10.808 [main] DEBUG com.hzchendou.blog.demo.mapper.BlogMapper.selectAll - <==      Total: 4
15:34:10.809 [main] INFO com.hzchendou.blog.demo.example.Case1 - 博文信息列表: [BlogDO(id=1, title=时间海绵博文, authorId=1, tags=博文、时间海绵, status=1), BlogDO(id=2, title=时间海绵博文, authorId=1, tags=博文、时间海绵, status=1), BlogDO(id=3, title=时间海绵博文, authorId=1, tags=博文、时间海绵, status=1), BlogDO(id=4, title=时间海绵博文, authorId=1, tags=博文、时间海绵, status=1)]
15:34:10.810 [main] DEBUG com.hzchendou.blog.demo.mapper.AuthorMapper.insert - ==>  Preparing: insert into author(`username`, `remark`) values (?, ?)
15:34:10.810 [main] DEBUG com.hzchendou.blog.demo.mapper.AuthorMapper.insert - ==> Parameters: 时间海绵(String), 不知名博主(String)
15:34:10.810 [main] DEBUG com.hzchendou.blog.demo.mapper.AuthorMapper.insert - <==    Updates: 1
15:34:10.810 [main] INFO com.hzchendou.blog.demo.example.Case1 - 创建时间海绵作者结果: 1
15:34:10.810 [main] DEBUG com.hzchendou.blog.demo.mapper.AuthorMapper.selectAll - ==>  Preparing: SELECT id, `username`, `remark` FROM `author`
15:34:10.811 [main] DEBUG com.hzchendou.blog.demo.mapper.AuthorMapper.selectAll - ==> Parameters: 
15:34:10.811 [main] DEBUG com.hzchendou.blog.demo.mapper.AuthorMapper.selectAll - <==      Total: 3
15:34:10.811 [main] INFO com.hzchendou.blog.demo.example.Case1 - 作者信息列表: [AuthorDO(id=1, username=时间海绵, remark=不知名博主), AuthorDO(id=2, username=时间海绵, remark=不知名博主), AuthorDO(id=3, username=时间海绵, remark=不知名博主)]
15:34:10.811 [main] DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction - Committing JDBC Connection [org.sqlite.SQLiteConnection@52f759d7]
15:34:10.812 [main] DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction - Resetting autocommit to true on JDBC Connection [org.sqlite.SQLiteConnection@52f759d7]
15:34:10.812 [main] DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction - Closing JDBC Connection [org.sqlite.SQLiteConnection@52f759d7]
 Pool类型数据源,SQLSession的关闭操作会将使用的connect连接返回到连接池中,方便后续业务继续使用
15:34:10.812 [main] DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - Returned connection 1391942103 to pool.

总结

我们基于博客案例搭建了一套最基础的Mybatis项目,为此我们做了以下工作:

  • 引入基础依赖保障Mybatis能够运行
    • mybatis 依赖
    • sqlite 驱动依赖
    • 日志依赖
    • lombok依赖(注解形式编写setter、getter方法)
  • Mybatis配置文件
    • JDBC事务
    • JDBC数据源
    • mapper xml文件
  • Mapper接口(方便Java程序操作数据库,而不是调用JDBC操作数据库)
  • DO数据模型(方便业务使用数据库中的记录,Mybatis将自动完成数据库记录到DO数据模型的映射操作,当然映射规则需要指定,也可以开启默认规则)
  • Mapper XML文件(提供SQL,Mapper接口中的方法底层都是调用SQL语句完成数据库操作,这些SQL语句就是在XML文件中定义的,通过命名空间 + id(方法名)的方式进行一一对应)

参考文档

联系方式

技术更新换代速度很快,我们无法在有限时间掌握全部知识,但我们可以在他人的基础上进行快速学习,学习也是枯燥无味的,加入我们学习牛人经验:

QQ:901856121

点击:加群讨论 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值