前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MyBatis学习总结(一)——ORM概要与MyBatis快速入门

MyBatis学习总结(一)——ORM概要与MyBatis快速入门

作者头像
张果
发布2018-10-09 12:09:02
8250
发布2018-10-09 12:09:02
举报
文章被收录于专栏:软件开发软件开发

程序员应该将核心关注点放在业务上,而不应该将时间过多的浪费在CRUD中,多数的ORM框架都把增加、修改与删除做得非常不错了,然后数据库中查询无疑是使用频次最高、复杂度大、与性能密切相关的操作,我们希望得到一种使用方便,查询灵活的ORM框架,MyBatis可以满足这些要求,MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架,它也是SSM框架集成中的重要组成部分。

一、ORM

1.1、ORM简介

ORM可以解决数据库与程序间的异构性,比如在Java中我们使用String表示字符串,而Oracle中可使用varchar2,MySQL中可使用varchar,SQLServer可使用nvarchar。

对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),用于实现面向对象编程语言里不同类型系统的数据之间的转换。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象与关系数据库相互映射。

没有ORM时我们是这样完成对象与关系数据库之间的映射的:

这种方案存在以下不足: 

持久化层缺乏弹性。一旦出现业务需求的变更,就必须修改持久化层的接口

持久化层同时与域模型与关系数据库模型绑定,不管域模型还是关系数据库模型发生变化,都要修改持久化曾的相关程序代码,增加了软件的维护难度。

将和数据库交互(CRUD)的代码硬编码到JDBC程序中

实现见状的持久化层需要高超的开发技巧,而且编程量很大

对象模型和关系模型的转换非常麻烦

ORM(O/R Mapping:对象关系映射):

一种将内存中的对象保存到关系型数据库中的技术

负责实体域对象的持久化,封装数据库访问细节

ORM提供了实现持久化层的另一种模式,采用映射元数据(XML)来描述对象-关系的映射细节,使得ORM中间件能在任何一个Java应用的业务逻辑层和数据库之间充当桥梁。

ORM提供了实现持久化层的另一种模式,它采用映射元数据来描述对象关系的映射,使得ORM中间件能在任何一个应用的业务逻辑层和数据库层之间充当桥梁。

Java典型的ORM中有:

hibernate:全自动的框架,强大、复杂、笨重、学习成本较高

Mybatis:半自动的框架(懂数据库的人 才能操作) 必须要自己写sql

JPA:JPA全称Java Persistence API、JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,是Java自带的框架

ORM的方法论基于三个核心原则:

  · 简单:以最基本的形式建模数据。

  · 传达性:数据库结构被任何人都能理解的语言文档化。

  · 精确性:基于数据模型创建正确标准化了的结构。

1.2、ORM的概念

让我们从O/R开始。字母O起源于"对象"(Object),而R则来自于"关系"(Relational)。几乎所有的程序里面,都存在对象和关系数据库。在业务逻辑层和用户界面层中,我们是面向对象的。当对象信息发生变化的时候,我们需要把对象的信息保存在关系数据库中。

当你开发一个应用程序的时候(不使用O/R Mapping),你可能会写不少数据访问层的代码,用来从数据库保存,删除,读取对象信息,等等。你在DAL中写了很多的方法来读取对象数据,改变状态对象等等任务。而这些代码写起来总是重复的。

ORM解决的主要问题是对象关系的映射。域模型和关系模型分别是建立在概念模型的基础上的。域模型是面向对象的,而关系模型是面向关系的。一般情况下,一个持久化类和一个表对应,类的每个实例对应表中的一条记录,类的每个属性对应表的每个字段。

将关系数据库中表中的记录映射成为对象,以对象的形式展现,程序员可以把对数据库的操作转化为对对象的操作。

因此ORM的目的是为了方便开发人员以面向对象的思想来实现对数据库的操作。

1.3、ORM的优缺点

优点:

1.提高了开发效率。由于ORM可以自动对Entity对象与数据库中的Table进行字段与属性的映射,所以我们实际可能已经不需要一个专用的、庞大的数据访问层。

2.ORM提供了对数据库的映射,不用sql直接编码,能够像操作对象一样从数据库获取数据。

缺点:

牺牲程序的执行效率和会固定思维模式,降低了开发的灵活性。

从系统结构上来看,采用ORM的系统一般都是多层系统,系统的层次多了,效率就会降低。ORM是一种完全的面向对象的做法,而面向对象的做法也会对性能产生一定的影响。

在我们开发系统时,一般都有性能问题。性能问题主要产生在算法不正确和与数据库不正确的使用上。ORM所生成的代码一般不太可能写出很高效的算法,在数据库应用上更有可能会被误用,主要体现在对持久对象的提取和和数据的加工处理上,如果用上了ORM,程序员很有可能将全部的数据提取到内存对象中,然后再进行过滤和加工处理,这样就容易产生性能问题。

在对对象做持久化时,ORM一般会持久化所有的属性,有时,这是不希望的。

但ORM是一种工具,工具确实能解决一些重复,简单的劳动。这是不可否认的。但我们不能指望工具能一劳永逸的解决所有问题,有些问题还是需要特殊处理的,但需要特殊处理的部分对绝大多数的系统,应该是很少的。

二、MyBatis

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。

iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

2.1、MyBatis的特点

简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。

灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql基本上可以实现我们不使用数据访问框架可以实现的所有功能,或许更多。

解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。

提供映射标签,支持对象与数据库的ORM字段关系映射

提供对象关系映射标签,支持对象关系组建维护

提供XML标签,支持编写动态sql。

2.2、MyBatis工作流程

(1)、加载配置并初始化

触发条件:加载配置文件

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

(2)、接收调用请求

触发条件:调用Mybatis提供的API

传入参数:为SQL的ID和传入参数对象

处理过程:将请求传递给下层的请求处理层进行处理。

(3)、处理操作请求 触发条件:API接口层传递请求过来 

传入参数:为SQL的ID和传入参数对象

处理过程:   (A)根据SQL的ID查找对应的MappedStatement对象。

  (B)根据传入参数对象解析MappedStatement对象,得到最终要执行的SQL和执行传入参数。

  (C)获取数据库连接,根据得到的最终SQL语句和执行传入参数到数据库执行,并得到执行结果。

  (D)根据MappedStatement对象中的结果映射配置对得到的执行结果进行转换处理,并得到最终的处理结果。

  (E)释放连接资源。

(4)、返回处理结果将最终的处理结果返回。

无论是用过的hibernate,mybatis,你都可以法相他们有一个共同点:

在java对象和数据库之间有做mapping的配置文件,也通常是xml 文件

从配置文件(通常是XML配置文件中)得到 SessionFactory

由SessionFactory 产生 Session

在Session中完成对数据的增删改查和事务提交等

在用完之后关闭Session

2.3、MyBatis架构

Mybatis的功能架构分为三层:

API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。

数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。

基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。

2.4、MyBatis的主要成员如层次结构

主要成员:

Configuration:MyBatis所有的配置信息都保存在Configuration对象之中,配置文件中的大部分配置都会存储到该类中

SqlSession:作为MyBatis工作的主要顶层API,表示和数据库交互时的会话,完成必要数据库增删改查功能

Executor:MyBatis执行器,是MyBatis 调度的核心,负责SQL语句的生成和查询缓存的维护

StatementHandler:封装了JDBC Statement操作,负责对JDBC statement 的操作,如设置参数等

ParameterHandler:负责对用户传递的参数转换成JDBC Statement 所对应的数据类型

ResultSetHandler:负责将JDBC返回的ResultSet结果集对象转换成List类型的集合

TypeHandler:负责java数据类型和jdbc数据类型(也可以说是数据表列类型)之间的映射和转换

MappedStatement:MappedStatement维护一条<select|update|delete|insert>节点的封装

SqlSource:负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回

BoundSql:表示动态生成的SQL语句以及相应的参数信息

层次结构:

更多请参考:《深入理解mybatis原理》 MyBatis的架构设计以及实例分析

2.5、学习资源

mybatis3中文帮助:http://www.mybatis.org/mybatis-3/zh/index.html

mybatis-spring:http://www.mybatis.org/spring/zh/index.html

MyBatis中国分站:http://www.mybatis.cn/

源代码:https://github.com/mybatis/mybatis-3/

三、MyBatis快速入门示例

3.1、在IDEA中创建项目

普通java项目或者是Maven项目都可以,如下图所示:

3.2、添加依赖

下载地址:https://github.com/mybatis/mybatis-3/releases

网盘下载:http://pan.baidu.com/s/1hrB1guo

【MyBatis】

         mybatis-3.4.6.jar

【MYSQL驱动包】     mysql-connector-java-5.1.38-bin.jar

Maven POM

3、创建数据库和表,针对MySQL数据库

SQL脚本如下:

将SQL脚本在MySQL数据库中执行,完成创建数据库和表的操作,如下:

表中的数据如下:

3.3、添加Mybatis配置文件

在Resources目录下创建一个conf.xml文件,如下图所示:

conf.xml文件中的内容如下:

解释

3.4、定义表所对应的实体类

Student实体类的代码如下:

3.5、定义操作Student表的sql映射文件

在resources目录下创建一个mapper目录,专门用于存放sql映射文件,在目录中创建一个studentMapper.xml文件,如下图所示:

studentMapper.xml文件的内容如下:

解释

参考:https://www.cnblogs.com/hellokitty1/p/5216025.html

3.6、在配置文件中注册映射文件

在配置文件conf.xml中注册studentMapper.xml映射文件

3.7、编写数据访问类

StudentDao.java,执行定义的select语句

 执行过程解释:

1、mybatis配置

SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。

mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。

2、通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂

3、由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。

4、mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。

5、Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。

6、Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。

7、Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。

参考:https://www.cnblogs.com/selene/p/4604605.html

3.8、编写单元测试

 测试结果:

 3.9、IDEA中Junit插件与生成测试类位置

打开IntelliJ IDEA工具,Alt+Ctrl+S,打开设置窗口,点击进入Plugins。

从插件资源库中搜索JunitGenerator V2.0版本

安装此插件,重启IDEA就可以了。

现在可通过此工具自动完成test类的生成了,在需要进行单元测试的类中按 Alt+Insert

选中你要创建测试用例的方法即可。

IntelliJ IDEA JUnit Generator自动创建测试用例到指定test目录

修改生成位置:

修改模板文件:

测试类生成目录分析:

对应的目录结构为

${SOURCEPATH}是到src/main/java这一层

../是退到上一层目录的意思,对着图理解一下

四、基于XML的CRUD

五、基于注解的CRUD

参考的映射文件:

六、说明与注意事项

6.1.parameterType和resultType

parameterType:在映射文件中通过parameterType指定输入参数的类型。

resultType:在映射文件中通过resultType指定输出结果的类型

6.2.#{}和${}

#{}

#{}表示一个占位符号,#{}接收输入参数,类型可以是简单类型,pojo、hashmap;

如果接收简单类型,#{}中可以写成value或其它名称;

#{}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。使用#{}意味着使用的预编译的语句,即在使用jdbc时的preparedStatement,sql语句中如果存在参数则会使用?作占位符,我们知道这种方式可以防止sql注入,并且在使用#{}时形成的sql语句,已经带有引号,例,select? * from table1 where id=#{id}? 在调用这个语句时我们可以通过后台看到打印出的sql为:select * from table1 where id='2' 加入传的值为2.也就是说在组成sql语句的时候把参数默认为字符串。

${}

表示一个拼接符号,会引用sql注入,所以不建议使用${};

${}接收输入参数,类型可以是简单类型,pojo、hashmap;

如果接收简单类型,${}中只能写成value;

${}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。

使用${}时的sql不会当做字符串处理,是什么就是什么,如上边的语句:select * from table1 where id=${id} 在调用这个语句时控制台打印的为:select * from table1 where id=2 ,假设传的参数值为2 从上边的介绍可以看出这两种方式的区别,我们最好是能用#{}则用它,因为它可以防止sql注入,且是预编译的,在需要原样输出时才使用${},如, select * from ${tableName} order by ${id} 这里需要传入表名和按照哪个列进行排序 ,加入传入table1、id 则语句为:select * from table1 order by id 如果是使用#{} 则变成了select * from 'table1' order by 'id' 我们知道这样就不对了。

6.3.selectOne()和selectList()

selectOne表示查询出一条记录进行映射。如果使用selectOne可以实现使用selectList也可以实现(list中只有一个对象)。

selectList表示查询出一个列表(多条记录)进行映射。如果使用selectList查询多条记录,不能使用selectOne。

如果使用selectOne报错: org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 4

七、视频

https://www.bilibili.com/video/av32447485/

八、示例

https://git.coding.net/zhangguo5/MyBatis02.git

九、作业

1、请使用MyBatis完成一个用户管理的数据访问功能,要求实现根据用户名查询用户对象功能,表中至少5个字段。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-09-25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、ORM
    • 1.1、ORM简介
      • 1.2、ORM的概念
        • 1.3、ORM的优缺点
        • 二、MyBatis
          • 2.1、MyBatis的特点
            • 2.2、MyBatis工作流程
              • 2.3、MyBatis架构
                • 2.4、MyBatis的主要成员如层次结构
                  • 2.5、学习资源
                  • 三、MyBatis快速入门示例
                    • 3.1、在IDEA中创建项目
                      • 3.2、添加依赖
                        • 3.3、添加Mybatis配置文件
                          • 3.4、定义表所对应的实体类
                            • 3.5、定义操作Student表的sql映射文件
                              • 3.6、在配置文件中注册映射文件
                                • 3.7、编写数据访问类
                                  • 3.8、编写单元测试
                                    •  3.9、IDEA中Junit插件与生成测试类位置
                                      • 四、基于XML的CRUD
                                        • 五、基于注解的CRUD
                                          • 六、说明与注意事项
                                            • 6.1.parameterType和resultType
                                            • 6.2.#{}和${}
                                            • 6.3.selectOne()和selectList()
                                        • 七、视频
                                        • 八、示例
                                        • 九、作业
                                        相关产品与服务
                                        云数据库 MySQL
                                        腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
                                        领券
                                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档