一、定义 SQL 语句

(1)select 标签的使用
属性介绍:
id : 唯一的标识符.
parameterType: 传给此语句的参数的全路径名或别名 例: com.test.poso.User 或 user
resultType : 语句返回值类型或别名。注意,如果是集合,那么这里填写的
是集合的泛型,而不是集合本身(resultType 与 resultMap 不能并用)
例子:
sql:

 <select parameterType="user" resultType="User">  
 select * from user where name =#{name}  
 </select>  

(2)insert 标签的使用
属性介绍:
id : 唯一的标识符
parameterType: 传给此语句的参数的全路径名或别名 例: com.test.poso.User

(3)delete 标签的使用
例:

 <delete parameterType="int">   
 delete from user   
 where id = #{id}   
 </delete>  

(4)update 标签的使用
类似于 insert

二、配置对象属性与查询结果集

(1)resultMap 标签的使用

基本作用:建立 SQL 查询结果字段与实体属性的映射关系信息

查询的结果集转换为 java 对象,方便进一步操作

将结果集中的列与 java 对象中的属性对应起来并将值填充进去

!注意:与 java 对象对应的列不是数据库中表的列名,而是查询后结果集的列名

例:
<resultMap id="getStudentRM" type="EStudnet">
  <id property="id" column="ID"/>
  <result property="studentName" column="Name"/>
  <result property="studentAge" column="Age"/>
</resultMap>
<select id="getStudent" resultMap="getStudentRM">
  SELECT ID, Name, Age
    FROM TStudent
</select>
标签说明:
主标签
id:该resultMap的标志
type:返回值的类名,此例中返回EStudnet类
子标签:
 
id:用于设置主键字段与领域模型属性的映射关系,此处主键为ID,对应id。
result:用于设置普通字段与领域模型属性的映射关系

三、动态拼接 SQL

(1)if 标签的使用

if 标签通常用于 WHERE 语句中,通过判断参数值来决定是否使用某个查询条件, 他也经常用于 UPDATE 语句中判断是否更新某一个字段,还可以在 INSERT 语句中用来判断是否插入某个字段的值

例:

 
  <select id="getStudentListLikeName" parameterType="StudentEntity" resultMap="studentResultMap"> 
     SELECT * from STUDENT_TBL ST 
 WHERE ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%') 
  </select> 
 

但是此时如果 studentName 是 null 或空字符串,此语句很可能报错或查询结果为空。此时我们使用 if 动态 sql 语句先进行判断,如果值为 null 或等于空字符串,我们就不进行此条件的判断。

修改为:

  <select id="getStudentListLikeName" parameterType="StudentEntity" resultMap="studentResultMap"> 
   SELECT * from STUDENT_TBL ST 
   <if test="studentName!=null and studentName!='' "> 
   WHERE ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%') 
  </if> 
 </select> 

(2)foreach 标签的使用

foreach 标签主要用于构建 in 条件,他可以在 sql 中对集合进行迭代。如下:

delete from user where id in

#{id}

我们假如说参数为 ----  int[] ids = {1,2,3,4,5}  ---- 那么打印之后的 SQL 如下:

delete form user where id in (1,2,3,4,5)

释义:

collection :collection 属性的值有三个分别是 list、array、map 三种,分别对应的参数类型为:List、数组、map 集合,我在上面传的参数为数组,所以值为 array

item : 表示在迭代过程中每一个元素的别名

index :表示在迭代过程中每次迭代到的位置(下标)

open :前缀

close :后缀

separator :分隔符,表示迭代时每个元素之间以什么分隔

我们通常可以将之用到批量删除、添加等操作中。

(3)choose 标签的使用

有时候我们并不想应用所有的条件,而只是想从多个选项中选择一个。MyBatis 提供了 choose 元素,按顺序判断 when 中的条件出否成立,如果有一个成立,则 choose 结束。当 choose 中所有 when 的条件都不满则时,则执行 otherwise 中的 sql。类似于 Java 的 switch 语句,choose 为 switch,when 为 case,otherwise 则为 default。
         if 是与 (and) 的关系,而 choose 是或(or)的关系。

例如下面例子,同样把所有可以限制的条件都写上,方面使用。选择条件顺序,when 标签的从上到下的书写顺序:

 
1.  <select id="getStudentListChooseEntity" parameterType="StudentEntity" resultMap="studentResultMap"> 
2.   SELECT * from STUDENT_TBL ST 
3.   <where> 
4.   <choose> 
5.   <when test="studentName!=null and studentName!='' "> 
6.   ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%') 
7.   </when> 
8.   <when test="studentSex!= null and studentSex!='' "> 
9.   AND ST.STUDENT_SEX = #{studentSex} 
10.   </when> 
11.   <when test="studentBirthday!=null"> 
12.   AND ST.STUDENT_BIRTHDAY = #{studentBirthday} 
13.   </when> 
14.   <when test="classEntity!=null and classEntity.classID !=null and classEntity.classID!='' "> 
15.   AND ST.CLASS_ID = #{classEntity.classID} 
16.   </when> 
17.   <otherwise> 
 
19.   </otherwise> 
20.   </choose> 
21.   </where> 
22.  </select> 
 

四、格式化输出

(1)where
当 if 标签较多时,这样的组合可能会导致错误。例如,like 姓名,等于指定性别等:

Xml 代码

1.  <!-- 查询学生 list,like 姓名,= 性别 --> 
2.  <select id="getStudentListWhere" parameterType="StudentEntity" resultMap="studentResultMap"> 
3.   SELECT * from STUDENT_TBL ST 
4.   WHERE 
5.   <if test="studentName!=null and studentName!='' "> 
6.   ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%') 
7.   </if> 
8.   <if test="studentSex!= null and studentSex!='' "> 
9.   AND ST.STUDENT_SEX = #{studentSex} 
10.   </if> 
11.  </select> 
 

如果上面例子,参数 studentName 为 null 或’’,则或导致此 sql 组合成 “WHERE AND” 之类的关键字多余的错误 SQL。
 这时我们可以使用 where 动态语句来解决。这个 “where” 标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。此外,如果标签返回的内容是以 AND 或 OR 开头的,则它会剔除掉。
 上面例子修改为:

Xml 代码

1.  <!-- 查询学生 list,like 姓名,= 性别 --> 
2.  <select id="getStudentListWhere" parameterType="StudentEntity" resultMap="studentResultMap"> 
3.   SELECT * from STUDENT_TBL ST 
4.   <where> 
5.   <if test="studentName!=null and studentName!='' "> 
6.   ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%') 
7.   </if> 
8.   <if test="studentSex!= null and studentSex!='' "> 
9.   AND ST.STUDENT_SEX = #{studentSex} 
10.   </if> 
11.   </where> 
12.  </select> 

(2)set
当在 update 语句中使用 if 标签时,如果前面的 if 没有执行,则或导致逗号多余错误。使用 set 标签可以将动态的配置 SET 关键字,和剔除追加到条件末尾的任何不相关的逗号。
没有使用 if 标签时,如果有一个参数为 null,都会导致错误,如下示例:

Xml 代码

 
1.  <!-- 更新学生信息 --> 
2.  <update id="updateStudent" parameterType="StudentEntity"> 
3.   UPDATE STUDENT_TBL 
4.   SET STUDENT_TBL.STUDENT_NAME = #{studentName}, 
5.   STUDENT_TBL.STUDENT_SEX = #{studentSex}, 
6.   STUDENT_TBL.STUDENT_BIRTHDAY = #{studentBirthday}, 
7.   STUDENT_TBL.CLASS_ID = #{classEntity.classID} 
8.   WHERE STUDENT_TBL.STUDENT_ID = #{studentID}; 
9.  </update>

 使用 set+if 标签修改后,如果某项为 null 则不进行更新,而是保持数据库原值。如下示例:

Xml 代码

 
1.  <!-- 更新学生信息 --> 
2.  <update id="updateStudent" parameterType="StudentEntity"> 
3.   UPDATE STUDENT_TBL 
4.   <set> 
5.   <if test="studentName!=null and studentName!='' "> 
6.   STUDENT_TBL.STUDENT_NAME = #{studentName}, 
7.   </if> 
8.   <if test="studentSex!=null and studentSex!='' "> 
9.   STUDENT_TBL.STUDENT_SEX = #{studentSex}, 
10.   </if> 
11.   <if test="studentBirthday!=null"> 
12.   STUDENT_TBL.STUDENT_BIRTHDAY = #{studentBirthday}, 
13.   </if> 
14.   <if test="classEntity!=null and classEntity.classID!=null and classEntity.classID!='' "> 
15.   STUDENT_TBL.CLASS_ID = #{classEntity.classID} 
16.   </if> 
17.   </set> 
18.   WHERE STUDENT_TBL.STUDENT_ID = #{studentID}; 
19.  </update> 
 

(3)trim

trim 是更灵活的去处多余关键字的标签,他可以实践 where 和 set 的效果。

where 例子的等效 trim 语句:

1.  <!-- 查询学生 list,like 姓名,= 性别 --> 
2.  <select id="getStudentListWhere" parameterType="StudentEntity" resultMap="studentResultMap"> 
3.   SELECT * from STUDENT_TBL ST 
4.   <trim prefix="WHERE" prefixOverrides="AND|OR"> 
5.   <if test="studentName!=null and studentName!='' "> 
6.   ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%') 
7.   </if> 
8.   <if test="studentSex!= null and studentSex!='' "> 
9.   AND ST.STUDENT_SEX = #{studentSex} 
10.   </if> 
11.   </trim> 
12.  </select> 
 

set 例子的等效 trim 语句:

Xml 代码

1.  <!-- 更新学生信息 --> 
2.  <update id="updateStudent" parameterType="StudentEntity"> 
3.   UPDATE STUDENT_TBL 
4.   <trim prefix="SET" suffixOverrides=","> 
5.   <if test="studentName!=null and studentName!='' "> 
6.   STUDENT_TBL.STUDENT_NAME = #{studentName}, 
7.   </if> 
8.   <if test="studentSex!=null and studentSex!='' "> 
9.   STUDENT_TBL.STUDENT_SEX = #{studentSex}, 
10.   </if> 
11.   <if test="studentBirthday!=null"> 
12.   STUDENT_TBL.STUDENT_BIRTHDAY = #{studentBirthday}, 
13.   </if> 
14.   <if test="classEntity!=null and classEntity.classID!=null and classEntity.classID!='' "> 
15.   STUDENT_TBL.CLASS_ID = #{classEntity.classID} 
16.   </if> 
17.   </trim> 
18.   WHERE STUDENT_TBL.STUDENT_ID = #{studentID}; 
19.  </update> 

五、配置关联关系

(1)collection

一对一

association 通常用来映射一对一的关系,例如,有个类 user, 对应的实体类如下:(getter,setter 方法省略)

private String id;//主键
    private String userName;//用户姓名

有个类 Article, 对应的实体类如下:

private String id;//主键
    private String articleTitle;//文章标题
    private String articleContent;//文章内容

如果我想查询一个用户的时候,也查到他写的一篇文章,可以怎样写呢?在类 user 加入一个属性 article

private String id;//主键
   private String userName;//用户姓名
   private Article article;//新增的文章属性

2、mapper.xml 我在 user 类的 mapper.xml 这样配置

<resultMap type="test.mybatis.entity.User">
  <id column="id" property="id" jdbcType="VARCHAR" javaType="java.lang.String"/>
  <result column="userName" property="userName" jdbcType="VARCHAR" javaType="java.lang.String"/>
//这里把user的id传过去
   <association property="article" column="id"                       
            select="test.mybatis.dao.articleMapper.selectArticleByUserId" />//test.mybatis.dao.articleMapper为命名空间
 </resultMap>

同时,我的 article 对应的 xml 这样写:

1 <resultMap type="test.mybatis.entity.Article">
2   <id column="id" property="id" jdbcType="VARCHAR" javaType="java.lang.String"/>
3   <result column="articleTitle" property="articleTitle" jdbcType="VARCHAR" javaType="java.lang.String"/>
4  <result column="articleContent" property="articleContent" jdbcType="VARCHAR" javaType="java.lang.String"/>
5  </resultMap>
  (当然,这里还有查询user表的语句,省略)

同时,在 article 对应的 xml 有这样的 select 语句:

<select
parameterType="java.lang.String"
resultMap="ArticleResultMap" >
select * from
tb_article where userId=#{userId} </select>

(2)association

一对多

实体类增加对应属性

private String id;//主键
   private String userName;//用户姓名
   private List<Article> articleList;

userMapper.xml 这样配置

<resultMap type="test.mybatis.entity.User">
  <id column="id" property="id" jdbcType="VARCHAR" javaType="java.lang.String"/>
  <result column="userName" property="userName" jdbcType="VARCHAR" javaType="java.lang.String"/>
//这里把user的id传过去
   <collection property="articleList" column="id"                       
            select="test.mybatis.dao.articleMapper.selectArticleListByUserId" />
 </resultMap>
以下省略,类同,Mybatis会把结果封装成List类型。

三、如果我还想通过 Article 表另一张表,比如文章中有个 fk_id,也可以像上面这样重复配置,把 fk_id 当做与另一张表关联的参数,那时就可以通过用户查到文章,查到文章关联的另一张表了。

六、SQL 标签

更多用于写 sql 语句的一部分,写在配置文件中的常量

七、include 标签

用于引用常量