MyBatis介绍
MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
MyBatis架构
MyBatis配置
sqlMapConfig.xml
此文件为mybatis的全局配置文件,配置了MyBatis的运行环境等信息,在classpath路径下。
sqlMapConfig.xml示例内容:
<?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>
<!-- 加载配置文件,默认路径为classpath下 -->
<properties resource="jdbc.properties" />
<!-- 配置别名,这样在UserMapper.xml中就可以使用User代替com.zrxjuly.mybatis.pojo.User -->
<typeAliases>
<!-- 如果实体类较多的话,这样配就很麻烦
<typeAlias type="com.zrxjuly.mybatis.pojo.User" alias="User" />
-->
<!-- 使用package,这样把该包下的实体类都配置成别名,别名名称为类名。
eg:如果 com.zrxjuly.mybatis.pojo包下有个User的实体类,则别名为user或User.
-->
<package name="com.zrxjuly.mybatis.pojo"/>
</typeAliases>
<!-- 和spring整合后environments配置将废除 -->
<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>
<!-- 方式1.使用resource -->
<mapper resource="com/zrxjuly/mybatis/pojo/UserMapper.xml" />
<!-- 方式2.使用class,指定写sql语句的文件的位置,并且pojo的类名要和mapper文件的类名一致 -->
<!-- <mapper class="com.zrxjuly.mybatis.pojo.UserMapper"/> -->
</mappers>
</configuration>
sql映射文件
文件中配置了操作数据库的sql语句,此文件需要在sqlMapConfig.xml中加载。
UserMapper.xml文件示例内容:
<?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 namespace="com.zrxjuly.mybatis.mapper.UserMapper">
<!-- 通过id查询一个用户.
parameterType:代表传入sql语句中的参数的类型.
parameterMap:已经废弃.
返回类型用resultType或resultMap表示.
resultType:自动映射。前提:实体类中的属性名要与数据库表中的字段名对应。
resultMap:手动映射-当实体类中的属性名与数据库表中的字段名不一致时使用。
#{参数}:参数名称可以任意取
-->
<select id="findUserById" parameterType="Integer" resultType="User">
select * from user where id = #{id}
</select>
<!-- 根据用户名称模糊查询用户列表
注意以下区别:
#{}: select * from user where id = ?; 占位符时用#,此时?=='参数'
${}: select * form user where username like '%${参数}%'; 字符串拼接时用$
使用 select * from user where username like "%"#{value}"%"防止sql注入
${}中的参数名称必须是value.
-->
<select id="findUserByUsername" parameterType="String" resultType="com.zrxjuly.mybatis.pojo.User">
select * from user where username like "%"#{value}"%"
</select>
<!-- 添加用户 -->
<insert id="insertUser" parameterType="com.zrxjuly.mybatis.pojo.User">
<!-- 要想返回给操作层主键值,则加selectKey.
selectKey表示返回的主键,keyProperty:主键的属性名称,resultType:返回的类型,
order:若主键类型为Integer类型,自增长,此时order用AFTER;若主键为char/varchar类型,order用BEFORE -->
<selectKey keyProperty="id" resultType="Integer" order="AFTER">
select LAST_INSERT_ID()
</selectKey>
insert into user (username,birthday,address,sex)
values (#{username},#{birthday},#{address},#{sex})
</insert>
<!-- 修改用户. -->
<select id="updateUser" parameterType="com.zrxjuly.mybatis.pojo.User">
update user
set username=#{username},birthday=#{birthday},address=#{address},sex=#{sex}
where id=#{id}
</select>
<!-- 删除用户. -->
<delete id="deleteUserById" parameterType="Integer">
delete from user where id=#{id}
</delete>
</mapper>
#{}
和${}
区别
#{}
表示一个占位符号,通过#{}
可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换。#{}
可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
${}
表示拼接sql串,通过${}
可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, ${}
可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}
括号中只能是value。
parameterType
指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。
resultType
指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。如果有多条数据,则分别进行映射,并把对象放到容器List中
selectOne
查询一条记录
selectList
查询多条记录
mysql自增主键返回
<?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 namespace="com.zrxjuly.mybatis.mapper.UserMapper">
<!-- 添加用户 -->
<insert id="insertUser" parameterType="com.zrxjuly.mybatis.pojo.User">
<!-- 要想返回给操作层主键值,则加selectKey.
selectKey表示返回的主键,keyProperty:主键的属性名称,resultType:返回的类型,
order:若主键类型为Integer类型,自增长,此时order用AFTER;若主键为char/varchar类型,order用BEFORE -->
<selectKey keyProperty="id" resultType="Integer" order="AFTER">
select LAST_INSERT_ID()
</selectKey>
insert into user (username,birthday,address,sex)
values (#{username},#{birthday},#{address},#{sex})
</insert>
</mapper>
MySql使用uuid实现主键返回
需要增加select uuid()
得到uuid的值,此时selectKey的order值为BEFORE。
MyBatis与Hibernate比较
1.Mybatis与Hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句。MyBatis可以通过XML或注解方式灵活配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,最后将sql执行的结果再映射生成java对象。
2.MyBatis简单易学,程序员直接编写原生态sql,可严格控制sql执行性能,灵活度高,适合对关系数据模型要求不高的软件开发,eg:互联网软件、企业运营类软件等。但mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义sql映射文件,工作量大。
3.Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件如果用hibernate开发可以节省很多代码,提高效率。
4.总之,按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构。对于框架来说,适合的才是最好的。
Mapper动态代理
Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。
Mapper接口开发需要遵循以下规范:
1、Mapper.xml文件中的namespace与mapper接口的类路径相同。
2、Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
3、Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
4、Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
此篇文章仅是对MyBatis部分知识做了一个笔记,并非完整的案例。【这个是传到GitHub上的MyBatis案例】