MyBatis动态标签

MyBatis动态标签

set

​ set标签是Mybatis提供的一个智能标签,一般情况下用在更新操作中。

​ set标签的功能是动态的配置SET关键字,并且剔除追加到条件末尾的任何不相关的逗号

​ set和if标签配合使用时,如果某项数据为null则不进行更新,而是保持数据库原值。

语法格式

<set>
    <!--每个字段进行修改必须用逗号接间隔,并且set标签不会自动补全逗号-->
    <if test="uname != null and">uname=#{uname,jdbcType=VARCHAR},</if>
    <if test="use != null">use=#{use,jdbcType=VARCHAR},</if>
</set>

sql、include

​ sql标签用于封装一些通用的sql语句,通过include标签实现sql的复用

语法格式

<sql id="Base_Column_List">
    stu_id,stu_name,stu_class
</sql>
<!--以下语句相当于直接插入一条字符串-->
<include refid="Base_Column_List"/>

trim

语法格式

<trim prefix="" prefixOverrides="" suffix="" suffixOverrides="">
</trim>
属性说明
prefix指定一个字符串,替换prefixOverrides属性指定的字符串
prefixOverrides指定SQL语句的前缀字符串(如果不是则不起作用),用prefix指定字符串替换该属性指定的字符串
suffix指定一个字符串替换suffixOverrides属性指定的字符串
suffixOverrides指定SQL语句的后缀字符串(如果不是则不起作用),用suffix指定字符串替换该属性指定的字符串

功能说明

  • 如果标签中有SQL语句就把格式化后的SQL语句拼接到之前的SQL语句上,如果标签体中没有SQL语句,则该标签相当于不存在
  • 该标签的四个属性默认值都为空字符串
  • 如果prefixOverrides值为空字符串,相当于prefix指定的字符串拼接到SQL语句首位
  • 如果prefix值为空字符串,相当于删除prefixOverrides指定的字符串

使用实例

检索

SELECT * FROM user
<trim prefix="WHERE" prefixOverrides="AND|OR">
    <if test="name != null and name != ''">AND name = #{name}</if>
    <if test="gender != null and gender != ''"> AND gender = #{gender}</if>
</trim>

SELECT * FROM user
<where>
    <trim prefixOverrides="AND|OR">
    <if test="name != null and name != ''">AND name = #{name}</if>
    <if test="gender != null and gender != ''"> AND gender = #{gender}</if>
</trim>
</where>

更新

UPDATE user
<trim prefix="SET" suffix="WHERE id = #{id}" suffixOverrides=",">
	    <if test="name != null and name != ''">name = #{name},</if>
    <if test="gender != null and gender != ''">gender = #{gender},</if>
</trim> 

分组

SELECT stafid,companyId,area
FROM user
	<trim prefix="GROUP BY" suffixOverrides=",">
        <if test="param.staffId != null">
       		t.staffId, 
        </if>
        <if test="param.companyId != null">
            t.companyId,
        </if>
        <if test="param.area != null">
            area,
        </if>
	</trim>

foreach

​ foreach标签主要用在构建IN条件中,它可以在SQL语句中迭代一个集合

语法格式

<foreach collection="" item="" index="" open="" separator="" close="">
</foreach>
属性说明
collection传入的参数的数据类型(对象),必选
item指定一个字符串作为名称,表示集合每次迭代过程中的元素(对象),支持点路径访问,必选
index指定一个字符串作为名字,用于迭代过程中,每次迭代到的位置
open开始的字符串
separator每次进行迭代时分隔字符串
close结束的字符串

collection属性

​ 该属性是必选的,但在不同情况下该属性的值是不一样的,主要有以下3种情况:

  • 如果传入的是单参数且参数类型是一个List,则默认使用list作为List对象的键
  • 如果传入的是单参数且参数类型是一个Array,则默认使用array作为Array对象的键
  • 如果传入的参数是多个,可以封装到一个Map中,但是Map对象没有默认的键,必须使用**@Param注解指定collection的键。多参数也可以分别使用注解@Param独立传入,不需要封装到Map**中

键值覆盖:List对象和Array对象默认键(collection属性值)分别为list和arraya,但是可以使用注解@Param进行覆盖

index和item属性

index和item属性值自由指定,当传入对象是List和Array时,index表示元素下标,item表示元素值(对象),

当传入对象是Map时,index表示key,item表示value

传入参数可以是一个包含List、Array或Map的对象,这时访问就需要使用点路径进行访问。

例如一个名为User的对象包含一个名为message的List,则进行迭代时,colleaction属性值设定为User.message,需要使用@Param指定键名

使用实例

使用foreach实现IN语句

<foreach collection="list" item="t" open="AND name IN(" separator="," close=")">
    #{t}
</foreach> 

网络资源

https://my.oschina.net/u/3555887/blog/1838220

https://www.cnblogs.com/caoyajun33-blog/p/6875169.html


if

​ if标签用于添加条件判断,配合其他动态标签可以根据传入参数动态生成SQL语句

语法格式

<if test="id != null">
</if>

test属性对应的表达式中可以进行一系列条件判断,但是需要注意的是,在这里使用大于小于大于等于 等判断符号时需要转义,以下罗列了常用需要转义的字符:

常规字符转义字符
&&amp;
<&lt;
>&gt;
``"&quot;
'&apos;
<=&lt;=<![CDATA[<= ]]>
>=&gt;=<![CDATA[>= ]]
!=<![CDATA[ <> ]]><![CDATA[!= ]]>

xml解析忽略字符

放在<![CDATA[ ]]>中的字符串在解析xml文件时将会被忽略,因此应该仅仅包含>、<等特殊字符,而不能包含动态sql标签。


where

​ where标签的作用是自动生成WHERE子句,同时自动去除条件语句开头的OR或AND关键字。如果所有条件都不满足,那Mybatis就会查询出所有的数据。

使用实例

<where>
   <if test="uname != null and uname ! = ''">
       AND uname LIKE CONCAT('%',#{uname},'%')
   </if>
   <if test="usex != null and usex != '' ">
       AND use = #{use}
   </if >
</where>

choose、when、otherwise

​ chosse、when和otherwise标签配合使用实现Java中switch语法效果。

​ MyBatis动态sql中没有同if-else语法相似的标签元素,只能通过choose、when和otherwise组合变相实现if-else语法。

语法格式

<!--switch-->
<choose>
	<when test=""></when>
    <when test=""></when>
    <otherwise></otherwise>
</choose>

<!--if-else-->
<choose>
	<when test=""></when>
    <otherwise></otherwise>
</choose>

selectKey

该标签用来返回新增成功的字段数据, 一般来说都是用来返回数据库内部生成的主键值的,比如自增主键和自动生成的uuid主键

值得注意的是

selectKey返回的值是保存在传入参数中的,而不是直接作为方法返回值。

语法格式

<select>
    <selectKey id="" keyProperty="" order="" resultType="">
    	SELECT /*代码实现*/;
	</selectKey>
    INSERT INTO tableName(
    	field1,field2
    )
    VALUES(
    	#{field1},
    	#{field2}
    )
</select>
属性说明
keyProperty设置语句返回结果的目标字段名。
keyColumn通过生成键值设置表中的列名,这个设置仅在某些数据库中是必须的(如PostgreSQL),当主键列不是表中的第一列的时候需要设置。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
order设置selectKey标签和外层标签的执行顺序,可以设置为BEFOREAFTER,分别表示selectKey先执行和后执行。(需要注意的是,如果在插入数据时期望返回结果为自增主键,则该属性必须设定为AFTER,才能通过LAST_INSERT_ID函数拿到正确的主键)
resultType返回结果的数据类型。MyBatis允许任何简单类型(包含字符串)作为主键类型。
statementType设置sql语句的映射类型。选值为STETEMENT、PREPARED、CALLABLE

使用实例

  • 获取自增主键

1.实体类

/*StudentEntity.calss*/
public class StudentEntity implements Serializable {
    private static final long serialVersionUID = -86709138255246164L;
    /*学生主键*/
    private Integer stuId;
    /*学生姓名*/
    private String stuName;
    /*学生性别*/
    private String stuGender;
    /*学生年龄*/
    private Integer stuAge;
    /*学生身高*/
    private String stuHeight;
    /*学生体重*/
    private String stuWeight;
    /*学生年级*/
    private String stuRank;
    /*学生班级*/
    private String stuClass;
    /*学生住址*/
    private String stuAddress;
    /*get and set ...*/
}

2.Dao层接口

Integer insertStudent(StudentEntity studentEntity);

3.映射文件

<!--添加学生信息-->
<insert id="insertStudent" parameterType="StudentEntity">
    <selectKey keyProperty="stuId" order="AFTER" resultType="java.lang.Integer">
        SELECT LAST_INSERT_ID()
    </selectKey>
    INSERT INTO stream_student(
    stu_name,stu_gender,
    stu_age,stu_height,
    stu_weight,stu_rank,
    stu_class,stu_address
    )VALUES(
    #{stuName,jdbcType=VARCHAR},
    #{stuGender,jdbcType=VARCHAR},
    #{stuAge,jdbcType=INTEGER},
    #{stuHeight,jdbcType=VARCHAR},
    #{stuWeight,jdbcType=VARCHAR},
    #{stuRank,jdbcType=VARCHAR},
    #{stuClass,jdbcType=VARCHAR},
    #{stuAddress,jdbcType=VARCHAR}
    )
</insert>

4.测试方法

public void getStudent() {
    StudentEntity studentEntity = new StudentEntity();
    studentEntity.setStuAge(1);
    studentEntity.setStuName("测试");
    int row = selectKeyDao.insertStudent(studentEntity);//方法返回的还是新增行数
    System.err.println("新增的主键为:" + studentEntity.getStuId());//selectKey标签将指定值赋值给了对象的指定属性
    System.err.println("新增的行数为:" + row);
}
  • 获取非自增主键

    在开发过程中通常使用UUID作为主键,字段类型为字符串类型。

1.实体类

/*CourseEntity.calss*/
public class CourseEntity implements Serializable {
    private static final long serialVersionUID = -2857317476780544289L;

    /*课程主键*/
    private String couId;
    /*课程名称*/
    private String couName;
    /*课程周期*/
    private Integer couPeriod;
    /*课程类型*/
    private String couType;
    /*课程学分*/
    private Integer couCredits;
        /*get and set ...*/
    }

2.Dao层接口

Integer insertCourse(CourseEntity courseEntity);

3.映射文件

<insert id="insertCourse" parameterType="com.ziytek.taozhu.mybaits.entity.CourseEntity">
    <selectKey order="BEFORE" resultType="java.lang.String" keyProperty="couId">
        SELECT (REPLACE(UUID(),'-','')
    </selectKey>
    <!--order属性必须设置为BEFORE否则将没有主键值进行插入-->
    INSERT INTO stream_course(
    cou_id,cou_name,
    cou_period,cou_type,cou_credits
    )VALUES(
    #{couId,jdbcType=VARCHAR},
    #{couName,jdbcType=VARCHAR},
    #{couPeriod,jdbcType=VARCHAR},
    #{couType,jdbcType=VARCHAR},
    #{couCredits,jdbcType=INTEGER}
    )
</insert>

4.测试方法

@Test
public void insertCourse() {
    CourseEntity courseEntity = new CourseEntity();
    courseEntity.setCouName("测试");
    courseEntity.setCouPeriod(11);
    courseEntity.setCouType("测试");
    courseEntity.setCouCredits(11);
    int row = selectKeyDao.insertCourse(courseEntity);
    System.err.println("新增主键为:" + courseEntity.getCouId());
    System.err.println("新增的行数:" + row);
}

其他方法获取自增主键值

设置useGeneratedKeys=true进行返回自增主键

  • 该属性只能用于Insert操作中,update操作不能使用

  • 该方法只能返回主键数据

  • 这种方式只能用在支持自动增长的数据库,比如MySql可以使用,而Orcale就只能用selectKey的方式返回主键。

使用实例:

<!--keyProperty指定实体类属性,keyColumn指定数据库字段-->
<insert id="insertStudentUseGeneratedKeys" useGeneratedKeys="true" keyProperty="stuId" keyColumn="stu_id"
  parameterType="com.ziytek.taozhu.mybaits.entity.StudentEntity">
      INSERT INTO stream_student(
stu_name,stu_gender,
stu_age,stu_height,
stu_weight,stu_rank,
stu_class,stu_address
)VALUES(
#{stuName,jdbcType=VARCHAR},
#{stuGender,jdbcType=VARCHAR},
#{stuAge,jdbcType=INTEGER},
#{stuHeight,jdbcType=VARCHAR},
#{stuWeight,jdbcType=VARCHAR},
#{stuRank,jdbcType=VARCHAR},
#{stuClass,jdbcType=VARCHAR},
#{stuAddress,jdbcType=VARCHAR}
)
</insert>

网络资源

https://blog.csdn.net/xu1916659422/article/details/77921912

https://blog.csdn.net/u014515854/article/details/82863055

https://www.cnblogs.com/dongfangshenhua/p/7091198.html


insert、update、delete

语法格式

<insert id="" parameterType="">
    INSERT INTO user(id,name,password,age,deleteFlag)
    VALUES(#{id},#{name},#{password},#{age},#{deleteFlag})
</insert>

<update id="" parameterType="">
	UPDATE tableName
    SET field1=#{field1},field2=#{field2}
    WHERE field3=#{field3}
</update>

<delete id="" parameterType="">
    DELETE FROM tableName 
    WHERE field1=#{field1}
</delete>
属性配置说明
id必选配置命名空间唯一标识符,一个命名空间对应一个持久层接口,该id对应持久层中的某个方法,需要同方法名保持一致。
parameterType可选配置指定传入参数的全限定名或别名,默认Mybatis自动推断出传入参数的类型。指定的数据类型可以是基本数据类型和String,或对象
flushCache可选配置(默认为true)用于设置在调用SQL语句后是否要求MyBatis清空之前查询的本地缓存和二级缓存,默认值为false,如果设置为true,则任何时候调用该SQl语句都将清空本地和二级缓存(对应插入、更新和删除语句)
statementType可选配置(默认为PREPARED)指定JDBC类型,取值为STATEMENT(Statement)PREPARED(PreparedStatement)CALLABLE(CallableStatement),默认值为PREPARED
keyProperty可选配置(默认为unset)唯一标记一个属性。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表
keyColumn可选配置通过生成的键值设置表中的列名。这个设置仅在某些数据库(PosrgreSQL)是必须的,当主键列不是表中的第一列的时候需要设置。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表
useGeneratedKeys可选配置(默认为false)使能MyBatis使用JDBC的getGeneratedKeys方法来取出由数据库内部生成的主键(比如MySql和SQLServer中的自动递增字段)
timeout用于设置超时的参数,单位是秒,超时将抛出异常(即设定等待数据库返回请求结果的时间,如果数据没有在指定时间内返回数据则抛出异常)

注意:以上属性中keyProperty、keyColumn、useGeneratedKeys仅对insert和update有用


select

select标签用于映射SQL语句的SELECT语句。

属性配置说明
id必选配置同Mapper的命名空间组合起来作为唯一标识,供MyBaits调用,同持久层接口文件中的方法名需保持一致
paramterType可选配置指定传入参数的全限定名或别名,默认Mybatis自动推断出传入参数的类型。指定的数据类型可以是基本数据类型和String,或对象
resultType同(resultType和reslutMap)二选一配置指定返回类型的全限定名。指定的类型可以是基本数据类型容器Bean对象
reslutMap同(resultType和reslutMap)二选一配置指定引用的返回参数映射集,需同标签一起使用,是高级复杂映射的关键
flushCache可选配置用于设置在调用SQL语句后是否要求MyBatis清空之前查询的本地缓存和二级缓存,默认值为false,如果设置为true,则任何时候调用该SQl语句都将清空本地和二级缓存
useCache可选配置启动二级缓存的开关,默认值为true,表示将查询结果存入二级缓存中
timeout可选配置用于设置超时的参数,单位是秒,超时将抛出异常(即设定等待数据库返回请求结果的时间,如果数据没有在指定时间内返回数据则抛出异常)
fethchSize可选配置尝试在获取数据时进行分批获取,指定每次分批获取的数量
statementType可选配置指定JDBC类型,取值为STATEMENT(Statement)PREPARED(PreparedStatement)CALLABLE(CallableStatement),默认值为PREPARED
resultSetType可选配置FORWARD_ONLYSCROLL_SENSITIVE或者SCROLL_INSENSITIVE。默认为空。

网络资源

https://www.cnblogs.com/dongying/p/4073259.html

https://www.cnblogs.com/wangdaijun/p/6132604.html


reslutMap

reslutMap实现复杂的映射关系,是实现多对一一对多关系的关键。

resultMap语法

<!--
	type 对应JavaBean对象的完全限定名或别名,也可以是其他类型
	id resultMap标签的唯一标识符,通过id对映射关系进行引用
-->
<resultMap type="" id="">
    <!--id为JavaBean的唯一标识,不一定是数据库主键
		property对应JavaBean类中的属性名
		column对应数据库中的字段名,
		(通过propert和column指定数据库表字段注入的属性,
		不用需要指定字段别名的情况)
	-->
	<id property="" column=""/><!--对应主键属性-->
    <result property="" column_""/><!--对应普通属性-->
    
    <!--constructor对应JavaBean中的构造方法-->
    <constructor>
    	<idArg column=""/><!--idArg对应构造方法中的id参数-->
        <arg column=""/><!--arg对应构造方法中的普通参数-->
    </constructor>
    
    <!--
	collection 处理一对多的关联关系
	property 对应JavaBean中容器对应的属性名
	column 对应数据库表中的字段名
	ofType 指定JavaBean中容器的类型
	resultMap 用于引用外部映射关系
	-->
    <collection property="" column="" ofType="" resultMap="">
        <id property="" column=""/>
    	<result property="" column_""/>
    </collection>
    
    <!--
	association 处理一对一的关联关系
	property JavaBean容器中对应的属性
	column 对应数据库表中的字段名
	javaType 指定关联的数据类型
	resultMap 用于引用外部映射关系,可以将association中的映射关系提取到外部的resultMap中
	-->
    <association property="" column="" javaType="" resultMap="">
        <id property="" column=""/>
    	<result property="" column_""/>
    </association>
</resultMap>

collection和associationi的区别

association映射的是一个JavaBean类

使用实例

Student.java

public class Student {
    private int id;
    private String idCard;
    private String name;
    private List<Course> courseList;
    private int deleteFlag;
    public Student(int id, String idCard, String name, List<Course> courseList, int deleteFlag){
        /*......*/
    }
    
    /*省略get和set方法*/
    }

Course.java

public class Course {
    private int id;
    private String name; 
    private int deleteFlag;
    /*省略get和set方法*/
}

reslutMap处理一对多关系的映示例:

<resultMap type="student" id="student"><!--type指定全路径名或别名-->
    <id property="idCard" column="stu_id_card"/>
    <result property="id" column="stu_id"/>
    <result property="name" column="stu_name"/>
    <result property="deleteFlag" column="stu_delete_flag"/>
    
    <collection property="courseList" column="stu_course_id" ofType="Course">	
    	<id property="name" column="course_name"/>
        <result property="deleteFlag" course="course_delete_flag"/>
    </collection>
</resultMap>

<select id="findStudentById" resultMap="studentMap">
    SELECT s.*,c.*
    FROM t_student s LEFT JOIN t_course 
    ON s.stu_course_id = c.course_id
    WHERE s.stu_id_card = #{idCard}
</select>

网络资源

https://www.cnblogs.com/dongying/p/4073259.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值