初识MyBatis

建立mybatis工程

先不管什么原理不原理,上来就是干呀。

前期准备

建立一个空白的maven工程,添加依赖:

<dependencies>

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

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.16</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>LATEST</version>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.8</version>
    </dependency>


</dependencies>

最重要的就是mybatis与mysql依赖,其他的都可以不加入,但具体代码需你自己调整。

再建一张表,简单点就好

CREATE TABLE `fruits` (
`id` INT ( 11 ) NOT NULL AUTO_INCREMENT,
`fruits_name` VARCHAR ( 40 ) DEFAULT NULL,
`color` VARCHAR ( 20 ) DEFAULT NULL,
`weight` DOUBLE DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY ( `id` ) 
) ENGINE = INNODB AUTO_INCREMENT = 2 DEFAULT CHARSET = utf8mb4;

建表的时候想吃水果了,所以就建了这么个东西。再随便插入条数据:如

INSERT INTO `test`.`fruits`(`fruits_name`, `color`, `weight`, `created_at`) VALUES ('banana', 'green', 1234.2, '2019-06-18 16:16:35')

前期准备就算完成了。

写配置

本例中只关注mybatis,所以不会有与其他框架整合的配置。

配置与mysql的连接

先建个mysql.properties文件(这不是必须的,你可以直接写到mybatis的配置里去)
写(根据自己的情况修改):

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8&serverTimezone=UTC
username=root
password=root

下面就是真正的配置,建个mybatis-config.xml文件,写入:

<configuration>
    <!-- 引入外部配置文件 -->
    <properties resource="mysql.properties"></properties>
    <environments default="development">
        <environment id="development">
            <!-- type="JDBC" 代表使用JDBC的提交和回滚来管理事务 -->
            <transactionManager type="JDBC"/>
            <!-- mybatis提供了3种数据源类型,分别是:POOLED,UNPOOLED,JNDI -->
            <!-- POOLED 表示支持JDBC数据源连接池 -->
            <!-- UNPOOLED 表示不支持数据源连接池 -->
            <!-- JNDI 表示支持外部数据源连接池 -->
            <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>
</configuration>

建立表与实体的关系

建实体类

@Data
public class Fruits implements Serializable {
    private static final long serialVersionUID = 1L;
    private Integer id;

    private String fruitsName;

    private String color;

    private Double weight;

    private Date createdAt;

    private Date updatedAt;
}

lombok大法好呀~

建mapper接口

public interface FruitsMapper {
    
    Fruits selectById(Integer id);
}

建实体类的xml文件

resource文件夹下建mapperxml/FruitsMapper.xml文件:

<mapper namespace="com.llh.mybatis.mapper.FruitsMapper">
    <select id="selectById" resultType="com.llh.mybatis.pojo.Fruits">
        select * from fruits where id=#{id} ;
    </select>
</mapper>

至此所有的配置文件已经写完了。但是,因为这里只是用了mybatis单一框架,又把映射文件(FruitsMapper.xml)放在了自定义文件夹里,所以我们需要给mybatis指定这个文件位置。
打开mybatis-config.xml文件,在configuration标签内添加:

    <mappers>
         <mapper resource="mapperxml/FruitsMapper.xml"/>
    </mappers>

那么,无聊的配置工作就可以告一段落了。

构建查询

使用mybatis查询总的来说,就两步:

  1. 告诉mybatis我们写的配置
  2. 使用SqlSession对象进行查询
    如下代码:
 private SqlSessionFactory sqlSessionFactory;

    @Before
    public void config() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }
    @Test
    public void selectOne() {
        try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
            FruitsMapper mapper = sqlSession.getMapper(FruitsMapper.class);
            Fruits fruits = mapper.selectById(1);
            System.out.println(fruits);
        }
    }

如果一切顺利的话,你就可以看到打印出查询的结果了。
那么,我们费了这么大劲写的这个特简单东西到底有什么意思呢?
这个例子虽然简单,但它把mybatis核心组件都用上了。

MyBatis核心组件

从我们的代码来看:
首先是SqlSessionFactoryBuilder读取了配置文件,给我们返回了SqlSessionFactory对象,我们用SqlSessionFactory对象获取SqlSession对象,再由SqlSession对象去获取我们写的mapper接口,此时就可以使用mapper接口查询方法了。
所以整理出MyBatis核心组件:

  • SqlSessionFactoryBuilder:读配置文件生成SqlSessionFactory对象
  • SqlSessionFactory: 生成SqlSession对象
  • SqlSession:执行所写的mapper接口查询方法
    不少书认为sqlSession.getMapper这样的方法是使用了SQL Mapper组件,目前尚未看出这个组件在源码里有体现,暂议。不过这个方法确实是以前方法的改进。更老一点的查询方法:
 @Test
    public void selectOneOld() {
        try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
            Fruits fruits = sqlSession.selectOne("com.llh.mybatis.mapper.FruitsMapper.selectById", 1);
            System.out.println(fruits);
        }
    }

流程解读

流程.png

简书不支持时序图语法。
基本上一个查询的完整流程就是这样子。

后记

看到打印的结果你可能会奇怪为啥有些字段没值呢(如果你的代码与我保持一致的话)?
首先确认数据库里的值是否存在,如果存在,还是打印不出来的话,那就要来看看这个了。

自动映射

mybatis-config.xml文件里,properties标签之后(顺序很重要)添加:

    <settings>
        <setting name="autoMappingBehavior" value="NONE"/>
    </settings>

然后再次执行查询,你就会惊喜地发现嘛都查不出来了。
这就是mybatis自动映射的功能(关闭方法)。
之前的配置中并没有配置结果字段与Java字段的映射,mybatis会自动把查询结果映射到指定Java类中具有相同名称和setter方法字段上。

字段映射

关闭了自动映射功能,自然就想到使用手动映射。
FruitsMapper.xml文件内mapper标签内添加:

   <resultMap id="BaseMapper" type="com.llh.mybatis.pojo.Fruits">
        <id column="id" jdbcType="INTEGER" property="id"/>
        <result column="color" jdbcType="VARCHAR" property="color" />
        <result column="fruits_name" jdbcType="VARCHAR" property="fruitsName" />
        <result column="weight" jdbcType="VARCHAR" property="weight" />
        <result column="created_at" jdbcType="TIMESTAMP" property="createdAt" />
        <result column="updated_at" jdbcType="TIMESTAMP" property="updatedAt" />
    </resultMap>

再给select标签添加属性resultMap="BaseMapper"就可以引用这套映射配置(也就是说你可以整多套配置来满足需要)。
如此,之前没有值的字段也就有了值。

备注

MyBatis 自动映射有三种模式:NONE、PARTIAL、FULL。

第一个已经知道了。
第二个是默认项。
第三个会对嵌套对象进行映射。
总结下:第三个基本不会用,如无特殊需求就用默认。事实上配合代码生成工具,用第一个还是第二个配置并没有什么区别。

源码

此文使用项目源码在这里,查看标签v0.1里的代码即可。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,992评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,212评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,535评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,197评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,310评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,383评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,409评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,191评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,621评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,910评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,084评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,763评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,403评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,083评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,318评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,946评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,967评论 2 351

推荐阅读更多精彩内容