这是MyBatis系列第1篇。大概会用十三篇的篇幅来讲解MyBatis,喜欢这个系列的欢迎关注公众号【Java冢狐】获取最新文章。那么废话不多说,让我们开始吧!
没有MyBatis的时代
要说起MyBatis,那要从还没有MyBatis的时代的时候说起。那个时候我们进行数据库开发的,大多使用jdbc来进行。但是JDBC的操作数据库用起来真的是头大。十分的繁琐和无聊,很容易出现问题和错误。其中具体的情况如下所示:
JDBC时代
连接使用数据库的过程:
- 加载驱动
- 获取连接
- 拼接sql
- 执行sql
- 获取结果
- 解析结果
- 关闭数据库
上面这些操作都是我们使用jdbc连接数据库的时候必须经过的过程。可以看出步骤十分的繁琐,关键是这些步骤中很多都不是我们程序员真正关心的,我们程序员真正关心的只有拼接sql、执行sql和解析结果。
但是基于JDBC得框架下,其他的操作又不得不去编写和操作,使得我们在代码编写上十分的吃力和冗余,对于程序员来说不是特别的友好。
JDBC缺点
正如上面所说的,JDBC有着一些很致命的缺点,总体来说有一下几个方面:
- 重复代码过多
- 每个操作耗时过多
- 调试维护麻烦
- 动态sql方面没有规范,难以维护
正是因为JDBC有着一些致命的缺点才导致我们使用其他的框架来完成与数据库的交互,诸如Hibernate和MyBatis就是其中比较好的代表。
Hibernate
介绍hibernate之前,我们先了解一下什么是ORM?
ORM
ORM:对象关系映射,简单点说就是将数据库中的表和java中的对象建立映射关系,可以让我们操作对象来间接的操作数据库。
ORM最好的框架就是hibernate,hibernate可以让你通过java对象来间接的操作数据库。对于开发者来说更加容易上手,也隐藏了底层jdbc和db的交互过程,对于程序员来说兼容了不同的数据库,但是对程序员来说是无感的。只需要像操作对象一样操作数据库即可
其甚至方便到了即使你不会sql也能通过它来操作数据库,可以说是十分的友好了,尤其是对于初入职场和工作经验差的小伙伴来说。
优点
总结起来优点就是:
- 简化了整个jdbc操作过程
- 需要去操作对象,不需要关心sql,hibernate可以帮我们自动生成所需要的sql
- 代码移植性比较好,通过hibernate操作db都是通过操作对象来进行的,如果我们需要切换db的类型,hibernate会自动适应,对于开发者业务代码来说不需要做任何业务代码上的调整
- 开发效率比较高
缺点
正所谓有的就有失,我们获得了这些方便,那也有一些相应的缺点和不足。
- sql优化比较艰难,各种操作最终发给db的,而sql是由hibernate自动生成的,对于开发者来说如果想干预最终需要执行的sql,相对来说比较困难
- hibernate入门比较容易,精通难
- 对于复杂的动态sql,代码中也需要写很多判断进行组装,动态sql这块的支持比较欠缺
所以说Hibernate只适合做一些简单的系统,或者是开发周期比较紧张的系统,对sql优化不高的项目。
MyBatis
而mybatis将sql交由开发者去控制,所以开发者来说比较自由自在,没有过多的限制,可以尽情的实现各种公司各种奇奇怪怪的业务和逻辑,在SQL优化方面,也是能够发挥程序员的能力,可谓是好坏皆有自己定。而Mybatis只是帮我们把重复性的工作优化到了极致,例如操作db的过程、动态sql的拼接,结果和对象的映射都帮我们处理完成了,不需要我们过多的操心和关注。让我们把更多的精力放在sql的编写上,所以这也受到了国内很多大厂的青睐,所以要想年后进入大厂那必须要掌握起来。
言而总之MyBatis:
- 是一款优秀的持久层框架
- 几乎避免了所有的JDBC代码和寿佛那个设置参数以及获取结果集的过程。
- 使用简单的XML或者注释来配置和映射原生信息,将接口和Java的实体类映射成数据库中的记录
mybatis开发项目的具体步骤
上面说的这么好,总归是骡子是马要拉出来遛一遛,那么接下来我们就一起搭建一个Mybatis项目的架子,在下一篇文章中会将其填充完成。并进行演示
Spring项目中引入mybatis maven配置
首先第一步就是要引入mybatis
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
上面的myba.ve.version版本,大家可以在maven仓库中寻找最新的,或者公司要求的版本。
创建mybatis配置文件
当我们引入Mybatis后,接下来就是要编写mybatis的配置文件。配置文件为xml格式,一般放在resource目录下。
如下所示:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties>
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatisdemo?characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/user.xml"/>
</mappers>
</configuration>
这个文件主要是对mybatis进行全局配置,比如数据源、事务的配置,如上面的datasource元素用来配置数据源,数据源中就需要指定数据库的一些配置信息;在这里我就设置了我使用到的数据库的连续信息,大家可以根据自己的数据库更改这个代码。
现在对于代码并不是很了解没有关系,后续的文章会逐步进行讲解和分析。
创建mapper xml文件
这个文件中表示我们所有对表的操作。完成后然后再由上面的mybatis的配置文件来引入,如下所示
<mappers>
<mapper resource="mapper/user.xml"/>
</mappers>
mappers元素中可以有多个mapper文件,我们开发的项目中可能有很多表需要操作,那么对应会有很多mapper xml文件,我们都需要在mappers元素中进行引入,然后mybatis才会使用到。一般来说一个表对应一个mapper文件。
创建Mapper接口
上面我们创建了mybatis的配置文件和表操作文件,后面我们就需要用一个Mapper接口来和我们上面一步中的mapper.xml来建立映射关系。
后续当我们调用Mapper接口中的方法的时候,会间接的调用到mapper xml中的各种数据的sql操作。
Mapper接口与xml文件关联
上面我们创建了Mapper接口和xml文件,但是这两者又是如何建立关联的呢?
这就需要uesr.xml中进行配置,如下所示
<mapper namespace="zhonghu.mybatis.chat01.UserMapper"
注意上面的namespace的值,对应的是UserMapper这个接口完整的引用,通过这个namespace,UserMapper接口就可以user.xml建立了映射关系。
user.xml中又有很多db操作,这些操作会和UserMapper接口中的方法建立映射关系,当调用UserMapper中的方法的时候,间接的会调用到user.xml中对应的操作。
如user.xml中有下面一段配置:
<!-- 批量插入 -->
<insert id="insertBatch" parameterType="map">
<![CDATA[ INSERT INTO `user` (`id`, `name`, `age`, `salary`) VALUES ]]>
<foreach collection="list" separator="," item="item">
(#{item.id}, #{item.name}, #{item.age}, #{item.salary})
</foreach>
</insert>
而UserMapper中有个insertBatch方法和上面这个insert批量插入对应,如下:
/**
* 批量插入用户信息
*
* @param userModelList
*/
void insertBatch(List<UserModel> userModelList);
所以当我们调用UserMapper中的insertBatch方法的时候,会间接调用到user.xml中的id ="insertBatch"这个操作。
下面我们就可以使用mybatis来操作db了。
接口和mapper xml映射起来间接调用,是通过java动态代理实现的。
通过mybatis获取Mapper接口执行对db的操作
上面我们说了,我们可以通过mapper接口来执行对db的操作,获取Mapper的主要代码如下:
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"));
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
上面代码中使用到了mybatis中的核心组件,我们具体来看一下。
Mybatis核心对象介绍
SqlSessionFactoryBuilder
这个是一个构建器,是用来构建SqlSessionFactory对象的,SqlSessionFactoryBuilder可以通过读取mybatis的配置文件,然后构建一个SqlSessionFactory对象。
SqlSessionFactoryBuilder将mybatis配置文件、mapper xml文件、mapper xml文件和Mapper 接口的映射关系,这些都先给解析好,然后放在java对象中,java对象存在于内存中,内存中访问会非常快的,那么我们每次去用的时候就不需要重新去解析xml了,SqlSessionFactoryBuilder解析配置之后,生成的对象就是SqlSessionFactory,这个是一个重量级的对象,创建他是比较耗时的,所以一般一个db我们会创建一个SqlSessionFactory对象,然后在系统运行过程中会一直存在,而SqlSessionFactoryBuilder用完了就可以释放了。
SqlSessionFactory
通过名字可以知道,这个是一个工厂,是用来创建SqlSession的工厂。
如上面所说SqlSessionFactory是一个重量级的对象,一般一个db对应一个SqlSessionFactory对象,系统运行过程中会一直存在。
SqlSessionFactory是一个接口,这个接口有2个实现DefaultSqlSessionFactory和SqlSessionManager,一般都是通过SqlSessionFactoryBuilder来创建SqlSessionFactory对象。
通过SqlSessionFactoryBuilder来创建SqlSessionFactory对象主要有2种方式,一种通过读取mybatis配置文件的方式,另外一种是硬编码的方式。
SqlSession
我们通过jdbc操作数据库需要先获取一个Connection连接,然后拿着这个连接去对db进行操作,在mybatis中SqlSession就类似于jdbc中Connection连接对象,在mybatis中叫做Sql会话对象,一般我们一个db操作使用一个SqlSession对象,所以这个对象一般是方法级别的,方法结束之后,这个对象就销毁了,这个对象可以调用sqlSessionFactory.openSession的方法来进行获取。
我们可以直接通过SqlSession对象来调用mapper xml中各种db操作,需要指定具体的操作的id,id的格式为namespace.操作的id。
Mapper接口
我们可以通过SqlSession直接调用mapper xml中的db操作,不过更简单的以及推荐的方式是使用Mapper接口,Mapper接口中的方法和mapper xml文件中的各种db操作建立了映射关系,是通过Mapper接口完整名称+方法名称和mapper xml中的namespace+具体操作的id来进行关联的,然后我们直接调用Mapper接口中的方法就可以间接的操作db了,使用想当方便,Mapper接口需要通过SqlSession获取,传入Mapper接口对应的Class对象,然后会返回这个接口的实例,如:
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
最后
- 如果觉得看完有收获,希望能关注一下,顺便给我点个赞,这将会是我更新的最大动力,感谢各位的支持
- 欢迎各位关注我的公众号【java冢狐】,专注于java和计算机基础知识,保证让你看完有所收获,不信你打我
- 求一键三连:点赞、转发、在看。
- 如果看完有不同的意见或者建议,欢迎多多评论一起交流。感谢各位的支持以及厚爱。
——我是冢狐,和你一样热爱编程。
欢迎关注公众号“ Java冢狐”,获取最新消息
来源:oschina
链接:https://my.oschina.net/u/4851357/blog/4942566