网上得来终觉浅

_φ(❐_❐✧ 人丑就要多读书

导航

统计

ms

2022-6-20

mybatis动态SQL常用的标签

1. <sql>标签。

也叫<sql>片段,在使用sql片段时使用include标签通过sql片段的id进行引用

 <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        id, name, age, hobby, del_flag, create_time, update_time
    </sql>
    <select id="listAnimals" resultType="com.zhang.entity.Animal">
        select
	<!--<include>可以是单标签的,效果是一样的-->
        <include refid="Base_Column_List"></include>
        from animal
    </select>

2.<where>标签、<if>标签

  • where;根据where其后是否有sql,判断拼接 where,满足条件就拼接,否则不拼接
  • if:当参数满足条件才会执行某个条件
    <select id="getAnimalByName" resultType="com.zhang.entity.Animal">
        select * from animal
        <where>
            <if test="name!=null and name!=''">
                and name = #{name}
            </if>
        </where>
    </select>

3.choose、when、otherwise 标签.

choose、when、otherwise : choose标签是按顺序判断其内部when标签中的test条件是否成立,如果有一个成立,则choose结束;如果所有的when条件都不满足时,则执行otherwise中的SQL。类似于java的switch语句。

<select id="getAnimalsByNameOrHobby" resultType="com.zhang.entity.Animal">
        select * from animal
        <choose>
            <when test="hobby!=null and hobby!='' and name!=null and name!=''">
                hobby = #{hobby} and name = #{name}
            </when>
            <when test="hobby!=null and hobby!=''">
                hobby = #{hobby}
            </when>
            <otherwise>
                name = #{name}
            </otherwise>
        </choose>
    </select>

4.<set>标签

set标签用于解决动态更新语句存在的符号问题
与where有相似,其后如果存在条件,则拼接set。标签会动态前置SET关键字,并且自动帮我们去掉多余的逗号,适用于update,示例:

    <update id="update">
        update animal
        <set>
            <if test="age!=null and age!=''">
                age = #{age}
            </if>
            <if test="name!=null and name!=''">
                name = #{name},
            </if>
            <if test="hobby!=null and hobby!=''">
                hobby = #{hobby}
            </if>
        </set>
        where id = #{id}
    </update>
    <update id="updateById" parameterType="com.zhang.entity.Animal">
    update animal
    <set>
        <if test="name != null">
            `name` = #{name,jdbcType=VARCHAR},
        </if>
        <if test="age != null">
            `age` = #{age,jdbcType=VARCHAR},
        </if>
        <if test="hobby != null">
            hobby = #{hobby,jdbcType=VARCHAR},
        </if>
        <if test="create_time != null">
            create_time = #{create_time,jdbcType=TIMESTAMP},
        </if>
        <if test="update_time != null">
            update_time = #{update_time,jdbcType=TIMESTAMP},
        </if>
    </set>
    where id = #{id,jdbcType=INTEGER}
    </update>

5.<foreach>标签

用于遍历List、Map、Array , 属性如下:

collection:指定需要遍历的元素
item:遍历之后的每一项
separator:定义foreach里面语句的分隔符
index:map中代表key,数组中代表数组下标

    <select id="listAnimals" resultType="com.zhang.entity.Animal">
        SELECT * FROM animal
        WHERE id in
        <foreach collection="ids" item="id" index="index"
                 open="(" close=")" separator=",">
            #{id}
        </foreach>
    </select>

6。<bind>标签,用来定义变量,

示例:

mapper层:
List<Animal> getByName(@Param("animalName") String name);
xml映射层: 
    <select id="getByName" resultType="com.zhang.entity.Animal">
        <!--animalName为传过来的参数-->
        <!--根据动物名字进行模糊查询-->
        <bind name="animalNameLike" value="'%'+ animalName +'%'"/>
        select * from animal
        <where>
            <if test="animalName != null and animalName != ''">
                and `name` like #{animalNameLike}
            </if>
        </where>
    </select>

bind:bind标签可以从OGNL(对象图导航语言)表达式中创建一个变量并将其绑定到上下文
Mybatis中使用Mysql的模糊查询字符串拼接(like) 中也涉及到bind的使用

<select id="findName" resultType="String">
 	 SELECT stu.name FROM tab_stu stu 
	<where>
 		<if test="name!= null">
 			<bind name="stuName" value="'%'+stuName+'%'">
			name like #{stuName}
		</if> 
	</where>
</select>

7.trim

trim:trim标签可实现where/set标签的功能
Trim标签有4个属性,分别为prefix、suffix、prefixOverrides、suffixOverrides
prefix:表示在trim标签包裹的SQL前添加指定内容
suffix:表示在trim标签包裹的SQL末尾添加指定内容
prefixOverrides:表示去掉(覆盖)trim标签包裹的SQL指定首部内容,去掉多个内容写法为and |or(中间空格不能省略)(一般用于if判断时去掉多余的AND |OR)
suffixOverrides:表示去掉(覆盖)trim标签包裹的SQL指定尾部内容(一般用于update语句if判断时去掉多余的逗号)

<select id="findName" resultType="String">
 	 SELECT stu.name FROM tab_stu stu 
	<trim prefix="where" prefixOverrides="and |or">
		<if test="age != null">
			age = #{age}
		</if> 
 		<if test="name!= null">
			AND name= #{name}
		</if> 
		<if test="class!= null">
			OR class = #{class}
		</if> 
	</trim>
</select>
<update id=”updateStu”>
			Update tab_stu
			<trim prefix="set" subfix="where id=#{id}" suffixOverrides=",">
				<if test="name != null"> name=#{name},</if>
				<if test="age != null"> age=#{age},</if>
				<if test="class != null"> class=#{class},</if>
				<if test="subject != null"> subject=#{subject}</if>
			</trim>
</update>

mybatis批量插入后获取自增主键

批量插入返回自增ID列表和普通插入返回自增ID是一样的,通常只需要在 mapper.xml 的 上添加属性 useGeneratedKeys=“true” keyProperty=“id” 就能实现插入成功后,mybatis 会把获得的自增ID set 到对象里,如自动 set 到 user 对象的 id 属性里,而非通过返回值获得ID或ID列表。

Dao

void insertBatch(List<User> users); // 批量插入

Mapper.xml

<insert id="insertBatch" useGeneratedKeys="true" keyColumn="user_id" keyProperty="userId" parameterType="java.util.List">
        insert into user
        (user_name, age)
        values
        <foreach collection="list" separator="," item="item">
            (
            #{item.userName, item.age}
            )
        </foreach>
    </insert>

需要注意

关于这个批量导入返回id列表需要注意以下几点
1、确保 mybatis 版本在 3.3.1 以上
2、batchInsert 方法上不能加 @param()
3、batchInsert 方法只能一个参数
4、batchInsert 返回值为 Integer 或 void,不能写 List
5、如果你的自增id数据库字段和实体类属性不一致,如 user_id 和 userId, 需要写成useGeneratedKeys=“true” keyColumn=“user_id” keyProperty=“userId”

mysql中的select,from,where,groupby等关键字执行顺序

我们平常写的顺序是这样的:

SELECT
DISTINCT<select_list>
FROM<left_table>
<join_type>JOIN<right_table>
ON<join_condition>
WHERE<where_condition>
GROUPBY<group_by_list>
HAVING<having_condition>
ORDERBY<order_by_condition>
LIMIT<limit_number>

执行顺序:

FROM
<表名># 笛卡尔积

ON
<筛选条件># 对笛卡尔积的虚表进⾏筛选

JOIN<join,leftjoin,rightjoin...>
<join># 指定join,⽤于添加数据到之后的虚表中,例如left join会将左表的剩余数据添加到虚表中

WHERE
<where条件> #对上述虚表进⾏筛选

GROUPBY
<分组条件> #分组

<SUM()等聚合函数> #⽤于having⼦句进⾏判断,在书写上这类聚合函数是写在having判断⾥⾯的
HAVING

<分组筛选> #对分组后的结果进⾏聚合筛选
SELECT
<返回数据列表> #返回的单列必须在group by⼦句中,聚合函数除外

DISTINCT #数据除重

ORDERBY
<排序条件> #排序 

LIMIT
<⾏数限制>

其实,引擎在执⾏上述每⼀步时,都会在内存中形成⼀张虚拟表,然后对虚拟表进⾏后续操作,并释放没⽤的虚拟表的内存,以此类推。

  1. from:select * from table_1, table_2; 与 select * from table_1 join table_2; 的结果⼀致,都是表⽰求笛卡尔积;⽤于直接计算
    两个表笛卡尔积,得到虚拟表VT1,这是所有select语句最先执⾏的操作,其他操作时在这个表上进⾏的,也就是from操作所完成的
    内容
  2. on: 从VT1表中筛选符合条件的数据,形成VT2表;
    join: 将该 join 类型的数据补充到VT2表中,例如 left join 会将左表的剩余数据添加到虚表VT2中,形成VT3表;若表的数量⼤于2,则会重复1-3步;
  3. where: 执⾏筛选,(不能使⽤聚合函数)得到VT4表;
  4. group by: 对VT4表进⾏分组,得到VT5表;其后处理的语句,如select,having,所⽤到的列必须包含在group by条件中,没有出现的需要⽤聚合函数;
  5. having: 筛选分组后的数据,得到VT6表;
  6. select: 返回列得到VT7表;
  7. distinct: ⽤于去重得到VT8表;
  8. order by: ⽤于排序得到VT9表;
  9. limit: 返回需要的⾏数,得到VT10;

posted on   bgtong  阅读(224)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示