MyBatis+Spring MVC开发指南(一)
前言
MyBatis+Spring MVC这套组合,在实际互联网项目中非常流行,博主工作中也涉及过,打算由浅入深、系统的写出来!这个系列将会涵盖MyBatis开发详解、Spring MVC开发详解,以及2者的结合使用,并会分析它们的原理!(可以参考博主的另一篇文章了解Spring MVC原理:《写出我的第一个框架:迷你版Spring MVC》)
没有MyBatis之前
在早期,我们都是通过原生的JDBC来操作数据库的,而这种方式存在很多问题。
我们先来看一个例子:
问题有哪些呢?
第一,在创建数据库连接这块,程序是需要时创建,用完后关闭。如果频繁的创建、关闭数据库连接,显然存在问题。当然,我们可以通过数据库连接池来处理这个问题。
第二,硬编码的地方太多了。比如,数据库连接相关的一些信息,SQL相关的一些信息。当然,我们可以通过使用配置文件,来避免这个问题。
第三,实质上,我们编写JDBC是有步骤可循的,比如,我们得先得到数据库连接对象,得有SQL,有输入参数,设置参数,去执行SQL,然后遍历结果集将数据库SQL执行的结果对象转化为JAVA对象,然后再去业务处理,最后释放资源。那么这个过程,实际上是个模板,能不能抽离出来,更好的去完成这个过程呢?
比如,Hibernate,这个纯粹的ORM(对象关系映射)框架,让程序员以面向对象的方式来完成数据库的操作,功能很强大,SQL都帮我们自动生成了,但是这也带来了一些其他问题,比如门槛较高,有时候我们想编写SQL,修改SQL,优化SQL都费劲,在互联网项目快速迭代开发中,太过笨重了!
基于这些因素,出现了iBatis,并发展为今天的MyBatis,作为Apache的顶级项目,目前已经托管到github下。
MyBatis框架的架构
上面我们说了一些JDBC的缺点,而MyBatis是避免了这些问题的。如果让我们来实现MyBatis的话,我们会怎么想呢?
第一,应该存在一个配置文件A,可以将数据库的连接信息,事务信息等放入其中;
第二,应该提供一个配置文件B,可以让程序员编写SQL,重点需要解决的是如何给SQL传递参数,以及如何将结果映射为JAVA对象;
第三,应该提供API可以执行文件B中的SQL
基于上面的分析,我们来看一下MyBatis的架构:
这里,我们先简单了解些概念:
SqlSessionFactory用于创建SqlSession,SqlSession即操作DB的接口,其内部借助Executor执行器完成对数据库的操作。
全局配置文件,就是图中的SqlMapConfig.xml;SQL文件即是Mapper.xml文件。
对于MappedStatement而言,会完成输入映射以及输出映射。
Quick Start
这里先写个简单的DEMO带大家初步了解下。
POM依赖:
MyBatis的全局配置文件:
需要注意下:
第一,我们把MySQL的一些连接信息放入到db.properties中,使用<properties>标签加载属性文件,并通过${XXX}的方式引用。
第二,要知道现在的日志框架有很多,这里使用<settings>设置下日志使用LOG4J实现。
第三,我们说SQL结果集要完成到JAVA对象的映射,那么根据反射的原理,我们都能猜到必须要提供带包路径的全限定名称,那么为了简化,提供<typeAliases>标签进行别名映射处理。提供了2种方式,一个是单个的类型别名映射,一个是基于包扫描的批量映射。当然批量映射的别名就是类名。
第四,需要<mappers>标签加载SQL文件。同上面一样,也提供了基于包扫描的批量加载。
log4j.properties:
在开发阶段,显然,我们希望MyBatis能够为我们打印SQL日志,方便调试,排查问题。
SQL配置:
需要关注下:
第一,namespace,顾名思义,命名空间,其实是想隔离SQL,不过到了MyBatis和Spring结合使用时,具有特殊的意义。这里暂且使用全限定类名。
第二,<select>等SQL Command标签需要一个ID,还需要输入参数parameterType,输出参数映射resultType等。其实这些在MyBatis的底层封装成了一个MappedStatement对象。当然定位这个对象,需要namespace.id的方式。
第三,${value} VS #{xxx}
其实2者,都可以接受JAVA简单类型,如int,也可以接受POJO,Map等复杂类型。如果是JAVA简单类型,那么$的方式必须是${value},而#{}可以随意,是因为在这种情况下,$会通过反射getValue()的方式取值。如果是POJO等复杂类型,2者其实都可以通过OGNL表达式取到,只不过#会额外的进行JAVA类型到数据库类型的转换,而$没有类型处理过程,它直接拼接。也就是说#会使用预编译成?,而$将在SQL编译阶段就采取替换操作,可能带来SQL注入的问题。所以在实际开发中,我们当然优先采用#的方式取值。
测试程序:
测试程序,并没有太多可以说的,关注2点即可:
第一,selectOne VS selectList
显然,我们需要清楚的知道,SQL返回的结果集是一条记录,还是多条记录,如果使用selectOne那么必须最多返回一条记录。那么返回多条记录与返回一条记录的时候,resultType有变化么?(其实是不变的。)
第二,SqlSession
SqlSessionFactoryBuilder -> SqlSessionFactory -> SqlSession
我们重点关注的是SqlSession,它其实是一个interface,定义了很多操作数据库的接口,而且extends Closeable,很明确是需要close的。
它的实现类DefaultSqlSession中有一些数据域(比如说autoCommit,在默认情况下是不开启自动提交的),而且方法也并不是Synchronized,这说明SqlSession并不是线程安全的,因此我们应该是局部使用SqlSession,使用完毕后close掉。
Mapper代理开发
其实,除了Mapper代理开发外,还有一种原始Dao开发的方式。原始Dao开发方式的思路大致是这样的:
第一,我们提供Dao接口,有增、删、改、查的方法。
第二,我们提供Dao的实现类,在实现类中,我们利用Spring注入SqlSessionFactory,然后在各个方法中得到SqlSession,进行操作后,关闭SqlSession即可。
这种方式,重复的代码太多,已经OUT了,目前使用最多的就是Mapper代理开发。
提供Mapper.java接口:
提供与之对应的Mapper.xml文件:
在全局配置文件中加载Mapper.xml:
测试代码示例:
从这里,你应该可以看出Mapper的开发应该遵循一些规范,这样MyBatis才可以自动帮助我们生成XXXMapper类的代理实现类。(说白了,这些规范,就是为了利用反射)
第一,保证XXXMapper.xml中的namespace同XXXMapper.java的全限定名称一致
第二,保证XXXMapper.xml中的Statement的ID同XXXMapper.java的方法名称一致
第三,保证XXXMapper.xml中的Statement的输入参数的类型(parameterType)、输出参数的类型(resultType)同XXXMapper.java的保持一致
从这里,你大致可以了解到Mapper代理开发,程序员主要关注的就是Mapper.java以及Mapper.xml的生成,可以说极大的简化了工作量!
关于自增主键返回
很多时候,我们面临这样的需求,A表的字段ID是主键,而且是auto_increment自动增长的;我们完成A表的插入后,希望得到主键,以便后续的操作,比如另外一个表B,和表A存在主外键关系。
MyBatis当然早就替我们想好了,只需要稍微配置下,就可以将MySQL自动生成的主键取出设置到对应的JAVA对象的属性上。
看一个例子:
特别注意keyProperty是表示将获取到的自动增长的值设置到哪个Field域上。
关于动态SQL
我们知道,在JSP中,可以使用JSTL标签开发;而动态SQL就是类似于JSTL的一组标签,可以帮助我们灵活的生成SQL,比如实现判断,遍历数组/集合,SQL片段的复用等。值得关注的是,有些标签还挺智能,比如<where>还可以替你去掉第一个and.....
本篇博客并不会说明各个标签的使用方式,这样的例子,网上很多,大家可以参考。一句话,在开发阶段,我们只需要让MyBatis打印SQL,我们就能明白,我们的动态SQL是不是使用对了!
到这里,本篇博客就准备结束了,下一篇博客将会为大家介绍MyBatis的一些高级开发知识~
See U next time~
作者:张丰哲
链接:https://www.jianshu.com/p/91a32e3d4b26
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
MyBatis+Spring MVC开发指南(一)相关推荐
- pom添加mysql依赖tomcat崩溃_Spring Boot + Mybatis + Spring MVC环境配置(一) :Spring Boot初始化,依赖添加...
最近在搭建一个Spring Boot + Mybatis + Spring MVC的环境,折腾来折腾去,两三天才搞定,记录下大概过程和遇到的错误 看一下Spring Boot官方的介绍 : Sprin ...
- 《Servlet、JSP和Spring MVC初学指南》——第2章 会话管理 2.1URL重写
本节书摘来自异步社区<Servlet.JSP和Spring MVC初学指南>一书中的第2章,第2.1节,作者:[加]Budi Kurniawan(克尼亚万) , [美]Paul Deck著 ...
- 使用Spring MVC开发Restful Web服务
REST简介 摘自Wikipedia: REST风格的体系结构由客户端和服务器组成. 客户端向服务器发起请求: 服务器处理请求并返回适当的响应. 请求和响应围绕资源表示的传递而构建. 资源本质上可以是 ...
- Spring MVC开发步骤以及执行流程
Spring MVC开发步骤以及执行流程 开发步骤 1.在web.xml中定义前端控制器DispatcherServlet来拦截用户请求. 2.如果要以post方式提交请求,则定义包含表单数据的jsp ...
- spring boot之Spring Mvc开发和常用注解说明
spring boot之Spring Mvc开发和常用注解说明 Spring boot主要用于开发微服务接口.所以采用的控制层注解主要是restful形式. 创建微服务: 与上一篇文章一致. 依赖多一 ...
- Spring MVC学习指南(11-12章总结)
11:上传文件 将介绍如何在SpringMVC中使用Commons FileUpload和Servlet 3上传文件. 在填写表单的html中,必须将html的enctype属性值设置为multipa ...
- 框架应用 : Spring MVC - 开发详述
软件开发中的MVC设计模式 软件开发的目标是减小耦合,让模块之前关系清晰. MVC模式在软件开发中经常和ORM模式一起应用,主要作用是将(数据抽象,数据实体传输和前台数据展示)分层,这样前台,后台,数 ...
- Spring MVC开发–快速教程
这是我们的JCG合作伙伴之一,来自Manoj的有关使用Spring开发Web应用程序的简短教程, 网址为" The Khangaonkar Report ". (注意:对原始帖子进 ...
- Servlet JSP和Spring MVC初学指南 PDF
下载地址:网盘下载 Servlet和JSP是开发Java Web应用程序的两种基本技术.Spring MVC是Spring框架中用于Web应用快速开发的一个模块,是当今流行的Web开发框架之一. 本书 ...
最新文章
- C++资源之不完全导引(上)
- wamp配置虚拟主机
- 6 种激活函数核心知识点,请务必掌握!
- Java防止Xss注入json_浅谈 React 中的 XSS 攻击
- Airbnb: React Native 从选择到放弃
- SVM(一) 问题的提出
- 使用Google Guice消除实例之间的歧义
- OGR示例:写shp,求面与面的交和差操作
- mysql偏移注入_移位溢注:告别靠人品的偏移注入
- 【OpenCV】OpenCV函数精讲之 -- 访问图像中的像素--计时函数
- ListView的两种使用方法--Android学习笔记
- 概述--Nginx集成Vcenter 6.X HTML Console系列之 1--(共4)
- 【QT】QT从零入门教程(十二):实现工具箱QButtonGroup
- 山西省职业技能鉴定计算机操作员(中级工)理论知识试卷,山西省职业技能鉴定统一试卷 中级...
- 怎么确认mysql正确安装_怎么确认mysql是否安装好了
- fpgrowth算法实战 mlib_Spark MLlib FPGrowth关联规则算法
- iOS动画——流光文字
- tensorflow graphics详解
- linux正常关机使用命令是,Linux系统关机的命令
- Excise_Oop1
热门文章
- [PHP] 使用 pcntl 库实现PHP多进程
- QTableWidget控件总结
- 2016年,新的开始
- CentOS6.5下Nginx1.7.4安装记录
- 读书-算法《程序设计导引及在线实践》-简单计算题5:装箱问题
- IPIP地址、ipv4ipv6、子网掩码、网段计算、网络广播ID计算、默认网关、DNS服务器、DHCP服务器
- Flask实战2问答平台-首页布局,功能完成
- 使用深度学习解决拍照文档复杂背景二值化问题
- java 代码 内存泄露_如何用Java编写一段代码引发内存泄露
- element手机验证格式_Excel数据验证:给数据把个关,工作效率有保障。