1.为什么是MyBatis?
在我们的系统开发中,我们的业务逻辑最终基本都是基于数据库的内容的,所以这一过程就涉及到与数据库的增删改查各种操作,我们在javase的学习中,对数据库的操作都是基于JDBC的操作的,但是JDBC存在这么一个问题:所有的数据库连接的连接信息或者是SQL语句都是被我们固定地写死在Java代码中的,这在编程中我们称之为“硬编码”。硬编码这样的代码编写习惯会使我们后期的软件维护相当困难。因为只要数据库信息改变之后就意味着我们的java代码里的JDBC信息需要重新改写、重新编译。这一工作是相当影响我们的项目维护升级的,因此也就给后期维护升级人员带来一定程度的困难。另外JDBC的操作是通过数据库连接池来管理的,在系统运行中需要不断与数据库进行交互,这样JDBC流频繁的连接、断开造成相当大程度的开销。所以MyBatis应运而生。
2、MyBatis基本原理与架构
2.1、基本原理
硬编码问题解决:MyBatis通过实现java逻辑代码与数据库连接、操作配置信息分离的方式,提高Java系统的健壮性和可维护性,使得开发人员只用专心在java的实现逻辑,而数据库相关信息则可以通过xml的形式进行配置并在My Batis**会话工厂**进行读取、组装。
2.2、基本架构
2.2.1、数据源配置文件:SqlMapConfig.xml
数据源配置文件也就是负责连接数据库并对数据进行操作。也就是MyBatis的一个全局配置文件。在该文件中配置了数据库驱动、数据库连接地址、数据库用户名、密码、事务管理等一系列的参数。另外如果需要对数据库连接池性能调优,可以在该文件配置连接池的连接数和空闲时间参数等等。具体如下:
<?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>
<!-- 加载java的配置文件或者声明属性信息 -->
<properties resource="db.properties">
<property name="db.username" value="123" />
</properties>
<!-- <settings></settings> -->
<!-- 自定义别名 -->
<typeAliases>
<!-- 别名定义 -->
<!-- <typeAlias type="com.shanshui.mybatis.User" alias="user"/> -->
<!-- 批量别名定义) -->
<!-- package:指定包名称来为该包下的po类声明别名,默认的别名就是类名(首字母大小写都可) -->
<package name="com.itheima.mybatis.po" />
</typeAliases>
<!-- 配置mybatis的环境信息,与spring整合,该信息由spring来管理 -->
<environments default="development">
<environment id="development">
<!-- 配置JDBC事务控制,由mybatis进行管理 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置数据源,采用mybatis连接池 -->
<dataSource type="POOLED">
<property name="driver" value="${db.driver}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</dataSource>
</environment>
</environments>
<!-- 加载映射文件 -->
<mappers>
<mapper resource="User.xml" />
<!-- <mapper resource="mapper/UserMapper.xml" /> -->
**<!-- 批量加载映射文件 -->**
<package name="com.itheima.mybatis.mapper" />
</mappers>
</configuration>
2.2.2、SQL映射配置文件
同样的,在java的JDBC中的增删改查操作,不能硬编码形式的写在我们的Java代码中,在MyBatis中提供Mapper.xml文件中进行配置映射规则。在这个文件中我们可以配置需要的SQL语句。例如:select、delete、update、insert。在该文件中的配置信息,可以对SQL查询语句的执行参数(id、group等),以及查询返回值的集合对象形式。
也就是说,Mapper.xml文件就是对SQL语句以及其输入输出参数的配置。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- ==================代理方式=================
由mapper标签开始,由/mapper结束,可以把它想成一个空间,是映射文件
属性namespace:空间名,主要在代理中使用。这个namespace是唯一的。
这里把mapper标签和接口联系在一起了,namespace=写接口路径,映射文件要和接口在同一目录下
-->
<mapper namespace="com.dao.UserinfoDAO">
<!-- =============映射关系标签=============
属性type:写po类的包名类名,由于之前定义了po类的别名,这里就写这个别名
属性id:是这个映射标签的唯一标识
id标签是查询结果集中的唯一标识
属性column:查询出来的列名
属性property:是po类里所指定的列名
通常会在原列名后面加下划线,这是固定的,这里就是id后面_
-->
<resultMap type="com.po.UserinfoPO" id="userinfoMap">
<result column="userid" property="userid"/>
<result column="loginname" property="loginname"/>
<result column="loginpass" property="loginpass"/>
<result column="username" property="username"/>
<result column="upower" property="upower"/>
<result column="birthday" property="birthday"/>
<result column="sex" property="sex"/>
</resultMap>
<!-- ==================定义sql片段==============
sql:是sql片段标签属性id是该片段的唯一标识 -->
<sql id="zd">
userid,loginname,loginpass,username,upower,birthday,sex
</sql>
<!-- 增删改查标签里的id:一定要和接口里对应的方法名一致,
resultMap输出类型里写映射标签里的id
parameterType:输入类型,规范输入数据类型,指明查询时使用的参数类型-->
<!-- 验证登录 -->
<select id="login" resultMap="userinfoMap" parameterType="com.po.UserinfoPO">
<!-- 用include标签引入sql片段,refid写定义sql片段的id,where标签不要写在片段里 -->
select <include refid="zd"/> from userinfo
<where>
loginname=#{loginname} and loginpass=#{loginpass}
</where>
</select>
<!-- 查询用户列表 -->
<select id="userList" resultMap="userinfoMap" parameterType="com.po.UserinfoPO">
<!-- 用include标签引入sql片段,refid写定义sql片段的id,where标签不要写在片段里 -->
select <include refid="zd"/> from userinfo
</select>
<!-- 查询修改用户信息的id -->
<select id="updateid" resultMap="userinfoMap" parameterType="com.po.UserinfoPO">
<!-- 用include标签引入sql片段,refid写定义sql片段的id,where标签不要写在片段里 -->
select <include refid="zd"/> from userinfo
<where>userid=#{userid}</where>
</select>
<!-- 修改用户信息 -->
<update id="update" parameterType="com.po.UserinfoPO">
update userinfo
set loginname=#{loginname},loginpass=#{loginpass},username=#{username},
upower=#{upower},birthday=#{birthday},sex=#{sex}
where userid=#{userid}
</update>
<!-- 添加用户信息 -->
<insert id="insert" parameterType="com.po.UserinfoPO">
insert into userinfo(<include refid="zd"/>)
values
(#{userid},#{loginname},#{loginpass},#{username},#{upower},#{birthday},#{sex})
</insert>
<!-- 增删改查标签里的id:一定要和接口里对应的方法名一致 -->
<delete id="delete" parameterType="int">
delete from userinfo where userid=#{userid}
</delete>
<!-- 根据用户名模糊查询,根据权限查询 -->
<select id="select" resultMap="userinfoMap" parameterType="java.util.Map">
<!-- 用include标签引入sql片段,refid写定义sql片段的id,where标签不要写在片段里 -->
select <include refid="zd"/> from userinfo
<!-- 当页面没有输入用户名和选择权限,就让它的条件永远为真,就变成全查询了 -->
<where>
<if test="username == null and username = '' and upower == -1">
and 1=1
</if>
<if test="username != null and username !=''">
and username LIKE '%${username}%'
</if>
<if test="upower != -1">
and upower=#{upower}
</if>
</where>
</select>
</mapper>
Mapper.xml的文件路径一般就是在SqlMapConfig.xml的全局文件中配置好,例如:
<mappers>
<mapper resource="User.xml" />
<!-- <mapper resource="mapper/UserMapper.xml" /> -->
2.2.3、会话工厂、会话
在准备好了我们 所需要的连接池信息和操作配置信息之后。就需要相应的程序段来执行这一数据库语句,在MyBatis中这个核心主体就是会话工厂和会话。
会话工厂,我们知道在设计模式中,工厂模式就对应着生成规范的对象的类。会话工厂是SqlSessionFactory的类。它根据配置文件中的信息。读取之后加载相应的会话SqlSession的类实例对象。
2.2.4、执行器Executor 和底层对象封装Mappered Statement
在以上步骤完成之后呢,就可以通过执行器Executor与底层封装对象Mappered Statement的结合,这样一来就实现了MyBatis与数据库的交互。
3.MyBatis初探总结
MyBatis说到底也就是Java基本功能的一个封装实现的类库,和Hibernate框架一样,作为数据持久层存在。把Java中存在很多暗病的传统JDBC形式进行抽象封装。这也充分功能逻辑与数据配置的分离,各司其职的开发特点。更多关于MyBatis的学习在后续文章更新。
By shanshui 2018.06.08