Mybatis
JDBC连接数据库存在的问题
1.数据库的连接频繁的开启关闭
2.sql语句,占位符,结果集遍历时所需的列名都存在硬编码问题
Mybatis架构
mapper.xml文件结构
文件名建议用 表名+mapper.xml
<mapper namespace="xxx">
namespace是为了对sql语句进行隔离,方便管理
<关键字 id="#" parameterType="#" resultType="#">
...
</关键字>
</mapper>
关键字有 select update delete insert
#{ } 和 ${ }的区别
#{ } 里面存放的值是保留其属性的,即不能拼接字符串
${ } 将接收到的参数不加修饰的拼接在sql中,这里去掉了属性,所以模糊查询时可以 '%${ }%',但这样会存在sql注入的问题.
获取插入记录后的主键
<insert id="#" parameterType="xxx.xxx.User" >
<selectKey keyProperty="id" order="AFTER" resultType="int">
select LAST_INSERT_ID()
</selectKey>
insert into userTable (name,password) values(#{name},#{password})
</insert>
其返回值存储在传入参数user对象的id属性中
keyProperty是User里的属性
order是相对于sql的顺序
插入记录前自动获取主键
使用mysql的uuid()机制自动生成主键
不需要考虑数据库移植后主键冲突的问题
<insert id="#" parameterType="xxx.xxx.User" >
<selectKey keyProperty="id" order="BEFORE" resultType="int">
select uuid()
</selectKey>
insert into userTable (id,name,password) values(#{id},#{name},#{password})
</insert>
Mapper代理的开发方式
只需要写Dao接口,接口的实现由Mybatis自动生成代理对象
Mapper的开发规范
1.mapper.xml的namespace为接口的全限定名
2.mapper.xml中的statement的id就是接口中的方法名
3.mapper.xml中的parameterType传入类型就是接口方法中的参数类型
4.mapper.xml中的resultType的类型就是接口方法中返回值类型
Mapper在SqlMapperConfig.xml中的加载方式
<mappers>
<mapper resource="xxx/xxx/mapper.xml"/>
</mappers>
Mapper接口返回对象或集合类型
无论返回的是对象还是集合类型,resultType中传入的都是对象类型.返回什么类型,取决于Mapper接口,当接口返回类型为对象类型时,Mybatis内部调用的是selectOne方法,当返回类型为集合时,内部调用的时select方法.
Mapper接口参数的问题
使用Mapper接口开发时,接口中只定义一个参数是否可行.
1.对象类型作为参数传递,本身就具有可扩展性,可以使用装饰类
2.Mapper接口位于Dao层,方法是通用的
sqlMapperConfig.xml
SqlMapConfig.xml中配置的内容和顺序如下:
properties(属性)
settings(全局配置参数)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mappers(映射器)
Properties
可以把通用的属性值配置在属性文件中,加载到mybatis的运行环境中
比如:创建db.properties的数据库连接参数属性文件
<properties resource="xxx.xxx.db.properties"/>
用${ }去引用文件中的Key值,比如${jdbc.driverClass}
注意
1.properties元素体内的属性首先被读取
2.然后读取resource或url中文件中的属性,若重复则覆盖之前
3.读取parameterType传递的参数,若重名则覆盖之前
建议使用properties,不要在properties体内定义属性,只用resource或url中的属性文件,并且属性文件中的key值要有特殊规则
settings全局参数配置
mybatis运行时可以调整一些全局参数(相当于软件的运行参数),根据使用需求进行参数配置。
注意:小心配置,配置参数会影响mybatis的执行。
ibatis的全局配置参数中包括很多的性能参数(最大线程数,最大待时间。。。),通过调整这些性能参数使ibatis达到高性能的运行,mybatis没有这些性能参数,由mybatis自动调节。
typeAliases(常用)
可以将parameterType和resultType中的参数类型设置别名
自定义别名
<typeAliases>
<typeAlias type="xxx.xxx.User" alias="user"/>
</typeAliases>
批量别名定义
<package name="com.xxx.xxx">
则在com.xxx.xxx的包下的类,全部可以用首字母大写或小写的别名
别名可以在parameterType和resultType中使用
Mappers
加载mapper,在和spring整合后,就可以通过mapper扫描器加载,不用再配置了
<mappers>
<mapper resource="xxx/xxx/mapper.xml"/>
或者可以用class加载接口,但要求.java和.xml同名且在一个包下
<mapper class="xxx.xxx.User"/>
或者可以用package扫描的方式加载多个,但要求.java和.xml同名且在一个包下
<package name="xxx.xxx.xxx"/>
</mappers>
resultType
sql查询的列名要和resultType中的pojo属性名相同,不然无法映射成功
resultMap
resultMap配置
<resultType id="#" type="#">
<id column="#" property="#">
<result column="#" property="#">
<result column="#" property="#">
...
</resultMap>
id是resultMap在mapper中的唯一标识名
type是其映射的对象类型
<id>是表的主键列名标签,colunm是列名,property是映射名
<result>是表的其他列名标签
resultMap的使用
若resultMap和mapper在一个文件中,那么
<select id="#" parameterType="#" resultMap="id">
若resultMap和mapper不在一个文件中,那么
<select id="#" parameterType="#" resultMap="xxx.id">
xxx表示resultMap所在mapper的namespace
动态sql(重点)
mybatis的重点是对sql的灵活处理与解析
sql片段
通过sql片段将通用的sql语句抽取出来,在不同的statement中使用
sql片段的定义
sql片段抽取的是对单表的操作,提高通用性
sql片段中不要包含<where>,因为在一个statement中可能会使用多个sql片段
<sql id="#" >
<if test="userCustom != null">
<if test="userCustom.name != null and userCustom.name != ' ' ">
and name like #{userCustom.name}
</if>
<if test="...">
</if>
</if>
</sql>
sql片段的使用
<select id="#" parameterType="#" resultType="#">
select * from userTable
<where>
<include refid="id" />
<include refid="#" />
...
</where>
</select>
<where>可以自动删除第一个and
当sql片段和statement在一个mapper时,可以直接使用sql片段的id
当sql片段和statement不在一个mapper时,需要使用sql片段所在的mapper的namespace.sqlid
foreach
在statement中通过foreach遍历集合
<select id ="#" parameterType="#" resultType="#">
<!--select * from user where id in (1,2,3) ->
select * from user
<where>
<foreach collection="ids" open="and id in (" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
2019.03.28