在JavaWeb项目开发中,我们使用最多的ORM框架可能就是Mybatis了,那么对于常用的mybatis,你究竟了解多少呢?

一 全局了解

1 Mybatis是什么

MyBatis 是支持定制化 SQL存储过程以及高级映射的优秀的持久层框架MyBatis 避免了几乎所有的 JDBC 代码,手动设置参数以及获取结果集

MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录

2 Mybatis如何操作数据库

支持三种操作方式

1)注解

2)语句构建器

3)xml文件与接口映射方式

3 Mybatis的缓存机制

缓存的重要性是不言而喻的。考虑到性能,几乎所有与性能相关工具都会涉及到使用缓存, 我们可以避免频繁的与数据库进行交互, 尤其是在查询越多、缓存命中率越高的情况下, 使用缓存对性能的提高更明显。这个不在本篇细讲,到时候会专门作为一期内容呈现

4 Mybatis的执行流程

1) 加载配置 配置来源于两个地方,一处是配置文件,一处是Java代码的注解,将SQL的配置信息加载成为一个个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中

2) SQL解析 当API接口层接收到调用请求时,会接收到传入SQL的ID和传入对象(可以是Map、JavaBean或者基本数据类型),Mybatis会根据SQL的ID找到对应的MappedStatement,然后根据传入参数对象对MappedStatement进行解析,解析后可以得到最终要执行的SQL语句和参数
3) SQL执行 将最终得到的SQL和参数拿到数据库进行执行,得到操作数据库的结果
4) 结果映射 将操作数据库的结果按照映射的配置进行转换,可以转换成HashMap、JavaBean或者基本数据类型,并将最终结果返回

--摘自《Mybatis》百度百科

5 执行流程-源码分析

mybatis的对数据库的底层操作,如Spring JDBC一样,实际上也是对JDBC的一个封装,它的底层原理依旧是JDBC。所以依然遵从JDBC的6个步骤

  • a 加载数据库驱动
  • b 建立链接
  • c 创建statement
  • d 执行SQL语句
  • e 处理结果集
  • f 关闭数据库

通过跟踪使用xml方式的查询方法源码,我们一路走下来是这样的:

1)建立连接

2)获取xml文件与接口中的对应方法

3)创建statement,并执行sql语句,返回结果集

4)在这几步结束之后,会关闭statement

5)关闭连接

其中,我们需要知道的是,Spring会根据我们引入的数据库类型,预先加载数据库的驱动。因此Mybatis执行数据库的流程,实际上就是JDBC的6大步骤。

6 得力助手

针对Mybatis的一些较为繁琐的方面,也分别有几个好用的工具

  • mybatis-代码生成器
  • 分页插件
  • mybatis-plus

使用它们,可以大大提高Mybatis的开发效率,感兴趣可以了解一下。
嗯,怎么说呢,它们的好,谁用谁知道呢~

二 实战 实战环节

对原理有个大概的了解,接下来,就进入今天的实战环节啦~
本次实战依旧演示操作mysql数据库-完成Spring Boot 使用Mybatis操作数据库的例子。

1 引入依赖

只需要引入mybtis依赖和mysql驱动两个主要依赖

<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.2</version>
</dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope>
</dependency>

2 属性配置

分别进行数据库连接信息以及mybatis的相关信息配置

以下分别为大家演示了表字段与实体类属性的映射支持下划线对应驼峰的方式机制、指定mapper.xml文件位置、以及配置日志输出这3个常用的配置项

#1、数据库连接信息配置
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=123456
#2、开启下划线的表字段映射为驼峰格式的实体类属性
#mybatis.configuration.map-underscore-to-camel-case=true
#3、用于指定xml文件的位置(使用xml执行sql语句的方式时)
mybatis.mapper-locations=classpath:mapper/*.xml
#4、打印sql语句
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

3 创建实体类

使用之前文章中提到过的一个好用的开发工具lombok(如果想要了解用法,可以参考文章

SpringBoot(二):第一个Spring Boot项目),我们建立好的实体类User如下:

@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {private long id;private String name;private int age;private Date createTime;private Date updateTime;
}

4 创建接口

针对在第一节中提到的三种操作方法,我们分别进行讲解

1)注解

mybatis提供了很多操作注解,如下

mybatis的注解方式,是使用这些操作注解,将sql语句写入这些注解中,进行数据库的操作的(其中结尾为Provider的注解,用于语句构建器方式)

我们只需要在接口上添加@Mapper注解,然后直接使用这些注解进行方法的定义

我们分别定义了数据库的新增和根据id查找记录这两个方法

2)语句构建器

a 创建UserBuilder

实现接口ProviderMethodResolver

public class UserBuilder  implements ProviderMethodResolver {public String deleteUserSql() {return new SQL() {{DELETE_FROM("user");WHERE("ID = ${id}");}}.toString();}public static String selectUserById() {return new SQL().SELECT("name,age,create_time,update_time").FROM("user").WHERE("id = #{id}").toString();}
}

b 创建接口

定义方法时,采用对应的Provider注解的方式,指定类型type为我们的语句构建类,然后定义与语句构建类中的方法名一致的方法

/*** 使用语句构造器方式定义数据库操作接口*/
@Mapper
public interface UserMapperWithBuilder {@SelectProvider(type = UserBuilder.class)User selectUserById(long id);
}

3)xml方式

xml方式,使我们经常使用的方式,因为它对于项目开发来说,还是比较灵活的。

a 建立与接口映射的xml文件UserMapper.xml

b 建立相应的映射接口

@SpringBootApplication
@Slf4j
@MapperScan("com.shumile.springbootmybatis.mapper")
//@EnableTransactionManagement
public class SpringBootMybatisApplication implementsApplicationRunner {@Autowiredprivate UserMapperWithAnnotation userMapperWithAnnotation;@Autowiredprivate UserMapperWithXml userMapperWithXml;@Autowiredprivate UserMapperWithBuilder userMapperWithBuilder;public static void main(String[] args) {SpringApplication.                run(SpringBootMybatisApplication.class, args);
}@Override@Transactionalpublic void run(ApplicationArguments args) throws Exception {//testByMapper();testByXml();//testBuilder();}private void testBuilder(){userMapperWithBuilder.selectUserById(18l);}private void testByXml() {Map<String, Object> map = new HashMap<>();map.put("name","小米");map.put("age",17);List<User> userList = userMapperWithXml.getUserList(map);userList.forEach(user->log.info("user:{}",user));}private void testByMapper() {User c = User.builder().name("小米").age(17).createTime(new Date()).updateTime(new Date()).build();int count = userMapperWithAnnotation.save(c);log.info("Save {} User: {}", count, c);c = userMapperWithAnnotation.findById(c.getId());log.info("Find User: {}", c);}
}

温馨提示:需要注意以下几点,否则程序执行的时候会找不到

  • 这个文件的放置位置应该与配置文件中所配置的路径一致
  • mapper标签中的namespace属性要指定为对应的映射接口UserMapperWithXml
  • 各个方法的id要与接口中的法名保持一致,同时相应的输入输出参数保持一致

5 调用接口方法

1)在启动类上添加注解,用于扫描我们所定义的数据库操作接口

@MapperScan("com.shumile.springbootmybatis.mapper")

接着,分别通过方法testBuilder、testByMapper以及testByXml调用以上所定义的各个数据库方法

@SpringBootApplication
@Slf4j
@MapperScan("com.shumile.springbootmybatis.mapper")
public class SpringBootMybatisApplication implementsApplicationRunner {@Autowiredprivate UserMapperWithAnnotation userMapperWithAnnotation;@Autowiredprivate UserMapperWithXml userMapperWithXml;@Autowiredprivate UserMapperWithBuilder userMapperWithBuilder;public static void main(String[] args) {SpringApplication.                run(SpringBootMybatisApplication.class, args);
}@Override@Transactionalpublic void run(ApplicationArguments args) throws Exception {//testByMapper();testByXml();//testBuilder();}private void testBuilder(){userMapperWithBuilder.selectUserById(18l);}private void testByXml() {Map<String, Object> map = new HashMap<>();map.put("name","小米");map.put("age",17);List<User> userList = userMapperWithXml.getUserList(map);userList.forEach(user->log.info("user:{}",user));}private void testByMapper() {User c = User.builder().name("小米").age(17).createTime(new Date()).updateTime(new Date()).build();int count = userMapperWithAnnotation.save(c);log.info("Save {} User: {}", count, c);c = userMapperWithAnnotation.findById(c.getId());log.info("Find User: {}", c);}
}

6 运行项目

运行项目,你就可以看到各个功能纷纷都实现啦,演示一下通过xml方式实现的日志打印效果

我们可以看到,日志中不仅为我们打印出来了格式化以后的sql语句,还将输出了sqlSession的创建与关闭等信息。所以在平时采用配置文件中所配置的日志输出方式还是挺好用的呢。

当然还有一种专门用于数据库监控的p6Spy工具,也挺好用的,感兴趣的话,可以搜索一下用法哦~

如果跟着文章的思路一路走到这里的话,那么恭喜你,Mybatis的三种操作数据库的方式,你已经全部学会啦~

三 总结 总而言之

总体来说,使用语句构建器的方式操作数据库,采用具体的sql语句对应的方法来替换具体sql关键词,可以简化代码中直接书写的动态sql语句,并且还可以支持随意更换数据库,但总得来说,还是不够灵活

使用 XML 或注解的方式来配置 ORM,把 SQL 用标签管理起来,不关心,也不干涉实际 SQL 的书写。在这种思路下框架轻量,很容易集成,又因为我们可以使用 SQL 所有的特性,可以写存储过程,也可以写 SQL 方言(Dialect),所以灵活度相当高。

那么为什么我们更倾向于使用xml与接口映射的方式呢?
使用xml有以下两大优点:

  1. 可以把所有的sql写在xml文件中,要是有什么修改,甚至是换数据库的操作,我们只需要更换xml文件就行了
  2. 针对各种复杂的sql、以及sql可能实现起来比较麻烦的情况,我们也可以直接使用存储过程等多种方式来实现

虽然步骤相对比较麻烦,但是它最为灵活,也最为简洁,代码看起来更清爽,使用久了,也并不会觉得麻烦了。

今天一起重新学习了Mybatis,总体来说,有以下几点:

1、Spring Boot集成Mybatis的加载流程2、Mybatis操作数据库的三种方式

3、三种操作方式各自的特点

嗯,就这样。每天学习一点,时间会见证你的成长

下期预告:Spring Boot(六):那些好用的连接池们
本期项目代码已上传到github~有需要的可以参考https://github.com/wangjie0919/Spring-Boot-Notes
往期精彩回顾

Spring Boot(四):让人又爱又恨的JPA​mp.weixin.qq.com

Spring Boot(三): 操作数据库-Spring JDBC​mp.weixin.qq.com

SpringBoot(二):第一个Spring Boot项目​mp.weixin.qq.com

SpringBoot(一):特性概览​mp.weixin.qq.com

springboot map数据类型注入_Spring Boot(五):春眠不觉晓,Mybatis知多少相关推荐

  1. springboot map数据类型注入_SpringBoot结合策略模式实战套路

    1. SpringBoot结合策略模式实战套路 1.1. 前言 我们都知道设计模式好,可以让我们的代码更具可读性,扩展性,易于维护,但大部分程序猿一开始都学过至少一遍设计模式吧,实战中不知用到了几成. ...

  2. springboot几种注入_Spring Boot中使用JdbcTemplate访问数据库

    本文介绍在Spring Boot基础下配置数据源和通过JdbcTemplate编写数据访问的示例. 数据源配置 在我们访问数据库的时候,需要先配置一个数据源,下面分别介绍一下几种不同的数据库配置方式. ...

  3. springboot mapper无法注入_Spring Boot通过ImportBeanDefinitionRegistrar动态注入Bean

    在阅读Spring Boot源码时,看到Spring Boot中大量使用ImportBeanDefinitionRegistrar来实现Bean的动态注入.它是Spring中一个强大的扩展接口.本篇文 ...

  4. mybatis注解开发_Spring Boot 中集成 MyBatis

    阅读本文约需要5分钟 大家好,我是你们的导师,我每天都会在这里给大家分享一些干货内容(当然了,周末也要允许老师休息一下哈).上次老师跟大家分享了Spring Boot 中的AOP处理,今天给大家分享下 ...

  5. springboot 事务统一配置_Spring Boot实现分布式微服务开发实战系列(五)

    最近已经推出了好几篇SpringBoot+Dubbo+Redis+Kafka实现电商的文章,今天再次回到分布式微服务项目中来,在开始写今天的系列五文章之前,我先回顾下前面的内容. 系列(一):主要说了 ...

  6. springboot开启debug日志_Spring Boot SLF4J日志实例(五十)

    默认情况下,SLF4j日志记录包含在Spring Boot Web应用程序中,只需要启用它就可以了. 注意:查看此Spring Boot Logback XML模板以了解默认的日志记录模式和配置. S ...

  7. springboot controller 分页查询_Spring Boot实战分页查询附近的人:Redis+GeoHash+Lua

    前言 最近在做社交的业务,用户进入首页后需要查询附近的人: 项目状况:前期尝试业务阶段: 特点: 快速实现(不需要做太重,满足初期推广运营即可) 快速投入市场去运营 收集用户的经纬度: 用户在每次启动 ...

  8. springboot服务调用超时_Spring Boot 异步请求和异步调用,一文搞定

    一.Spring Boot中异步请求的使用 1.异步请求与同步请求 特点: 可以先释放容器分配给请求的线程与相关资源,减轻系统负担,释放了容器所分配线程的请求,其响应将被延后,可以在耗时处理完成(例如 ...

  9. springboot controller 分页查询_Spring Boot实战分页查询附近的人: Redis+GeoHash+Lua

    您的支持是我不断创作巨大动力 CSDN博客地址(关注,点赞) 人工智能推荐 GitHub(Star,Fork,Watch) 前言 最近在做社交的业务,用户进入首页后需要查询附近的人: 项目状况:前期尝 ...

最新文章

  1. Chirp信号公式与对离散生成算法之间的差异
  2. DJANGO_SETTINGS_MODULE is undefined报错的解决
  3. Linux bash总结(一) 基础部分(适合初学者学习和非初学者参考)
  4. java时间戳版本号_maven 自动编译版本号 buildnumber-maven-plugin 1.4
  5. C++:求n以内被3除余余1的所有整数
  6. UI设计APP素材可编辑模板|底部标签式导航
  7. 布尔运算,二进制和门电路
  8. android thread线程通讯
  9. 《Effective Python 2nd》——类与接口
  10. xrd精修教程_一文详解XRD精修的应用
  11. Junit单元测试的基本编码步骤
  12. 如何从技术上分析舌战群儒?
  13. php codeigniter3,codeigniter
  14. 快速处理-小程序/uniapp,showToast没有效果
  15. WebAPI第四天学习总结—— 常见网页特效案例(轮播图、节流阀、返回顶部、筋斗云案例)
  16. python实现qq登录界面_Python实现QQ界面
  17. 【excel技巧读书笔记005】快速隔行填充
  18. 戏说:诸葛亮的真实身份竟是汉献帝
  19. 6.1电机,串口控制,PWM调速
  20. 推荐收藏!10大程序员必备生产力工具

热门文章

  1. 2017-10-湖南套题1
  2. 如何在linux centos下安装git(转)
  3. How to pronounce symbols on keyboard
  4. [转载] C++ STL之 vector的capacity和size属性区别
  5. [转载] Linux+树莓派3开发总结——cx_Freeze打包Python3程序(工程文件)
  6. 软工实践第八次作业(软件工程实践总结)
  7. Vimtutor中文版
  8. JS call()与apply()的用法
  9. Web.xml配置详解之context-param (加载spring的xml,然后初始化bean看的)
  10. hibernate的查询方式