mybatis foreach map_Spring Boot(五):春眠不觉晓,Mybatis知多少
在JavaWeb项目开发中,我们使用最多的ORM框架可能就是Mybatis了,那么对于常用的mybatis,你究竟了解多少呢?
Mybatis是什么
MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码,手动设置参数以及获取结果集
MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录
Mybatis如何操作数据库
支持三种操作方式
1)注解
2)语句构建器
3)xml文件与接口映射方式
Mybatis的缓存机制
缓存的重要性是不言而喻的。考虑到性能,几乎所有与性能相关工具都会涉及到使用缓存, 我们可以避免频繁的与数据库进行交互, 尤其是在查询越多、缓存命中率越高的情况下, 使用缓存对性能的提高更明显。这个不在本篇细讲,到时候会专门作为一期内容呈现
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》百度百科
执行流程-源码分析
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大步骤。
得力助手
针对Mybatis的一些较为繁琐的方面,也分别有几个好用的工具
- mybatis-代码生成器
- 分页插件
- mybatis-plus
使用它们,可以大大提高Mybatis的开发效率,感兴趣可以了解一下。
嗯,怎么说呢,它们的好,谁用谁知道呢~
实战环节
对原理有个大概的了解,接下来,就进入今天的实战环节啦~
本次实战依旧演示操作mysql数据库-完成Spring Boot 使用Mybatis操作数据库的例子。
引入依赖
只需要引入mybtis依赖和mysql驱动两个主要依赖
org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.2mysql mysql-connector-java runtime
属性配置
分别进行数据库连接信息以及mybatis的相关信息配置
以下分别为大家演示了表字段与实体类属性的映射支持下划线对应驼峰的方式机制、指定mapper.xml文件位置、以及配置日志输出这3个常用的配置项
#1、数据库连接信息配置spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8spring.datasource.username=rootspring.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
创建实体类
使用之前文章中提到过的一个好用的开发工具lombok(如果想要了解用法,可以参考文章
SpringBoot(二):第一个Spring Boot项目),我们建立好的实体类User如下:
@Builder@Data@NoArgsConstructor@AllArgsConstructorpublic class User implements Serializable { private long id; private String name; private int age; private Date createTime; private Date updateTime;}
创建接口
针对在第一节中提到的三种操作方法,我们分别进行讲解
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为我们的语句构建类,然后定义与语句构建类中的方法名一致的方法
/** * 使用语句构造器方式定义数据库操作接口 */@Mapperpublic 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")//@EnableTransactionManagementpublic class SpringBootMybatisApplication implementsApplicationRunner { @Autowired private UserMapperWithAnnotation userMapperWithAnnotation; @Autowired private UserMapperWithXml userMapperWithXml; @Autowired private UserMapperWithBuilder userMapperWithBuilder; public static void main(String[] args) { SpringApplication. run(SpringBootMybatisApplication.class, args);} @Override @Transactional public void run(ApplicationArguments args) throws Exception { //testByMapper(); testByXml(); //testBuilder(); } private void testBuilder(){ userMapperWithBuilder.selectUserById(18l); } private void testByXml() { Map map = new HashMap<>(); map.put("name","小米"); map.put("age",17); List 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要与接口中的法名保持一致,同时相应的输入输出参数保持一致
调用接口方法
1)在启动类上添加注解,用于扫描我们所定义的数据库操作接口
@MapperScan("com.shumile.springbootmybatis.mapper")
接着,分别通过方法testBuilder、testByMapper以及testByXml调用以上所定义的各个数据库方法
@SpringBootApplication@Slf4j@MapperScan("com.shumile.springbootmybatis.mapper")public class SpringBootMybatisApplication implementsApplicationRunner { @Autowired private UserMapperWithAnnotation userMapperWithAnnotation; @Autowired private UserMapperWithXml userMapperWithXml; @Autowired private UserMapperWithBuilder userMapperWithBuilder; public static void main(String[] args) { SpringApplication. run(SpringBootMybatisApplication.class, args);} @Override @Transactional public void run(ApplicationArguments args) throws Exception { //testByMapper(); testByXml(); //testBuilder(); } private void testBuilder(){ userMapperWithBuilder.selectUserById(18l); } private void testByXml() { Map map = new HashMap<>(); map.put("name","小米"); map.put("age",17); List 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); }}
运行项目
运行项目,你就可以看到各个功能纷纷都实现啦,演示一下通过xml方式实现的日志打印效果
我们可以看到,日志中不仅为我们打印出来了格式化以后的sql语句,还将输出了sqlSession的创建与关闭等信息。所以在平时采用配置文件中所配置的日志输出方式还是挺好用的呢。
当然还有一种专门用于数据库监控的p6Spy工具,也挺好用的,感兴趣的话,可以搜索一下用法哦~
如果跟着文章的思路一路走到这里的话,那么恭喜你,Mybatis的三种操作数据库的方式,你已经全部学会啦~
总而言之
总体来说,使用语句构建器的方式操作数据库,采用具体的sql语句对应的方法来替换具体sql关键词,可以简化代码中直接书写的动态sql语句,并且还可以支持随意更换数据库,但总得来说,还是不够灵活
使用 XML 或注解的方式来配置 ORM,把 SQL 用标签管理起来,不关心,也不干涉实际 SQL 的书写。在这种思路下框架轻量,很容易集成,又因为我们可以使用 SQL 所有的特性,可以写存储过程,也可以写 SQL 方言(Dialect),所以灵活度相当高。
那么为什么我们更倾向于使用xml与接口映射的方式呢?
使用xml有以下两大优点:
- 可以把所有的sql写在xml文件中,要是有什么修改,甚至是换数据库的操作,我们只需要更换xml文件就行了
- 针对各种复杂的sql、以及sql可能实现起来比较麻烦的情况,我们也可以直接使用存储过程等多种方式来实现
虽然步骤相对比较麻烦,但是它最为灵活,也最为简洁,代码看起来更清爽,使用久了,也并不会觉得麻烦了。
今天一起重新学习了Mybatis,总体来说,有以下几点:
1、Spring Boot集成Mybatis的加载流程2、Mybatis操作数据库的三种方式
3、三种操作方式各自的特点
嗯,就这样。每天学习一点,时间会见证你的成长
下期预告:
Spring Boot(六):那些好用的连接池们
本期项目代码已上传到github~有需要的可以参考
https://github.com/wangjie0919/Spring-Boot-Notes
往期精彩回顾
Spring Boot(四):让人又爱又恨的JPA
Spring Boot(三):操作数据库-Spring JDBC
SpringBoot(二):第一个Spring Boot项目
SpringBoot(一):特性概览
mybatis foreach map_Spring Boot(五):春眠不觉晓,Mybatis知多少相关推荐
- spring boot 转xml格式报错解决方法_芋道 Spring Boot MyBatis 入门(一)之 MyBatis + XML...
摘要: 原创出处 http://www.iocoder.cn/Spring-Boot/MyBatis/「芋道源码」欢迎转载,保留摘要,谢谢! 1. 概述 2. MyBatis + XML 2.1 引入 ...
- Spring Boot入门系列(六)Spring Boot如何整合Mybatis【附详细步骤】
前面介绍了Spring Boot 中的整合Thymeleaf前端html框架,同时也介绍了Thymeleaf 的用法.不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/z ...
- MyBatis批量插入的五种方式
MyBatis利用For循环批量插入 MyBatis的手动批量提交 MyBatis以集合方式批量新增(推荐) MyBatis-Plus提供的SaveBatch方法 MyBatis-Plus提供的Ins ...
- Kotlin 企业级应用开发教程(Spring 5 + Spring Boot 2.0 + MyBatis)
Kotlin 企业级应用开发教程 -- Spring 5 + Spring Boot 2.0 + MyBatis 内容简介 Kotlin编程语言是一种现代语言,它简洁,安全,实用,同时专注于与Java ...
- Spring Boot(七):Mybatis 多数据源最简解决方案
Spring Boot(七):Mybatis 多数据源最简解决方案 参考文章: (1)Spring Boot(七):Mybatis 多数据源最简解决方案 (2)https://www.cnblogs. ...
- Spring Boot项目利用MyBatis Generator进行数据层代码自动生成
概 述 MyBatis Generator (简称 MBG) 是一个用于 MyBatis和 iBATIS的代码生成器.它可以为 MyBatis的所有版本以及 2.2.0之后的 iBATIS版本自动生成 ...
- mybatis源码阅读(五) ---执行器Executor
转载自 mybatis源码阅读(五) ---执行器Executor 1. Executor接口设计与类结构图 public interface Executor {ResultHandler NO_ ...
- Spring Boot中使用MyBatis注解配置详解
之前在Spring Boot中整合MyBatis时,采用了注解的配置方式,相信很多人还是比较喜欢这种优雅的方式的,也收到不少读者朋友的反馈和问题,主要集中于针对各种场景下注解如何使用,下面就对几种常见 ...
- spring boot开发笔记——mybatis
概述 mybatis框架的优点,就不用多说了,今天这边干货主要讲mybatis的逆向工程,以及springboot的集成技巧,和分页的使用 因为在日常的开发中,当碰到特殊需求之类会手动写一下s ...
最新文章
- lisp直线连接圆象限电_用小学数学知识解释,为什么井盖是圆的?
- php根据城市获取天气预报,根据浏览者ip获取城市,然后在获取城市天气预报
- PyTorch模型量化工具学习
- 2017c语言考核册答案,2017年最新C语言考题带答案
- ha apache mysql_apache-2.2 – Apache和MySQL的HAProxy平衡算法
- mongoudb 等于_MongoDB常用操作
- 〈转贴〉如何解决 Windows XP 中的硬件和软件驱动程序问题
- 解密:LL与LR解析 2(译,完结)
- OpenShift 4 - 提权运行容器
- Ecology 查询某人所有流程待办事项
- android+显示ui布局,[Android ]UI布局 (线性布局+相对布局)
- colorui 使用iconfont图标
- DMG计算机,dmg文件怎么打开?dmg是什么意思?
- opencv 曲线拟合
- OA办公——SwebUI开源应用解决方案
- OSPF Vlink peer的配置
- 软考中级软件设计师基础整理(1.计算机组成与体系结构)
- 2017.11.06 ~ 11.10 NOIP八连测滚粗记
- 什么蓝牙耳机颜值高音质好?颜值高音质好的蓝牙耳机推荐
- 基于数据分析,是否自动档汽车比手动挡更耗油
热门文章
- uniapp同步获取用户信息_微信小程序云开发教程微信小程序的API入门获取用户身份信息系列API...
- C/C++ 全局变量和局部变量在内存里的区别?堆和栈
- JS获取一个字符串中被指定的两个字符串包括起来的所有字符串数组
- Window7 安装开源swf反编译软件JPEXS Free Flash Decompiler(FFdec)实录
- 从头开始学习Adobe Photoshop CC图像编辑
- C4D样条曲线建模大师班 Cinema 4D MasterClass: Master Modelling using Splines
- C语言的单链表实现队列
- 因链接静态库先后顺序不正确,引起符号定义找不到
- [kuangbin带你飞]专题六 最小生成树 L - 还是畅通工程 (简单最小生成树)
- Flutter中集成Font Awesome