前言

  • 作为一个资深后端码农天天都要和数据库打交道,最早使用的是 Hiberate,一个封装性极强的持久性框架。自从接触到 Mybatis 就被它的灵活性所折服了,可以自己写 SQL,虽然轻量级,但是麻雀虽小,五脏俱全。这篇文章就来讲讲什么是 Mybatis,如何简单的使用 Mybatis。

什么是 Mybatis

  • MyBatis 是一款优秀的持久层框架,它支持自定义 SQL存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

环境搭建

  • 本篇文章使用的环境是SpringBoot+Mybatis+Mysql

Maven 依赖

  • MySQL 驱动依赖和 Druid 连接池的依赖

  1.    
  1.     <dependency>
  2. <groupId>mysql</groupId>
  3. <artifactId>mysql-connector-java</artifactId>
  4. <version>5.1.</version>
  5. <scope>runtime</scope>
  6. </dependency>

  7. <!--druid连接池-->
  8. <dependency>
  9. <groupId>com.alibaba</groupId>
  10. <artifactId>druid-spring-boot-starter</artifactId>
  11. <version>1.1.</version>
  12. </dependency>
  • Mybatis 启动包依赖,此处导入的是 SpringBoot 和 Mybatis 整合启动器的依赖,点击去可以看到,这个启动包依赖了mybatismybatis-spring(Mybatis 和 Spring 整合的 Jar 包),因此使用 SpringBoot 之后只需要导入这个启动器的依赖即可。

  1.        
  1. <dependency>
  2. <groupId>org.mybatis.spring.boot</groupId>
  3. <artifactId>mybatis-spring-boot-starter</artifactId>
  4. <version>2.0.</version>
  5. </dependency>
  • 以上两个依赖添加成功后,Maven 环境就已经配置完了。

数据库连接池配置(Druid)

  • 这个不是本文的重点,而且网上很多教程,我就简单的配置一下,在 SpringBoot 的application.properties中配置即可。

  1. ##单一数据源
  2. spring.datasource.url=jdbc\:mysql\://127.0.0.1\:3306/vivachekcloud_pzhdermyy?useUnicode\=true&characterEncoding\=UTF-8&zeroDateTimeBehavior\=convertToNull&useSSL\=false
  3. spring.datasource.username=root
  4. spring.datasource.password=
  5. spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
  6. spring.datasource.driver-class-name=com.mysql.jdbc.Driver
  7. #初始化连接大小
  8. spring.datasource.druid.initial-size=
  9. #连接池最大使用连接数量
  10. spring.datasource.druid.max-active=
  11. #连接池最小空闲
  12. spring.datasource.druid.min-idle=
  13. #获取连接最大等待时间
  14. spring.datasource.druid.max-wait=
  15. spring.datasource.druid.validation-query=SELECT
  16. #spring.datasource.druid.validation-query-timeout=
  17. spring.datasource.druid.test-on-borrow=false
  18. spring.datasource.druid.test-on-return=false
  19. spring.datasource.druid.test-while-idle=true
  20. #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
  21. spring.datasource.druid.time-between-eviction-runs-millis=
  22. #置一个连接在池中最小生存的时间,单位是毫秒
  23. spring.datasource.druid.min-evictable-idle-time-millis=
  24. #spring.datasource.druid.max-evictable-idle-time-millis=
  25. #打开removeAbandoned功能,多少时间内必须关闭连接
  26. spring.datasource.druid.removeAbandoned=true
  27. #1800秒,也就是30分钟
  28. spring.datasource.druid.remove-abandoned-timeout=
  29. #<!-- 1800秒,也就是30分钟 -->
  30. spring.datasource.druid.log-abandoned=true
  31. spring.datasource.druid.filters=mergeStat
  32. #spring.datasource.druid.verifyServerCertificate
  33. #spring.datasource.filters=stat,wall,log4j
  34. # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
  35. spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=

基础概念

  • dao层:用于存放和数据库交互的文件,Mybatis 的interface都放在此层

  • service层:用于存放业务逻辑的文件。

配置 xml 文件存放的位置

  • Mybatis 中xml的文件默认是要和interface放在一个包下的,并且文件的名称要一样。

  • 在和 SpringBoot 整合后有两种配置方式,下面详细介绍。

application.properties 中设置

  • 既然是和 SpringBoot 整合,那么万变不离xxxAutoConfiguration这个配置类了,Mybatis 的配置类就是MybatisAutoConfiguration,如下:

  1. @org.springframework.context.annotation.Configuration
  2. @ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class })
  3. @ConditionalOnSingleCandidate(DataSource.class)
  4. @EnableConfigurationProperties(MybatisProperties.class)
  5. @AutoConfigureAfter(DataSourceAutoConfiguration.class)
  6. public class MybatisAutoConfiguration implements InitializingBean {}
  • 可以看到@EnableConfigurationProperties(MybatisProperties.class)这行代码,就是将 properties 中的属性映射到 MybatisProperties 这个成员属性中,因此设置的方式就要看其中的属性。

  1. public class MybatisProperties {
  2. //前缀
  3. public static final String MYBATIS_PREFIX = "mybatis";

  4. /**
  5. * Mybatis配置文件的位置
  6. */
  7. private String configLocation;

  8. /**
  9. * Mybatis的Mapper的xml文件的位置
  10. */
  11. private String[] mapperLocations;
  • 因此设置的方式很简单,如下:

  1. ## xml文件放置在/src/main/resource/mapper/文件夹下
  2. mybatis.mapper-locations=classpath*:/mapper/**/*.xml

配置类中设置

  • 不是本章重点,后面在讲 Mybatis 和 SpringBoot 整合的文章会涉及到该内容。

配置扫描 Mybatis 的 interface

  • 在和 SpringBoot 整合后,扫描 Mybatis 的接口,生成代理对象是一件很简单的事,只需要一个注解即可。

@Mapper

  • 该注解标注在 Mybatis 的interface类上,SpringBoot 启动之后会扫描后会自动生成代理对象。实例如下:

  1. @Mapper
  2. public interface UserInfoMapper {

  3. int insert(UserInfo record);

  4. int insertSelective(UserInfo record);
  5. }
  • 缺点:每个interface都要标注一个,很鸡肋,一个项目中的 interface 少说也有上百个吧。

@MapperScan

  • @Mapper注解的升级版,标注在配置类上,用于一键扫描 Mybatis 的interface

  • 使用也是很简单的,直接指定接口所在的包即可,如下:

  1. @MapperScan({"com.xxx.dao"})
  2. public class ApiApplication {}
  • @MapperScan@Mapper这两个注解千万不要重复使用。

  • 优点:一键扫描,不用每个 interface 配置。

基本的 crud

  • 既然和数据库交互,避免不了 crud 操作,就安心做一个妥妥的crud boy吧。

  • 针对 Mybatis 其实有两套方法映射,一个是 XML 文件的方式,一个是注解的方式。但是今天只讲 XML 文件的方式,原因很简单,注解的方式企业不用,谁用谁倒霉,哈哈。

查询

  • 查询语句是 MyBatis 中最常用的元素之一——光能把数据存到数据库中价值并不大,还要能重新取出来才有用,多数应用也都是查询比修改要频繁。 MyBatis 的基本原则之一是:在每个插入、更新或删除操作之间,通常会执行多个查询操作。因此,MyBatis 在查询和结果映射做了相当多的改进。一个简单查询的 select 元素是非常简单的。

  1. <select id="selectPersonById" parameterType="int" resultType="com.myjszl.domain.Person">
  2. SELECT name,age,id FROM PERSON WHERE ID = #{id}
  3. </select>
  • 对应的interface的方法如下:

  1. Person selectPersonById(int id);
  • <select>这个标签有很多属性,比较常用的属性如下:

    • id(必填):在命名空间中唯一的标识符,可以被用来引用这条语句。和interface中的方法名要一致。

    • parameterType(可选):将会传入这条语句的参数的类全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器(TypeHandler)推断出具体传入语句的参数,默认值为未设置(unset)。

    • resultType:期望从这条语句中返回结果的类全限定名或别名。 注意,如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型。 resultTyperesultMap 之间只能同时使用一个。

    • resultMap:对外部 resultMap 的命名引用。结果映射是 MyBatis 最强大的特性,如果你对其理解透彻,许多复杂的映射问题都能迎刃而解。 resultTyperesultMap 之间只能同时使用一个。

变更

  • 数据变更语句 insert,update 和 delete 的实现非常接近。

  • 下面是 insert,update 和 delete 语句的示例:

  1. <insert id="insertAuthor">
  2. insert into Author (id,username,password,email,bio)
  3. values (#{id},#{username},#{password},#{email},#{bio})
  4. </insert>

  5. <update id="updateAuthor">
  6. update Author set
  7. username = #{username},
  8. password = #{password},
  9. email = #{email},
  10. bio = #{bio}
  11. where id = #{id}
  12. </update>

  13. <delete id="deleteAuthor">
  14. delete from Author where id = #{id}
  15. </delete>

{}和${}的区别

  • 上面的例子中我们可以看到使用的都是#{},关于#{}${}的区别也是在很多初级工程师的面试最常被问到的,现在只需要记住区别就是#{}使用了 JDBC 的预编译,可以防止 SQL 注入,提高了安全性,${}并没有预编译,安全性不够。在后面 Mybatis 的源码讲解中将会涉及到为什么一个用了预编译,一个没用。

自增 ID 的返回

  • 关于 Mysql 的文章中有提到,设计一个表最好要有一个自增 ID,无论这个 ID 你是否用到,具体原因不在解释,可以翻看之前的文章。

  • 有了自增 ID,插入之后并不能自动返回,但是我们又需要这个 ID 值,那么如何返回呢?

  • <insert>标签提供了两个属性用来解决这个问题,如下:

    • useGeneratedKeys:设置为 true,表示使用自增主键返回

    • keyProperty:指定返回的自增主键映射到parameterType的哪个属性中。

  • 假设插入Person,并且 person 表中的自增主键 id 需要返回,XML 文件如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3. <mapper namespace="com.xxx.dao.PersonMapper">
  4. <insert id='addPerson' parameterType='com.xxx.domain.Person' useGeneratedKeys="true"
  5. keyProperty="id" >
  6. insert into person(name,age)
  7. values(#{name},#{age});
  8. </insert>
  9. </mapper>

SQL 代码片段

  • 这个元素可以用来定义可重用的 SQL 代码片段,以便在其它语句中使用。 参数可以静态地(在加载的时候)确定下来,并且可以在不同的 include 元素中定义不同的参数值。比如:

  1. <sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </sql>
  • 这个 SQL 片段可以在其它语句中使用,例如:

  1. <select id="selectUsers" resultType="map">
  2. select
  3. <include refid="userColumns"><property name="alias" value="t1"/></include>,
  4. <include refid="userColumns"><property name="alias" value="t2"/></include>
  5. from some_table t1
  6. cross join some_table t2
  7. </select>

开启驼峰映射

  • DBA 在设计数据库的时候,往往使用的是下划线(_)的方式,比如user_id。但是 Java 是不规范的,我们通常将它转换为userId,这就是驼峰命名方法。

  • 但是在使用 Mybatis 查询的时候,比如:

  1. <select id='selectById' resultType='com.xxx.doamin.User'>
  2. select user_id from user_info
  3. </select>
  • 上面的user_idUser中的userId根本不对应,也就映射不进去,此时查询的结果就是 userId 是 null,当然我们可以使用别名的方式,SQL 可以改写为select user_id as userId from user_info

  • 另外一种方式是不用别名,直接开启 Mybatis 的驼峰映射规则,会自动映射,开启的方式很简单,就是在application.properties文件配置一下,如下:

  1. mybatis.configuration.map-underscore-to-camel-case=true

总结

  • 本文主要讲了 Mybatis 与 SpringBoot 的整合过程,基本的 crud,各种标签的属性等内容,属于一个入门级别的教程,后续的内容会逐渐深入。

  • 另外,MySQL 进阶的教程已经写了五篇文章了,每一篇都是经典,已经出了一个专辑,感兴趣的可以收藏一下MySQL 进阶

  • 感谢你的阅读,作者会定时的更新原创文章,如果觉得写的不错的话,可以关注一下本公众号。

Mybatis入门篇之基础CRUD的更多相关文章

  1. Membership三步曲之入门篇 - Membership基础示例

    Membership 三步曲之入门篇 - Membership基础示例 Membership三步曲之入门篇 -  Membership基础示例 Membership三步曲之进阶篇 -  深入剖析Pro ...

  2. [转]Membership三步曲之入门篇 - Membership基础示例

    本文转自:http://www.cnblogs.com/jesse2013/p/membership.html Membership三步曲之入门篇 - Membership基础示例   Members ...

  3. Mybatis入门篇之结果映射,你射准了吗?

    目录 前言 什么是结果映射? 如何映射? 别名映射 驼峰映射 配置文件开启驼峰映射 配置类中开启驼峰映射 resultMap映射 总结 高级结果映射 关联(association) 例子 关联的嵌套 ...

  4. mybatis入门篇基——基本配置与参数说明

    Mybatis 好吧这是我第一次写这种文章~如果有不足和错误之处欢迎评论,指点.今天想谈谈关于mybatis的一些基础入门知识. 进入正题~~: a.关于mybatis: 我个人觉得mybatis深得 ...

  5. MyBatis入门篇

    一.什么是MyBatis MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改 ...

  6. mybatis入门篇:Mybatis高级查询

    1.ResultMap的association与collection association与collection功能类似,区别是一对一与一对多,这里以association为例. 首先说明一下需求: ...

  7. mybatis入门篇:代码生成器(MyBatis Generator)

    这篇文章只是按照自己的需要去配置代码生成器,未对所有配置进行讲解,需要了解具体详情的,请到官网查阅文档.传送门:http://www.mybatis.org/generator/ 1.首先引入相关的依 ...

  8. mybatis入门篇:Mapper接口/关联查询/新增数据

    1.数据准备 2.编写实体类 package com.forest.owl.entity; import java.util.Date; public class User { private Lon ...

  9. mybatis入门篇:通过SqlSession.selectList进行数据查询

    作为一个java菜鸟,早就从慕课网中学到一些基本的mybatis的用法,但是一直不成体系,懵懵懂懂,既然正式入了java这个坑,就打算好好学学,所以买了本<MyBatis从入门到精通>,在 ...

随机推荐

  1. C++的常用输入及其优化以及注意事项

    $\mathcal{P.S:}$ 对于输入方式及其优化有了解的大佬可直接阅读$\mathcal{Part}$ $\mathcal{2}$ 特别鸣谢:@归斋目录: $\mathcal{Part}$ $\ ...

  2. K短路 学习笔记

    K短路,顾名思义,是让你求从$s$到$t$的第$k$短的路. 暴力当然不可取,那么我们有什么算法可以解决这个问题? -------------------------- 首先,我们要维护一个堆. st ...

  3. CI4框架应用一 - 环境搭建

    CI框架 (codeigniter)算是一个古老的框架了,由于在工作中一直在使用这个框架,还是比较有感情的.我对CI的感觉就是,简单易用,学习曲线平滑,对于新手友好. 目前CI框架已经更新到CI4了, ...

  4. Python初学者的自我修养,找到自己的方向

    今天是 Python专题 的第22篇文章,原本今天是准备和大家继续Python当中多线程的使用的相关内容.然而前两天有一个读者在后台问我,学习Python有哪些适合新手入门的小项目推荐,所以今天这篇临 ...

  5. 史上最全的微信小程序代码大全

    --------------------- 本文来自 fenxiangjun 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/fenxiangjun/article/d ...

  6. GitLab 配置模板

    GitLab 配置模板 GitLab 使用模板和参数生成配置文件. 一般来说,我们会通过 gitlab.rb 文件修改配置,例如 Nginx 相关配置. gitlab.rb 只能使用特定的几个 Ngi ...

  7. 2020-06-18:ZK的分布式锁怎么实现?

    福哥答案2020-06-18: Zk分布式锁有两种实现方式一种比较简单,应对并发量不是很大的情况.获得锁:创建一个临时节点,比如/lock,如果成功获得锁,如果失败没获得锁,返回false释放锁:删除 ...

  8. C#LeetCode刷题之#811-子域名访问计数​​​​​​​(Subdomain Visit Count)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3814 访问. 一个网站域名,如"discuss.lee ...

  9. C#图解教程(第四版)—02—类的基本概念

    类  是一种能 存储数据  并且  执行代码  的数据结构,他包含数据成员和函数成员 .成员可以是9种可能的成员类型的任意组合 字段 属性 方法 常量 构造函数 析构函数 运算符 索引器 事件 1 字 ...

  10. 一文搞懂Java8 Lambda表达式(附带视频教程)

    Lambda表达式介绍 Java 8的一个大亮点是引入Lambda表达式,使用它设计的代码会更加简洁.通过Lambda表达式,可以替代我们以前经常写的匿名内部类来实现接口.Lambda表达式本质是一个 ...