MyBatis介绍
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了、
google code,并且改名为MyBatis 。2013年11月迁移到Github。 MyBatis是一个优秀的持久层框架,
它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如
注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、
CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最
后由mybatis框架执行sql并将结果映射成java对象并返回。
mybatis下载
mybaits的代码由github.com管理,地址:https://github.com/mybatis/mybatis-3/releases
#{}和${}
#{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value。
select * from user where username like '%${value}%'
Mapper中一些写法:
传递pojo包装类
<!-- 使用包装类型查询用户
使用ognl从对象中取属性值,如果是包装对象可以使用.操作符来取内容部的属性
-->
<select id="findUserByQueryVo" parameterType="queryvo" resultType="user">
SELECT * FROM user where username like '%${user.username}%'
</select>
where标签引用一个sql片段:
定义resultMap
<id />:此属性表示查询结果集的唯一标识,非常重要。如果是多个字段为复合唯一约束则定义多个<id />。
mysql开启多条语句修改配置
allowMultiQueries=true
jdbc:mysq?characterEncoding=UTF-8&allowMultiQueries=true
mybatis中:
<update id="rm" parameterType="java.util.List">
<foreach collection="list" item="item" index="index" separator=";">
UPDATE rm
<set>
<trim suffixOverrides=",">
<if test="item.nodeState != null">
nodeState = #{item.nodeState},
</if>
</trim>
</set>
WHERE ruleId = ${item.ruleId}
</foreach>
</update>
mysql自增主键返回
通过修改sql映射文件,可以将mysql自增主键返回:
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
<!-- selectKey将主键返回,需要再返回 -->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
select LAST_INSERT_ID()
</selectKey>
insert into user(username,birthday,sex,address)
values(#{username},#{birthday},#{sex},#{address});
</insert>
添加selectKey实现将主键返回
keyProperty:返回的主键存储在pojo中的哪个属性
order:selectKey的执行顺序,是相对与insert语句来说,由于mysql的自增原理执行完insert语句之后才将主键生成,所以这里selectKey的执行顺序为after
resultType:返回的主键是什么类型
LAST_INSERT_ID():是mysql的函数,返回auto_increment自增列新记录id值。
Mysql使用 uuid实现主键
需要增加通过select uuid()得到uuid值
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
<selectKey resultType="java.lang.String" order="BEFORE"
keyProperty="id">
select uuid()
</selectKey>
insert into user(id,username,birthday,sex,address)
values(#{id},#{username},#{birthday},#{sex},#{address})
</insert>
注意这里使用的order是“BEFORE”
SqlMapConfig.xml中配置的内容和顺序
properties(属性)
settings(全局配置参数)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mappers(映射器)
别名
mybatis默认支持别名
自定义别名
<typeAliases>
<!-- 单个别名定义 -->
<typeAlias alias="user" type="cn.itcast.mybatis.po.User"/>
<!-- 批量别名定义,扫描整个包下的类,别名为类名(首字母大写或小写都可以) -->
<package name="cn.itcast.mybatis.po"/>
<package name="其它包"/>
</typeAliases>
加载mapper文件的几种写法
加载指定包下的所有mapper接口如:
<mappers>
<package name="cn.itcast.mybatis.mapper"/>
</mappers>
使用mapper接口类路径
<mappers>
<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>
</mappers>
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
使用相对于类路径的资源
<mappers>
<mapper resource="com/itheima/mybatis/mapper/UserMapper.xml" />
</mappers>
扫描包形式配置mapper
<!--
第一种:原始Dao开发
第二种:Mapper动态代理开发
第三种:第二种的加强版 扫描式Mapper动态 代理开发
-->
<!-- 原始Dao开发 -->
<!-- <bean id="userDao" class="com.itheima.mybatis.dao.UserDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean> -->
<!-- <bean class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.itheima.mybatis.mapper.UserMapper"/>
<property name="sqlSessionFactory" ref="sqlSessionFactoryBean"/>
</bean> -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.itheima.mybatis.mapper"/>
</bean>
动态sql
if、where标签
<!-- 传递pojo综合查询用户信息 -->
<select id="findUserList" parameterType="user" resultType="user">
select * from user
<where>
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</where>
</select>
<where />可以自动处理第一个and。
foreach
<if test="ids!=null and ids.size>0">
<foreach collection="ids" open=" and id in(" close=")" item="id" separator="," >
#{id}
</foreach>
</if>
<!-- 集合List public List<User> findUserByIdsWithList(List<Integer> ids);-->
<select id="findUserByIdsWithList" parameterType="List" resultType="User">
<include refid="selector"/>
<where>
id in
<foreach collection="list" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</where>
</select>
<!--
传入多个ID 1: List<Integer> ids
Integer[] ids == parameterType="Integer" 或 parameterType="Integer[]" 全都正确
2: POJO类里面 List<Integer> ids 或 Integer[] ids
-->
<select id="findUserByIdsWithArray" parameterType="Integer[]" resultType="User">
<include refid="selector"/>
<where>
id in
<foreach collection="array" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</where>
</select>
Sql片段
Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的,如下:
sql片段:
<sql id="query_user_where">
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</sql>
引入:
<select id="findUserList" parameterType="user" resultType="user">
select * from user
<where>
<include refid="query_user_where"/>
</where>
</select>
注意:如果引用其它mapper.xml的sql片段,则在引用时需要加上namespace,如下:
<include refid="namespace.sql片段”/>
resultMap映射一对一查询结果
实体类:
Mapper.xml:
一对一关联映射 :
<!-- 查询订单关联用户信息使用resultmap -->
<resultMap type="Orders" id="orderUserResultMap">
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
<!-- 一对一关联映射 -->
<!--
property:Orders对象的user属性
javaType:user属性对应 的类型
-->
<association property="user" javaType="cn.itcast.po.User">
<!-- column:user表的主键对应的列 property:user对象中id属性-->
<id column="user_id" property="id"/>
<result column="username" property="username"/>
<result column="address" property="address"/>
</association>
</resultMap>
association:表示进行关联查询单条记录
property:表示关联查询的结果存储在cn.itcast.mybatis.po.Orders的user属性中
javaType:表示关联查询的结果类型
<id property="id" column="user_id"/>:查询结果的user_id列对应关联对象的id属性,这里是<id />表示user_id是关联查询对象的唯一标识。
<result property="username" column="username"/>:查询结果的username列对应关联对象的username属性。
查询语句:
<select id="findOrdersWithUserResultMap" resultMap="orderUserResultMap">
SELECT
o.id,
o.user_id,
o.number,
o.createtime,
o.note,
u.username,
u.address
FROM
orders o
JOIN `user` u ON u.id = o.user_id
</select>
resultMap映射一对多查询结果
实体类:
Mapper.xml
一对多关联映射:
<resultMap type="user" id="userOrderResultMap">
<!-- 用户信息映射 -->
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="birthday" column="birthday"/>
<result property="sex" column="sex"/>
<result property="address" column="address"/>
<!-- 一对多关联映射 -->
<collection property="orders" ofType="orders">
<id property="id" column="oid"/>
<!--用户id已经在user对象中存在,此处可以不设置-->
<!-- <result property="userId" column="id"/> -->
<result property="number" column="number"/>
<result property="createtime" column="createtime"/>
<result property="note" column="note"/>
</collection>
</resultMap>
collection部分定义了用户关联的订单信息。表示关联查询结果集
property="orders":关联查询的结果集存储在User对象的上哪个属性。
ofType="orders":指定关联查询的结果集中的对象类型即List中的对象类型。此处可以使用别名,也可以使用全限定名。
<id />及<result/>的意义同一对一查询。
查询语句:
<select id="getUserOrderList" resultMap="userOrderResultMap">
SELECT
u.*, o.id oid,
o.number,
o.createtime,
o.note
FROM
`user` u
LEFT JOIN orders o ON u.id = o.user_id
</select>
mybatis的逆向工程
详细见资料