#{}和${}的区别
#{}
是占位符,是采用预编译方式向sql中传递,可以防止sql注入,如果往sql中传值,使用#{}
一般用于向sql中的列传值
${}
是将内容直接拼到sql语句中,一般不用于向sql中传值,一般用于向sql动态传递列名
一般用于向sql动态传递列名 例如: 排序时 order by 后面的列名是可以改变的
例如: select 后面的列名也可以自由选择
resultMap
多张表关联查询时要使用resultMap
使用resultMap标签对查询结果进行自定义映射
type = "Admin" 最终返回的结果类型
-->
<resultMap id="adminMap" type="Admin">
<id column="adminid" property="id"></id>
<result column="account" property="account"></result>
</resultMap>
<select id="findAdmin" resultMap="adminMap">
select id adminid,account from admin
</select>
(1). resutlMap 的 id 属性是 resutlMap 的唯一标识,本例中定义为
“adminMap”
(2). resutlMap 的 type 属性是映射的 POJO 类型
(3). id 标签映射主键,result 标签映射非主键
(4). property 设置对象属性名称,column 映射查询结果的列名称
多表关联处理
resultMap元素中的association
collection
collection关联元素处理一对多关联
例如: 专业与学生的一对多关联
部门与员工的一对多关联
专业一方配置多方集合
public class Major {
private int id;
private String name;
private Student student;
private List<Student> students;
}
学生多方,在多方配置一方
public class Student {
private int id;
private int num;
private String name;
private String gender;
private Major major;
}
使用resultMap组装查询结果
<resultMap id="majorMap" type="Major">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<collection property="students" javaType="list" ofType="Student">
<result column="num" property="num"></result>
<result column="sname" property="name"></result>
</collection>
</resultMap>
<select id="findMajorById" parameterType="int" resultMap="majorMap">
select
m.id,
m.name,
s.num,
s.name sname
from major m inner join student s on s.majorid = m.id where m.id = #{id}
</select>
<select id="findMajors" resultMap="majorMap">
select
m.id,
m.name,
s.num,
s.name sname
from major m inner join student s on s.majorid = m.id
</select>
其中,查询单个专业对应的学生需要对应id,查询所有专业下的所有学生则不需要对应专业id
resultMap中的collection标签需要进行子类对象的配置
property元素是最终对象属性的名称,javaType则是对应返回的java对象类型,对于list这种对象则需要使用ofType对其内部的对象进行绑定,本例中list内部存储的是Student对象
association
association多在嵌套查询中使用,将一个多表关联查询拆分为多次查询,先查询主表数据,然后查询关联表数据
<!-- 嵌套查询 先查询主表(学生表)-->
<resultMap id="studentMap1" type="Student">
<id column="id" property="id"></id>
<result column="num" property="num"></result>
<result column="name" property="name"></result>
<result column="gender" property="gender"></result>
<!-- 封装关联数据-->
<association property="major" javaType="Major" select="findMajorById" column="majorid"></association>
</resultMap>
<select id="findStudentById1" resultMap="studentMap1">
select id,num,name,gender,majorid from student where id =#{id}
</select>
<!-- 嵌套查询学生关联的专业-->
<select id="findMajorById" resultType="Major">
select name from major where id = #{majorid}
</select>
(1). select:指定关联查询对象的 Mapper Statement ID 为 findMajorByID
(2). column=“majorid”;关联查询时将majorid列的值传入 findMajorByID,并将 findMajorByID 查询的结果映射到Student的Major属性中
(3).collection 和 association 都需要配置 select 和 column 属性,两者配置方法相同
注解方式
@Insert : 插入 sql , 和 xml insert sql 语法完全一样
@Select : 查询 sql, 和 xml select sql 语法完全一样
@Update : 更新 sql, 和 xml update sql 语法完全一样
@Delete : 删除 sql, 和 xml delete sql 语法完全一样
@Param : 入参
@Results : 设置结果集合
@Result : 结果
使用案例
查询所有信息
@Select("select * from t_emp")
@Results(id = "empMap",value = {
@Result(column = "emp_id",property = "empId",id = true),
@Result(column = "emp_name",property = "empName"),
@Result(column = "emp_tel",property = "empTel"),
@Result(column = "emp_education",property = "empEducation"),
@Result(column = "emp_birthday",property = "empBirthday")
})
List<Employee> getAll();
查询单个信息
@Select("select * from t_emp where emp_id=#{empId}")
@ResultMap(value="empMap")
Employee getById(@Param("empId") Integer empId);
插入信息
@Insert("insert into t_emp (emp_id, emp_name, emp_tel, " +
" emp_education, emp_birthday, fk_dept_id" +
" )" values (#{empId}, #{empName}, #{empTel}, " +
" #{empEducation}, #{empBirthday}, #{fkDeptId}" +
" )")
int insert(Employee record);
删除信息
@Delete("delete from t_emp where emp_id=#{empId}")
int deleteByPrimaryKey(@Param("empId") Integer empId);
动态SQL
MyBatis 的一个强大的特性之一通常是它的动态 SQL 能力
MyBatis 中用于实现动态 SQL 的元素主要有:
If
where
trim
set
choose (when, otherwise)
foreach
if元素
if标签可以对传入的条件进行判断
<select id="teachers" resultType="com.geroge.mybatispro.model.Teacher">
select * from teacher
where type = 1
<if test="num!=null">
and num = #{num}
</if>
<if test="name!=null">
or name =#{name}
</if>
<if test="gender!=null">
and gender = #{gender}
</if>
</select>
通过对if中的test元素进行编写,判断指定条件是否成立
若成立则执行标签内的语句,但是上述语句若是没有type = 1这一段,则会出现条件均不成立,where后没有语句的情况
此时可以使用标签
例如:
<select id="teachers" resultType="com.geroge.mybatispro.model.Teacher">
select * from teacher
<where>
<if test="num!=null">
and num = #{num}
</if>
<if test="name!=null">
or name =#{name}
</if>
<if test="gender!=null">
and gender = #{gender}
</if>
</where>
</select>
元素会进行判断,如果它包含的标签中有返回值的话,它就插入一个’where’
trim元素
where标签用trim也可以表示,当where后紧随AND或者OR的时候,就去除AND或者OR
<select id="teachers" resultType="com.geroge.mybatispro.model.Teacher">
select * from teacher
<trim prefix="where" prefixOverrides="and|or">
<if test="num!=null">
and num = #{num}
</if>
<if test="name!=null">
or name =#{name}
</if>
<if test="gender!=null">
and gender = #{gender}
</if>
</trim>
</select>
prefix是前缀,可以写where,prefixOverrides覆盖指定内容
Choose元素
<select id="teachers" resultType="com.geroge.mybatispro.model.Teacher">
select * from teacher
<trim prefix="where" prefixOverrides="and|or">
<choose>
<when test="name!=null">
name = #{name}
</when>
<otherwise>
name = '李老师'
</otherwise>
</choose>
</trim>
</select>
choose元素内部可以指定when和otherwise
前者是首次判断,后者是在所有判断均没有结果时执行
类似java中的if else语句
set元素
set元素可以去除语句中最后的逗号
例如:
<update id="updateTeacher" parameterType="teacher">
update teacher
<set>
<if test="num!=null">
num = #{num},
</if>
<if test="name!=null">
name = #{name},
</if>
<if test="gender!=null">
gender = #{gender}
</if>
</set>
where id = #{id}
</update>
上述语句中前两个if的语句后都存在逗号,若是只执行其中一个的话最后的查询语句中就会多出一个逗号
set元素可以自动去除语句中多余的逗号
此操作也可以通过trim元素实现
<update id="updateTeacher" parameterType="teacher">
update teacher
<trim prefix="set" suffixOverrides="," suffix="where">
<if test="num!=null">
num = #{num},
</if>
<if test="name!=null">
name = #{name},
</if>
<if test="gender!=null">
gender = #{gender}
</if>
</trim>
where id = #{id}
</update>
foreach元素
此元素主要用于构建in条件时,它可以在SQL语句中进行迭代一个集合
foreach元素的属性主要有item,index,collection,open,separator,close
item属性表示集合中每一个元素进行迭代时的别名,index指定一个名字,用于表示迭代过程中每次迭代到的位置
open表示该语句以什么开始(通畅表示前括号),separator表示每次迭代之间以什么符号作为分隔符
close表示以什么结束(通常为后括号)
在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但在不同的情况下,该属性的值是不一样的
如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
<select id="findTeacher" resultType="com.george.mybatispro.model.Teacher">
select
<foreach item="col" collection="list" separator=",">
${col}
</foreach>
from-teacher
</select>