目录
1.概述
2.SQL映射文件元素
3.Mybatis框架的条件查询
3.1 单参数查询(模糊查询)
3.2 多参数查询
3.2.1 JavaBean 对象参数
3.2.2 Map 参数
3.2.3 @Param 注解 参数
3.2.4 底层顺序[param1,param2]
4.Mybatis框架的结果映射
4.1 resultMap自定义映射
4.1.1 ResultMap元素实现自定义结果映射
4.1.2 association 嵌套结果映射
4.1.3 collection 嵌套结果映射
4.1.4 resultType 和resultMap小结
4.1.5 自动映射配置
5.Mybtais框架的增删改操作
6.实现动态SQL
6.1 where + if 组合标签
6.2 choose 标签
6.3 foreach 标签
6.3.1foreach 元素
6.4 set 标签
6.5 trim 标签
6.5.1 trim标签中的元素
1.概述
在SQL映射文件中,只需根据MyBatis提供的标签写入SQL语句操作, 将SQL语句从程序的代码中分离出来,对JDBC访问数据库的代码进行封装,只需关注sql事务操作。
2.SQL映射文件元素
以下是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="dao.SysUserMapper">
<!--配置二级缓存-->
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
<!--插入标签-->
<insert></insert>
<!--更改标签-->
<update></update>
<!--查询标签-->
<select></select>
<!--删除标签-->
<delete></delete>
<!--自定义映射标签-->
<resultMap></resultMap>
......
</mapper>
3.Mybatis框架的条件查询
- sql语句中的#{} 代表一个占位符,可根据key 找到值
3.1 单参数查询(模糊查询)
- 查询一个条件的值时,不需写key 标识对应 如: Param, 一个参数时MyBtais会自动找到。
- Mapper 接口
/**
* 模糊查询用户姓名
*/
List<User> getLikeAllUser(String name);
- Mapper.xml 映射文件
<!--id 必须跟接口的方法一致-->
<!--resultType 返回结果类型-->
<select id="getLikeAllUser" resultType="user">
--模糊查询用户表里的名称
select * from user where username like CONCAT("%",#{username},"%")
</select>
3.2 多参数查询
3.2.1 JavaBean 对象参数
- Mapper 接口
/**
* 多条件模糊查询用户姓名
*/
List<User> getLikesAllUser(User user);
- Mapper.xml 映射文件
<select id="getLikesAllUser" resultType="user" parameterType="user">
select id,name,password from user where name like CONCAT("%",#{name},"%") and id=#{id}
</select>
3.2.2 Map 参数
- 直接根据map 的key 来找值
/**
* 根据Map 来查询用户信息
*/
List<User> getLikeUserByMap(Map<String,Object> map);
<select id="getLikeUserByMap" resultType="cn.bdqn.entity.User">
select id,name,password from user where name like CONCAT(#{name},"%") and password=#{password}
</select>
3.2.3 @Param 注解 参数
- 没使用@Param注解多参数查询前,遇到的问题:
/**
* 根据两个参数条件查询用户信息
*/
List<User> getLikeUsersNoByParam(String name,String password);
<select id="getLikeUsersNoByParam" resultType="user">
select id,name,password from user where name like CONCAT(#{name},"%") and password=#{password}
</select>
- 上述代码执行结果:
该代码出现异常,指定没有找到key .
报错原因:由于是多个参数传值,底层是key-value形式,而java编译时会将sql里的name,password转译成 [arg1,arg0,param1,param2],只限于JDK1.8中。如果不将key设置成底层格式,如param1,他就会找不到参数的顺序,所以会报错。
- 使用@param注解设置key 会自动跟sql里的key 进行匹配,顺序更好查找。
/**
* @param注解来查找用户信息
*/
List<User> getLikeUsersByParam(@Param("name") String name,@Param("password") String password);
/**
* 将@Param作为实体类的key查找
*/
List<User> getLikeUsersByJOUO(@Param("user") User user);
- @Param将实体类作为key时,sql中要通过它的key . 出来值
<!--sql语句中的值必须跟Param注解里的key一致-->
<select id="getLikeUsersByParam" resultType="cn.bdqn.entity.User">
select id,name,password from user where name like CONCAT(#{name},"%") and password=#{password}
</select>
<select id="getLikeUsersByJOUO" resultType="cn.bdqn.entity.User">
select id,name,password from user where name like CONCAT(#{user.name},"%") and password=#{user.password}
</select>
3.2.4 底层顺序[param1,param2]
- 实现多参数时,也可以使用底层顺序,但是sql中的值必须跟底层名称一样,如: param1,param2,一定要注意参数顺序。
<select id="getLikeUsers" resultType="cn.bdqn.entity.User">
select id,name,password from user where name like CONCAT(#{param1},"%") and password=#{param2}
</select>
4.Mybatis框架的结果映射
- MyBtais SQL映射文件查找时,必须返回一个resultType的类型去接收,最后自动映射,但是自动映射的前提为: 实体类属性与数据库字段名称一致。但是,按照阿里巴巴开发规约的规定,数据库不允许出现大写字母,两个字母中间使用_连接这种情况下建议使用resultMap进行自定义映射。
4.1 resultMap自定义映射
- 当数据库字段和实体类属性名称不一致时或返回多个实体类时,可以使用resultMap自定义结果映射。
4.1.1 ResultMap元素实现自定义结果映射
- 当没有设置剩下的属性时,他们可以自动映射,前提是名称一致。
<resultMap id="userIdCard" type="user">
<id property="id" column="id"></id>
<result property="idCard" column="id_card"></result>
</resultMap>
<select id="getResultMapTest" resultMap="userIdCard">
select * from user
</select>
注意:
- select标签中的resultMap必须和定义好的resultMap标签中的id保持一致。
- resultMap标签中的id必须唯一。
4.1.2 association 嵌套结果映射
- association 嵌套结果映射适用于多个实体类查询时,并且实体类对应的关系是,一对一,多对一。
- 一对一: 如: 一个学生只属于一个班级
- 多对一: 多个学生都属于一个班级
- Student 实体类中定义Class班级
public class User implements Serializable {
private Integer id;
private String name;
private String password;
//将班级类定义为成员变量(一个实体对象)
private ClassInfo classInfo;
//...省略get set 方法...
}
- resultMap 写法
<resultMap id="getStudentsByClassInfo" type="student">
<id property="id" column="id"></id>
<result property="name" column="name"></result>
<!--嵌套从表并返回实体类类型-->
<association property="classInfo" javaType="classInfo">
<id property="classId" column="class_id"></id>
<result property="calssName" column="class_name"></result>
</association>
</resultMap>
<!--使用多表查询,查出每个学生所在的班级-->
<select id="getStudentsByClassInfo" resultMap="getStudentsByClassInfo">
select u.name,c.class_name from student u left join classinfo c on u.class_id=c.class_id
</select>
4.1.3 collection 嵌套结果映射
- collection 嵌套结果映射 适用于 实体类是一对多的关系。
- 一对多: 如: 一个班里有多个学生,对应实体类中也就是一个班级类里有多个学生实体对象(使用集合)。
- ClassInfo实体类中定义studentList集合
/**
* 班级实体类
*/
public class ClassInfo {
private Integer classId;
private String calssName;
//定义学生集合
private List<User> userList;
//...get set 方法已省略
}
- resultMap 写法
<resultMap id="getStudentsByClassInfo" type="classInfo">
<id property="classId" column="class_Id"></id>
<id property="calssName" column="class_Name"></id>
<!--多表查询,嵌套查询一个班级中的多个学生-->
<collection property="studentList" ofType="student">
<id property="id" column="id"></id>
<id property="name" column="name"></id>
</collection>
</resultMap>
<select id="getAllStudentsByClassInfo" resultMap="getStudentsByClassInfo">
select u.name,c.class_name from classinfo c left join student u on c.class_id=u.class_id
where c.class_id=#{calssId}
</select>
注意:association 和 collction 的写法差别 : collction 需要设置一个 ofType 集合对象的属性类型。
4.1.4 resultType 和resultMap小结
- resultType 适用于查询返回一个实体对象时并且实体类属性和数据库字段一致的情况下。
- resultMap 适用于多表查询返回多个实体对象,或实体类属性和数据库字段不一致的情况下。
- resultType 和resultMap不能同时出现
- 以上两个只用于select查询
两者的映射行为:
Mybtais中是开启自动映射的,默认为 PARTIAL。
<!--默认开启自动映射: 只针对于 resultType 和没有嵌套的resultMap-->
<setting name="autoMappingBehavior" value="RARTIAL"/>
4.1.5 自动映射配置
- PARTIAL 默认,只自动映射没有嵌套的resultMap和resultType。
- NONE 所有自动映射都失效,只能手工映射。
- FULL 嵌套的resultMap和resultType都开启自动映射。
5.Mybtais框架的增删改操作
## insert
parameterType 参数类型: 实体类或map或其他(可使用别名)
<insert id="add" parameterType="user"> </insert>
## update
<update id="update" parameterType="user"> </update>
## delete
<delete id="delete" parameterType="user"> </delete>
注意:增删改(insert、update、delete)这类操作通常返回影响行数,这三种元素均没有resultType/resultMap属性。
6.实现动态SQL
- 当处理SQL与语句时,当一个字段出现为null的情况,也会影响另一个条件的查询,可以使用动态处理SQL语句,让sql语句更加的灵活。
6.1 where + if 组合标签
- where 标签的主要作用是对sql 语句中的where 关键字进行简化处理,并可以智能处理其内部and,or 关键字,避免多余的语法错误。
- 当where 里的条件语句都为false时,where 标签就不会进行一个拼接。
<select id="getUsers" resultType="cn.bdqn.entity.User">
select id,name,password from user
<where>
<if test="user.name!=null">
name like CONCAT(#{user.name},"%")
</if>
<if test="password!=null">
and password=#{user.password}
</if>
</where>
</select>
如果没加where 标签,当其中一个条件字段为null时,sql 语法就会出现错误,当加上where 标签之后,即使有一个字段为null也会自动把多余关键字给去掉。
6.2 choose 标签
- choose标签其实就是java中的switch, choose 标签里有when,otherwise这两个子标签,而choose就相当于switch,when==case+break,otherwise==default。
- 该标签的条件是唯一的,只要一个条件满足就会终止。
<select id="selectUsers" resultType="user">
select id,name,password from t_supplier
<where>
<choose>
<when test="name!=null and name!=''">
name=#{name}
</when>
<when test="password!=null and password!=''">
supCode=#{supCode}
</when>
<otherwise>
id=#{id}
</otherwise>
</choose>
<where>
</select>
6.3 foreach 标签
- 该标签一般用于循环某个多条件的sql语句,提高效率。
- sql中可以遍历的类型参数: List,Map,array
/**
* 根据角色ID集合查询用户列表新信息
* @param roleList
* @return
*/
List<SysUser> getUserByRoleIdList(List<Integer> roleList);
<select id="getUserByRoleIdList" resultType="entity.SysUser">
select * from t_sys_user where roleId in
<foreach collection="list" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
6.3.1foreach 元素
-
collection=“” 引号中一般为入参@Param引号中的值 或默认值
-
item=“” 相当于给集合中每个元素都起了一个别名
-
open=“” 循环开始需要放一个什么字符串
-
separator=“” 第一次循环结束后需要用什么分割符拼接第二次循环结果
-
close=“” 全部循环完之后需要加什么
6.4 set 标签
- set 标签出现在update标签的修改语句中,它会动态在sql语句中添加set关键字,并添加一些属性。
<update id="update">
update user
<set>
<if test="name!=null and name!=''">
supName=#{supName},
</if>
<if test="password!=null and password!=''">
supDesc=#{supDesc},
</if>
</set>
<where>
id=#{id}
</where>
</update>
注意
- 修改时需要根据业务判断使用set标签就可以还是需要set+if标签。
- 如果使用set 那么当其中某一个字段为null时也会随之更改。
6.5 trim 标签
- 使用trim 标签一样可以实现 where 和 set 标签的动态忽略前后缀,但trim标签比set 标签范围更广,它可以给各种标签添加和忽略前后缀。
<update id="update">
update user
<trim prefix="set" suffix="where id=#{id}" suffixOverrides="," >
<if test="name!=null and name!=''">
name=#{name},
</if>
<if test="password!=null and password!=''">
password=#{password},
</if>
</trim>
</update>
6.5.1 trim标签中的元素
1.prefix :如果trim标签中有一个条件成立的话 就会在最前面添加prefix里面配置的关键字。
2.prefixOverrides :如果前面没有条件成立的话,会动态去掉前面的and关键字或者or关键字或其他,如果前面又条件成立的话,不会去掉所配置的关键字。
3.suffixOverrides 如果后面没有条件成立的话会动态去掉每个条件后面跟着的该关键字
4.suffix 如果trim标签中有一个条件成立的话,就会在所有成立的条件最后加上suffix配置的关键字,如果没有一个条件成立则不会加上所配置的关键字。