Mybatis
# 参数获取
# $与#区别
${}的本质就是字符串拼接,#{}的本质就是占位符赋值 ;
${}使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号;
传入的数据直接显示生成在sql中;无法防止sql注入;
#{}使用占位符赋值的方式拼接sql,此时为字符串类型或日期类型的字段进行赋值时,可以自动添加单引号;
传入的数据都生成一个字符串,自动传入的数据加一个双引号;能够防止sql注入;
# 一个参数
根据 id 查找
User findById(Integer id);
1<select id="findById" resultType="**.User"> select * from user where id = #{id} </select>
1
2
3根据 属性名 查找
User findByUser(User user);
1<select id="findByUser" resultType="**.User"> select * from user where id = #{id} and username = #{username} and age = #{age} and address = #{address} </select>
1
2
3根据 Map 中的Key获取对应值
User findByMap(Map map);
1<select id="findByMap" resultType="**.User"> select * from user where id = #{id} and username = #{username} and age = #{age} and address = #{address} </select>
1
2
3接口中调用:
Map map = new HashMap(); map.put("id",2); map.put("username","PDD"); map.put("age",25); map.put("address","上海"); userDao.findByMap(map);
1
2
3
4
5
6
# 多个参数
Mapper接口中的方法参数为多个时,此时MyBatis会自动将这些参数放在一个map集合中;
在方法参数前使用@Param来设置参数名;
接口中定义:
User findByCondition(@Param("id") Integer id,@Param("username") String username);
<select id="findByCondition" resultType="**.User">
select * from user where id = #{id} and username = #{username}
</select>
2
3
# 实体类参数
@Test
public void insertUser() {
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
User user = new User(null,"Tom","123456",12,"男","123@321.com");
mapper.insertUser(user);
}
2
3
4
5
6
7
<!--int insertUser(User user);-->
<insert id="insertUser">
insert into t_user values(null,#{username},#{password},#{age},#{sex},#{email})
</insert>
2
3
4
# CRUD
增
void insertUser(User user);
1<insert id="insertUser"> insert into user values(null,#{username},#{age},#{address}) </insert>
1
2
3删
void deleteById(Integer id);
1<delete id="deleteById"> delete from user where id = #{id} </delete>
1
2
3改
void updateUser(User user);
1<!--更新用户--> <update id="updateUser"> UPDATE USER SET age = #{age} , username = #{username},address = #{address} WHERE id = #{id} </update>
1
2
3
4查
根据 id 查询
User findById(Integer id);
1<select id="findById" resultType="**.User"> select * from user where id = #{id} </select>
1
2
3查询所有
List<User> findAll();
1<select id="findAll" resultType="**.User"> select * from user </select>
1
2
3
# 动态SQL
# if
<select id="findByCondition" resultType="**.User">
select * from user
where id = #{id}
<if test="username!=null">
and username = #{username}
</if>
</select>
2
3
4
5
6
7
如果参数username为null则执行的sql为:select * from user where id = ?
如果参数username不为null则执行的sql为:select * from user where id = ? and username = ?
在test属性中表示参数的时候不需要写#{};
# where
<select id="findByCondition" resultType="**.User">
select * from user
<where>
<if test="id!=null">
id = #{id}
</if>
<if test="username!=null">
and username = #{username}
</if>
</where>
</select>
2
3
4
5
6
7
8
9
10
11
如果id和username都为null,则执行的sql为:**select * from user **
如果id为null,username不为null,则执行的sql为:**select * from user where username = ? **
# set
<update id="updateUser">
UPDATE USER
<set>
<if test="username!=null">
username = #{username},
</if>
<if test="age!=null">
age = #{age},
</if>
<if test="address!=null">
address = #{address},
</if>
</set>
where id = #{id}
</update>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
如果调用方法时传入的User对象的id为2,username不为null,其他属性都为null:
最终执行的sql为:UPDATE USER SET username = ? where id = ?
# foreach
遍历集合或者数组类型的参数,获取其中的元素拿来动态的拼接SQL语句;
List<User> findByIds(@Param("ids") Integer[] ids);
如果期望动态的根据实际传入的数组的长度拼接SQL语句,例如:
select * from User WHERE id in( ? , ? , ? , ?, ? )
1
<select id="findByIds" resultType="**.User">
select * from User
<where>
<foreach collection="ids" open="id in(" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
2
3
4
5
6
7
8
collection:表示要遍历的参数;
open:表示遍历开始时拼接的语句;
item:表示给当前遍历到的元素的取的名字;
separator:表示每遍历完一次拼接的分隔符;
close:表示最后一次遍历完拼接的语句;
# choose/when/otherwise
- choose类似于java中的switch
- when类似于java中的case
- otherwise类似于java中的dufault
接口中方法定义如下:
List<User> selectChose(User user);
期望:
如果user对象的id不为空时就通过id查询;
如果id为null,username不为null就通过username查询;
如果id和username都会null就查询id为3的用户;
<select id="selectChose" resultType="**.User">
select * from user
<where>
<choose>
<when test="id!=null">
id = #{id}
</when>
<when test="username!=null">
username = #{username}
</when>
<otherwise>
id = 3
</otherwise>
</choose>
</where>
</select>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# ResultMap
# 基本使用
自定义结果集和实体类属性的映射规则;
<!--
resultMap 用来自定义结果集和实体类的映射
属性:
id 相当于这个resultMap的唯一标识
type 用来指定映射到哪个实体类
id标签 用来指定主键列的映射规则
属性:
property 要映射的属性名
column 对应的列名
result标签 用来指定普通列的映射规则
属性:
property 要映射的属性名
column 对应的列名
-->
<resultMap id="orderMap" type="**.Order" >
<id column="id" property="id"></id>
<result column="createtime" property="createtime"></result>
<result column="price" property="price"></result>
<result column="remark" property="remark"></result>
<result column="user_id" property="userId"></result>
</resultMap>
<!--使用我们自定义的映射规则-->
<select id="findAll" resultMap="orderMap">
SELECT id,createtime,price,remark,user_id FROM ORDERS
</select>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 自动映射
默认开启,如果结果集的列名和属性名相同是会自动映射的,只需要写特殊情况的映射关系即可;
下面这种写法和上面的写法会有相同的效果,因为其他属性的属性名和结果集的列名都是相同的会自动映射:
<resultMap id="orderMap" type="**.Order" >
<result column="user_id" property="userId"></result>
</resultMap>
<!--使用我们自定义的映射规则-->
<select id="findAll" resultMap="orderMap">
SELECT id,createtime,price,remark,user_id FROM ORDERS
</select>
2
3
4
5
6
7
如有需要可以选择关闭自动映射可以把resultMap的autoMapping属性设置为false:
<resultMap id="orderMap" type="**.Order" autoMapping="false">
<id column="id" property="id"></id>
<result column="createtime" property="createtime"></result>
<result column="price" property="price"></result>
<result column="remark" property="remark"></result>
<result column="user_id" property="userId"></result>
</resultMap>
2
3
4
5
6
7
# 继承映射关系
resultMap的extends属性来指定一个resultMap,从而复用重复的映射关系配置;
<!--定义个父映射,供其他resultMap继承-->
<resultMap id="baseOrderMap" type="**.Order" >
<id column="id" property="id"></id>
<result column="createtime" property="createtime"></result>
<result column="price" property="price"></result>
<result column="remark" property="remark"></result>
</resultMap>
<!--继承baseOrderMap,然后只需要写自己特有的映射关系即可-->
<resultMap id="orderMap" type="**.Order" autoMapping="false" extends="baseOrderMap">
<result column="user_id" property="userId"></result>
</resultMap>
2
3
4
5
6
7
8
9
10
11
# 多表查询
员工表&部门表,各有对方字段;
# 多对一
级联方式:
<resultMap id="empAndDeptResultMapOne" type="Emp"> <id property="eid" column="eid"></id> <result property="empName" column="emp_name"></result> <result property="age" column="age"></result> <result property="sex" column="sex"></result> <result property="email" column="email"></result> <result property="dept.did" column="did"></result> <result property="dept.deptName" column="dept_name"></result> </resultMap> <!--Emp getEmpAndDept(@Param("eid")Integer eid);--> <select id="getEmpAndDept" resultMap="empAndDeptResultMapOne"> select * from t_emp left join t_dept on t_emp.eid = t_dept.did where t_emp.eid = #{eid} </select>
1
2
3
4
5
6
7
8
9
10
11
12
13association
- association:处理多对一的映射关系;
- property:需要处理多对的映射关系的属性名;
- javaType:该属性的类型;
<resultMap id="empAndDeptResultMapTwo" type="Emp"> <id property="eid" column="eid"></id> <result property="empName" column="emp_name"></result> <result property="age" column="age"></result> <result property="sex" column="sex"></result> <result property="email" column="email"></result> <association property="dept" javaType="Dept"> <id property="did" column="did"></id> <result property="deptName" column="dept_name"></result> </association> </resultMap> <!--Emp getEmpAndDept(@Param("eid")Integer eid);--> <select id="getEmpAndDept" resultMap="empAndDeptResultMapTwo"> select * from t_emp left join t_dept on t_emp.eid = t_dept.did where t_emp.eid = #{eid} </select>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 一对多
collection方式:
- collection:用来处理一对多的映射关系;
- ofType:表示该属性对应的集合中存储的数据的类型;
<resultMap id="DeptAndEmpResultMap" type="Dept">
<id property="did" column="did"></id>
<result property="deptName" column="dept_name"></result>
<collection property="emps" ofType="Emp">
<id property="eid" column="eid"></id>
<result property="empName" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="email" column="email"></result>
</collection>
</resultMap>
<!--Dept getDeptAndEmp(@Param("did") Integer did);-->
<select id="getDeptAndEmp" resultMap="DeptAndEmpResultMap">
select * from t_dept left join t_emp on t_dept.did = t_emp.did where t_dept.did = #{did}
</select>
2
3
4
5
6
7
8
9
10
11
12
13
14
15