关于MyBatis动态sql,这⾥有10种超好⽤的写法
mybatis=<>的写法
第⼀种写法(1):
原符号<<=>>=&’"
替换符号<<=>>=&'"
例如:sql如下:
mysql语句的执行顺序create_date_time >= #{startTime} and create_date_time <= #{endTime}
第⼆种写法(2):
⼤于等于
<![CDATA[ >= ]]>
⼩于等于
<![CDATA[ <= ]]>
例如:sql如下:
create_date_time <![CDATA[ >= ]]> #{startTime} and create_date_time <![CDATA[ <= ]]> #{endTime}
1. ⽤来循环容器的标签forEach,查看例⼦
foreach元素的属性主要有item,index,collection,open,separator,close。
item:集合中元素迭代时的别名,
index:集合中元素迭代时的索引
open:常⽤语where语句中,表⽰以什么开始,⽐如以’('开始
separator:表⽰在每次进⾏迭代时的分隔符,
close 常⽤语where语句中,表⽰以什么结束,
在使⽤foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况下,该属性的值是不⼀样的,主要有⼀下3种情况:
如果传⼊的是单参数且参数类型是⼀个List的时候,collection属性值为list .
如果传⼊的是单参数且参数类型是⼀个array数组的时候,collection的属性值为array .
如果传⼊的参数是多个的时候,我们就需要把它们封装成⼀个Map了,当然单参数也可以封装成map,实际上如果你在传⼊参数的时候,在MyBatis⾥⾯也是会把它封装成⼀个Map的,map的key就是参数名,所以这个时候collection属性值就是传⼊的List或array对象在⾃⼰封装的map⾥⾯的key.
针对最后⼀条,我们来看⼀下官⽅说法:
注意 你可以将⼀个 List 实例或者数组作为参数对象传给 MyBatis,当你这么做的时候,MyBatis 会⾃动将它包装在⼀个 Map 中并以名称为键。List 实例将会以“list”作为键,⽽数组实例的键将是“array”。
所以,不管是多参数还是单参数的list,array类型,都可以封装为map进⾏传递。如果传递的是⼀个List,则mybatis会封装为⼀个list为key,list值为object的map,如果是array,则封装成⼀个array为key,array的值为object的map,如果⾃⼰封装呢,则colloection⾥放的是⾃⼰封装的map⾥的key值
//mapper中我们要为这个⽅法传递的是⼀个容器,将容器中的元素⼀个⼀个的
//拼接到xml的⽅法中就要使⽤这个forEach这个标签了
public List<Entity> queryById(List<String> userids);
//对应的xml中如下
<select id="queryById" resultMap="BaseReslutMap" >
select * FROM entity
where id in
<foreach collection="userids" item="userid" index="index" open="(" separator="," close=")">
#{userid}
</foreach>
</select>
2. concat模糊查询
//⽐如说我们想要进⾏条件查询,但是⼏个条件不是每次都要使⽤,那么我们就可以
/
/通过判断是否拼接到sql中
<select id="queryById" resultMap="BascResultMap" parameterType="entity">
SELECT * from entity
<where>
<if test="name!=null">
name like concat('%',concat(#{name},'%'))
</if>
</where>
</select>
3. choose (when, otherwise)标签
choose标签是按顺序判断其内部when标签中的test条件出否成⽴,如果有⼀个成⽴,则 choose 结束。
当 choose 中所有 when 的条件都不满则时,则执⾏ otherwise 中的sql。类似于Java 的 switch 语句,choose 为 switch,when 为 case,otherwise 则为 default。
例如下⾯例⼦,同样把所有可以限制的条件都写上,⽅⾯使⽤。choose会从上到下选择⼀个when标签的test为true的sql执⾏。安全考虑,我们使⽤where将choose包起来,放置关键字多于错误。
<!-- choose(判断参数) - 按顺序将实体类 User 第⼀个不为空的属性作为:where条件 -->
<select id="getUserList_choose" resultMap="resultMap_user" parameterType="com.yiibai.pojo.User">
SELECT *
FROM User u
<where>
<choose>
<when test="username !=null ">
u.username LIKE CONCAT(CONCAT('%', #{username, jdbcType=VARCHAR}),'%')
</when >
<when test="sex != null and sex != '' ">
AND u.sex = #{sex, jdbcType=INTEGER}
</when >
<when test="birthday != null ">
AND u.birthday = #{birthday, jdbcType=DATE}
</when >
<otherwise>
</otherwise>
</choose>
边框简笔画圆形
</where>
</select>
4. selectKey 标签
在insert语句中,在Oracle经常使⽤序列、在MySQL中使⽤函数来⾃动⽣成插⼊表的主键,⽽且需要⽅法能返回这个⽣成主键。使⽤myBatis的selectKey标签可以实现这个效果。
下⾯例⼦,使⽤mysql数据库⾃定义函数nextval(‘student’),⽤来⽣成⼀个key,并把他设置到传⼊的实体类中的studentId属性上。所以在执⾏完此⽅法后,边可以通过这个实体类获取⽣成的key。
<!-- 插⼊学⽣⾃动主键-->
<insert id="createStudentAutoKey" parameterType="liming.student.del.StudentEntity" keyProperty="studentId">
<selectKey keyProperty="studentId" resultType="String" order="BEFORE">
select nextval('student')
</selectKey>
INSERT INTO STUDENT_TBL(STUDENT_ID,
STUDENT_NAME,
STUDENT_SEX,
STUDENT_BIRTHDAY,
STUDENT_PHOTO,
CLASS_ID,
PLACE_ID)
VALUES (#{studentId},
没有数据库如何打开php文件#{studentName},
#{studentSex},
#{studentBirthday},
#{studentPhoto, javaType=byte[], jdbcType=BLOB, typeHandler=org.pe.BlobTypeHandler},
#{classId},
#{placeId})
</insert>
调⽤接⼝⽅法,和获取⾃动⽣成key
StudentEntity entity = new StudentEntity();
entity.setStudentName("黎明你好");
entity.setStudentSex(1);
entity.setStudentBirthday(DateUtil.parse("1985-05-28"));
entity.setClassId("20000001");
entity.setPlaceId("70000001");
ateStudentAutoKey(entity);
System.out.println("新增学⽣ID: " + StudentId());
5. if标签
if标签可⽤在许多类型的sql语句中,我们以查询为例。⾸先看⼀个很普通的查询:
<!-- 查询学⽣list,like姓名 -->
<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或等于空字符串,我们就不进⾏此条件的判断,增加灵活性。
参数为实体类StudentEntity。将实体类中所有的属性均进⾏判断,如果不为空则执⾏判断条件。
<!-- 2 if(判断参数) - 将实体类不为空的属性作为where条件 -->
<select id="getStudentList_if" resultMap="resultMap_studentEntity" parameterType="liming.student.del.StudentEntity">
SELECT ST.STUDENT_ID,
ST.STUDENT_NAME,
ST.STUDENT_SEX,
ST.STUDENT_BIRTHDAY,
ST.STUDENT_PHOTO,
ST.CLASS_ID,
ST.PLACE_ID
FROM STUDENT_TBL ST
WHERE
<if test="studentName !=null ">
ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName, jdbcType=VARCHAR}),'%')
</if>
<if test="studentSex != null and studentSex != '' ">
AND ST.STUDENT_SEX = #{studentSex, jdbcType=INTEGER}
</if>
<if test="studentBirthday != null ">
AND ST.STUDENT_BIRTHDAY = #{studentBirthday, jdbcType=DATE}
</if>
<if test="classId != null and classId!= '' ">
AND ST.CLASS_ID = #{classId, jdbcType=VARCHAR}
</if>
<if test="classEntity != null and classEntity.classId !=null and classEntity.classId !=' ' ">
AND ST.CLASS_ID = #{classEntity.classId, jdbcType=VARCHAR}
</if>
<if test="placeId != null and placeId != '' ">
AND ST.PLACE_ID = #{placeId, jdbcType=VARCHAR}
</if>
<if test="placeEntity != null and placeEntity.placeId != null and placeEntity.placeId != '' ">
AND ST.PLACE_ID = #{placeEntity.placeId, jdbcType=VARCHAR}
</if>
<if test="studentId != null and studentId != '' ">
AND ST.STUDENT_ID = #{studentId, jdbcType=VARCHAR}
</if>
</select>
使⽤时⽐较灵活, new⼀个这样的实体类,我们需要限制那个条件,只需要附上相应的值就会where这个条件,相反不去赋值就可以不在where中判断。
public void select_test_2_1() {
StudentEntity entity = new StudentEntity();
entity.setStudentName("");
entity.setStudentSex(1);
entity.setStudentBirthday(DateUtil.parse("1985-05-28"));eclipse下载安装教程学生使用
entity.setClassId("20000001");
//entity.setPlaceId("70000001");
List<StudentEntity> list = StudentList_if(entity);
for (StudentEntity e : list) {
System.out.String());
}
}
6. if + where 的条件判断
当where中的条件使⽤的if标签较多时,这样的组合可能会导致错误。我们以在3.1中的查询语句为例⼦,当java代码按如下⽅法调⽤时:
@Test
java nettypublic void select_test_2_1() {
StudentEntity entity = new StudentEntity();
entity.setStudentName(null);
entity.setStudentSex(1);
List<StudentEntity> list = StudentList_if(entity);
for (StudentEntity e : list) {
System.out.String());
}
}
如果上⾯例⼦,参数studentName为null,将不会进⾏STUDENT_NAME列的判断,则会直接导“WHERE AND”关键字多余的错误SQL。
这时我们可以使⽤where动态语句来解决。这个“where”标签会知道如果它包含的标签中有返回值的话,它就插⼊⼀个‘where’。此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉。
上⾯例⼦修改为:
<!-- 3 select - where/if(判断参数) - 将实体类不为空的属性作为where条件 -->
<select id="getStudentList_whereIf" resultMap="resultMap_studentEntity" parameterType="liming.student.del.StudentEntity">
SELECT ST.STUDENT_ID,
ST.STUDENT_NAME,
ST.STUDENT_SEX,
ST.STUDENT_BIRTHDAY,
ST.STUDENT_PHOTO,
ST.CLASS_ID,
ST.PLACE_ID
FROM STUDENT_TBL ST
<where>
<if test="studentName !=null ">
ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName, jdbcType=VARCHAR}),'%')
</if>
<if test="studentSex != null and studentSex != '' ">
AND ST.STUDENT_SEX = #{studentSex, jdbcType=INTEGER}
</if>
<if test="studentBirthday != null ">
AND ST.STUDENT_BIRTHDAY = #{studentBirthday, jdbcType=DATE}
</if>
<if test="classId != null and classId!= '' ">
AND ST.CLASS_ID = #{classId, jdbcType=VARCHAR}
</if>
<if test="classEntity != null and classEntity.classId !=null and classEntity.classId !=' ' ">
AND ST.CLASS_ID = #{classEntity.classId, jdbcType=VARCHAR}
</if>
<if test="placeId != null and placeId != '' ">
AND ST.PLACE_ID = #{placeId, jdbcType=VARCHAR}
</if>
<if test="placeEntity != null and placeEntity.placeId != null and placeEntity.placeId != '' ">
AND ST.PLACE_ID = #{placeEntity.placeId, jdbcType=VARCHAR}
</if>
王者荣耀名字空白代码<if test="studentId != null and studentId != '' ">
AND ST.STUDENT_ID = #{studentId, jdbcType=VARCHAR}
</if>
</where>
</select>
7. if + set实现修改语句
当update语句中没有使⽤if标签时,如果有⼀个参数为null,都会导致错误。
当在update语句中使⽤if标签时,如果前⾯的if没有执⾏,则或导致逗号多余错误。使⽤set标签可以将动态的配置SET 关键字,和剔除追加到条件末尾的任何不相关的逗号。使⽤if+set标签修改后,如果某项为null则不进⾏更新,⽽是保持数据库原值。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论