前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >给“小白”漫画+图示讲解MyBatis原理,就问香不香!

给“小白”漫画+图示讲解MyBatis原理,就问香不香!

作者头像
码农神说
发布2020-08-05 15:43:44
4160
发布2020-08-05 15:43:44
举报
文章被收录于专栏:码农神说

MyBatis一款后起之秀的持久层框架ORM,支持自定义SQL、存储过程和高级映射,相对于Hibernate算是半自动化的框架,在国内行业内非常流行。

常规的JDBC操作,配置相应的数据库连接的信息,比如账户密码等,应用加载数据库驱动并手动创建数据库连接,编写业务sql并设置其入参生成Statement对象用于执行,获取结果数据集,及时释放持有资源,再对结果集进行数据处理。

加载驱动、创建连接、返回结果、释放资源等等都是重复的体力活,为了不把自己忙碌成代码的搬运工,这些都可以封装由框架去做,而自己关注最核心的业务层,也就是sql相关的逻辑。

把业务相关的sql逻辑配置在mapper.xml文件中,包括入参和返回的结果集,这其中会涉及到数据库中的字段和Java对象的字段之间的映射,一般如果字段名和类型相同可以通过MyBatis的自动映射即可,如果差别较大,则需要手动映射,甚至自定义类型处理typeHandlers。

每个MyBatis的应用都会以一个SqlSessionFacotry的实例为核心的,SqlSessionFacotryBuilder通过build加载核心配置文件mybatis-config.xml,从而创建SqlSessionFacotry,再由SqlSessionFacotry创建SqlSession。

核心配置文件mybatis-config.xml包含mapper.xml文件,在SqlSessionFacotryBuilder加载核心配置文件时一同加载进来,形成Configuration实例,其中mapper.xml的每个select/update/insert/delete节点都会最终生成MappedStatement对象,简单理解就是对应的完整sql语句,类似JDBC的Statement角色。

实际上核心配置文件除了包含mapper.xml,还包含数据库连接、事务、类型别名、类型处理器、插件、环境配置等等。

1

准备工作:创建数据库和项目

创建数据库脚本

代码语言:javascript
复制
CREATE DATABASE `mybatisdemo`;
USE mybatisdemo;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 

创建maven项目,并在pom中添加mybatis和mysql驱动依赖包

代码语言:javascript
复制
<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.5.5</version>
</dependency>
<dependency>
  <groupId>MySQL</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.40</version>
</dependency>

2

添加核心配置文件mybatis-config.xml

代码语言:javascript
复制
<?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="com.mysql.jdbc.Driver"/>
          <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatisdemo"/>
          <property name="username" value="root"/>
          <property name="password" value="123456"/>
      </dataSource>
    </environment>
  </environments>
  <!--引用mapper-->
  <mappers>
    <mapper resource="UserMapper.xml"></mapper>
  </mappers>
</configuration>

3

UserMapper.xml

的配置

包含了插入数据的insert和查询数据的select,其中插入式通过设置useGeneratedKeys为true,返回自增id。

代码语言:javascript
复制
<?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.zhaiqianfeng.user.UserMapper">
  <!--插入-->
  <insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
    insert into user(name) values(#{name})
  </insert>
  <!--查询-->
  <select id="getUserById" resultMap="userMap">
    select * from user where id = #{id}
  </select>
  <!--Java对象字段与数据库表字段的映射-->
  <resultMap id="userMap" type="com.zhaiqianfeng.user.User">
    <result property="id" column="id"></result>
    <result property="name" column="name"></result>
  </resultMap>
</mapper>

4

UserMapper.xml

相对应Dao

UserMapper.java的代码如下,包含了相应插入和查询接口

代码语言:javascript
复制
package com.zhaiqianfeng.user;

public interface UserMapper {
    User getUserById(int id);
    int insertUser(User user);
}

5

创建SqlSession并验证

一切都准备好之后,开始创建SqlSession并执行

代码语言:javascript
复制
public static void main( String[] args ) throws IOException {
  String config= "mybatis-config.xml";
  InputStream inputStream= Resources.getResourceAsStream(config);
  //SqlSessionFactoryBuilder加载核心(+mapper)配置文件并创建SqlSessionFactory
  SqlSessionFactory sqlSessionFactory= 
    new SqlSessionFactoryBuilder().build(inputStream);

  //创建SqlSession
  try(SqlSession sqlSession=sqlSessionFactory.openSession()) {
    //获取mapper
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    User user = new User();
    user.setName("chris");

    //执行操作
    mapper.insertUser(user);
    sqlSession.commit(); //flush
    System.out.println("获取自增id:" + user.getId());

    user = mapper.getUserById(user.getId());
    System.out.println("刚刚入库的user对象" + user);
  }
}

此时的项目结构是这样的

运行main之后打印

获取自增id:1 刚刚入库的user对象User(id=1, name=chris)

查看数据库

6

优化

由于本例中的数据库表字段和Java对象的字段名一致,所以在UserMapper.xml中的resultMap可以省略,直接用resultType,mybatis会悄悄自动映射生成resultMap,省略后如

代码语言:javascript
复制
<?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.zhaiqianfeng.user.UserMapper">
  <insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
    insert into user(name) values(#{name})
  </insert>
  <select id="getUserById" resultType="com.zhaiqianfeng.user.User">
    select * from user where id = #{id}
  </select>
</mapper>

还可以再简化,比如使用别名替换权限定名(com.zhaiqianfeng.user.User)等。

PS:本篇文章主要是通过漫画和图并结合对比常规JDBC来讲解MyBatis的原理和设计目标,比较适合新手阅读,感谢阅读。

源码地址:https://github.com/zhaiqianfeng/codeceo-demo/tree/master/mybatis/mybatis-demo-1

End

版权归@码农神说所有,转载须经授权,翻版必究

转载可联系助手,微信号:codeceo-01

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农神说 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档