.Net转Java自学之路—Mybatis框架篇三(输入/输出映射、动态SQL)
Mybatis输入映射:
通过parameterType指定输入参数的类型,类型可以是简单类型、hashmap、pojo的包装类型。
pojo的包装类型:
当完成一个功能需要传入复杂的条件时,需要使用pojo的包装类型。那么包装类型的pojo类型映射:
<select id="findUserList" parameterType="cn.ccir.mybatis.entity.UserQueryVo" resultType="cn.ccir.mybatis.entity.UserCustom"> select * from t_User where sex=#{user.sex} and username like #{user.username} </select>
定义User实体类的扩展类:
public class UserCustom extends User{ //扩展的属性。 }
在包装类型的pojo中将复杂的条件包装进去:
public class UserQueryVo{ private UserCustom userCustom; public UserCustom getUserCustom(){ return userCustom; } public void setUserCustom(UserCustom userCustom){ this.userCustom=userCustom; } }
在mapper接口中定义方法:
public List<UserCustom> findUserList(UserQueryVo user) thorws Exception;
Mybatis输出映射:
resultType:
使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,则列才可以映射成功。
若完全不一致,没有创建pojo对象。
若由一个或多个一致,就会创建pojo对象。
输出简单类型:
查询出来的结果集只有一行且一列,可以使用简单类型进行输出映射。
mapper配置文件:
<!-- 用户信息综合查询总数 --> <select id="findUserCount" parameterType="cn.ccir.mybatis.entity.UserQueryVo" resultType="int"> select count(*) from t_User where sex=#{user.sex} and username like #{user.username} </select>
在mapper接口中定义方法:
public int findUserCount(UserQueryVo user) thorws Exception;
输出pojo对象和pojo列表:
无论是输出的pojo单个对象还是一个列表,在mapper.xml中resultType指定的类型是不一样的。
在mapper接口指定的方法返回值类型不一样:
1、输出单个pojo对象,方法返回值是单个对象类型。
2、输出pojo对象列表,方法返回值是一个list。
resultMap:
Mybatis中使用resultMap完成高级输出结果映射。
使用方法:
查询出的列名和pojo的属性名不一致,可以通过定义一个resultMap对列名和pojo属性名之间作一个映射关系。
1、定义resultMap。
2、使用resultMap作为statement的输出映射类型。
配置文件:
<!-- 定义resultMap: type:resultMap最终映射的java对象类型,可以使用别名 id:对resultMap的唯一标识。 --> <resultMap type="user" id="userResultMap"> <!-- id标识查询结果集中唯一标识 column:查询出来的列名 property:type指定的pojo类型中的属性名 --> <id column="u_id" property="id"/> <!-- result:对普通列名定义 column:查询出来的列名 property:type指定的pojo类型中的属性名 --> <result column="u_name" property="username"/> </resultMap> <!-- resultMap:指定定义的resultMap的id属性值。若这个resultMap定义在其他的mapper.xml文件中,则前面需要加namespace --> <select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap"> select id u_id,username u_name from t_User where id=#{id} </select>
mapper接口:
public User findUserByIdResultMap(int id) throws Exception;
使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。若查询出来的列名和pojo中的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间作一个映射关系。
Mybatis的动态SQL:
动态sql:Mybatis核心对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活的拼接、组装。
判断:
<select id="findUserCount" parameterType="cn.ccir.mybatis.entity.UserQueryVo" resultType="int"> select count(*) from t_User <!-- sql拼接 where:可以自动去掉条件中第一个and --> <where> <if test="userCustom!=null"> <if test="userCustom.sex!=null and userCustom.sex!=''"> and sex=#{userCustom.sex} </if> <if test="userCustom.username!=null and userCustom.username!=''"> and username like '%${user.username}%' </if> </if> </where> </select>
若Java代码中不进行条件值设置,则sql语句中的该条件不会拼接。
SQL片段:
可以对动态的sql判断配置进行抽取,组成一个sql片段。作用,其它的statement中也可以引用该sql片段。
<!-- 定义sql片段: id:sql片段的唯一标识 一般sql片段是基于单表来定义sql片段,这样该sql片段可复用性才高。 在sql片段中不要包含where --> <sql id="query_user_where"> <if test="userCustom!=null"> <if test="userCustom.sex!=null and userCustom.sex!=''"> and sex=#{userCustom.sex} </if> <if test="userCustom.username!=null and userCustom.username!=''"> and username like '%${user.username}%' </if> </if> </sql> <!-- 引用sql片段 --> <select id="findUserCount" parameterType="cn.ccir.mybatis.entity.UserQueryVo" resultType="int"> select count(*) from t_User <where> <!-- 引用sql片段的id,若refid指定的id不再本mapper.xml文件中,需要前面加namespace --> <include refid="query_user_where"></include> <!-- 可以引用多个sql片段 --> <include refid=""></include> <include refid=""></include> <include refid=""></include> ...... </where> </select>
foreach:
若向sql传递数组或List,Mybatis使用foreach解析。如下Sql语句:
select * from t_user where username='' and (id=1 or id=2 or id=3)
在输入参数类型中添加List<Integer> ids 传入多个id。
在UserQueryVo中定义该属性。配置文件:
<if test="ids!=null"> <!-- 使用foreach遍历传入ids的值 collection:指定输入对象中集合属性 item:每次遍历生成对象中 open:开始遍历时拼接串 close:结束遍历时拼接的串 separator:遍历的俩个对象中需要拼接的串 --> <foreach collection="ids" item="_self" open="and (" close=")" separator="or"> id=#{_self} </foreach> </if>
select * from t_user where id in (1,2,3,4)
<if test="ids!=null"> <!-- 使用foreach遍历传入ids的值 collection:指定输入对象中集合属性 item:每次遍历生成对象中 open:开始遍历时拼接串 close:结束遍历时拼接的串 separator:遍历的俩个对象中需要拼接的串 --> <foreach collection="ids" item="_self" open="and id in (" close=")" separator=","> #{_self} </foreach> </if>