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>
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标签和外层标签的执行顺序,可以设置为BEFORE或AFTER,分别表示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_ONLY 、SCROLL_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
转载:https://blog.csdn.net/SZQ2Mei/article/details/101850095