mybatis-笔记

基本写法

insert

  • 取回自增主键
// useGeneratedKeys取出由数据库自动生成的主键,仅对支持主键自动生成的数据库有效,默认为 false
// keyProperty主键的名称,必须与useGeneratedKeys 一起使用,默认未设置

<insert id="insertUserNoId" useGeneratedKeys="true" keyProperty="id"
        parameterType="com.imooc.mybatis.model.User">
  INSERT INTO user(username,age,score) VALUES (#{username},#{age},#{score})
</insert>
  • 批量插入
// 需要在数据库配置文件中url中添加参数allowMultiQueries=true
<insert id="addPersons">
    insert into person(username,email,gender) VALUES
    <foreach collection="persons" item="vo" separator=",">
        (#{vo.username},#{vo.email},#{vo.gender})
    </foreach>
</insert>

update

<update id="updateUserAgeById">
  UPDATE user SET age = #{age} WHERE id = #{id}
</update>

// set  主要用于动态更新时,智能消除逗号
<update id="dynamicUpdate" parameterType="User">
  UPDATE user
   <set>
      <if test="title != null">title = #{title},</if>
      <if test="content != null">content = #{content},</if>
   </set>
   where id = #{id}
</update>

delete

<delete id="deleteUserById">
  DELETE FROM user WHERE id = #{id}
</delete>

query

  • 模糊查询
mybatis中内置的参数_databaseId中保存了用户所指定的对应的数据库厂商标识
mybatis的另一个内置参数_parameter保存了对应传入的对象
<if test="_databaseId == 'mysql'">
      CONCAT('%',#{username},'%')
</if>
<if test="_databaseId == 'postgre' or _databaseId= 'oracle' ">
      '%' || #{username} || '%'
</if>
  • IN 查询
 <select id="selectUserInIds" resultType="com.imooc.mybatis.model.User">
  SELECT * FROM user
  WHERE id IN
  <foreach collection="collection" open="(" close=")" separator="," item="item" index="index">
    #{item}
  </foreach>
</select>
  • 日期查询

jdbcType =DATE 日期精确到年月日 剩余分秒 填0补齐
jdbcType= TIMESTAMP 日期精确到时分秒
jdbcType 重要性 传入null值时,可以防止null空指针异常报错

<if test="startTime != null ">
   AND <![CDATA[ order_date >= #{startTime,jdbcType=DATE}  ]]>
</if>
  • FIND_IN_SET
select FIND_IN_SET('2', '1,2'); 返回2
select FIND_IN_SET('6', '1');    返回0 list中不存在str,所以返回0//使用find_in_set判断参数是否在数组中
queryWrapper.lambda()
.apply(!tag.isEmpty(), "FIND_IN_SET ('" + tag + "',label)");
  • SUM NULL问题
COALESCE函数:返回传入的参数中第一个非null的值,如果参数都是null则返回null,例:SELECT COALESCE(NULL, NULL, NULL,3); 返回结果为3

IFNULL函数进行查询,判断第一个参数是否为null,如果是 则返回结果为第二个参数(数值自定义):
  • 特殊符号
<![CDATA[ >=  ]]>
  • 时间间隔

假设要获取一个名为 timestamp_field 的字段和当前时间差多少天,其中 timestamp_field 存储的是毫秒时间戳,可以使用以下 SQL 语句:

SELECT DATEDIFF(NOW(), FROM_UNIXTIME(timestamp_field/1000)) AS diff_days FROM table_name;

其中,NOW() 函数返回当前时间,FROM_UNIXTIME() 函数将毫秒时间戳转换为 MySQL 的日期时间格式,DATEDIFF() 函数计算两个日期之间的天数差。最终得到的 diff_days 字段即为当前时间和 timestamp_field 的时间差,以天为单位。注意要将毫秒时间戳除以 1000,以转换为秒。

  • 派生字段查询 使用HAVING

如果需要对派生的 diff_days 字段进行范围查询,可以在 SQL 语句中使用 HAVING 子句。例如,如果要查询 diff_days 在 0 到 30 天之间的记录,可以使用以下 SQL 语句:

SELECT DATEDIFF(NOW(), FROM_UNIXTIME(timestamp_field/1000)) AS diff_days 
FROM table_name 
HAVING diff_days >= 0 AND diff_days <= 30;

在这个 SQL 语句中,HAVING 子句用于筛选 diff_days 字段在指定范围内的记录。根据实际需要,可以修改 HAVING 子句中的条件,以查询不同范围的记录。需要注意的是,由于 diff_days 是一个派生的字段,因此不能在 WHERE 子句中使用它进行筛选,而必须使用 HAVING 子句。

  • 语法顺序
SELECT [列名1], [列名2], ... 
FROM [表名] 
WHERE [条件] 
GROUP BY [列名1], [列名2], ... 
HAVING [条件] 
ORDER BY [列名] [ASC|DESC];

其他标签

  • resultType 上指定的类的全路径名(或指定了别名),MyBatis 会自动创建 resultMap 对象进行数据的映射
  • 使用resultMap标签直接定义映射关系,能避免 MyBatis类型 推断和映射带来的性能损耗
  • resultMap 和 resultType 不能共存,只能二选一
  • sql标签可以抽出一部分sql片段
  • parameterType 语句的参数类型,默认可选,MyBatis 会自动推断
<select id="selectUserAgeById" parameterType="java.lang.Integer" resultType="com.model.User">
	SELECT * FROM user WHERE id = #{id}
</select>

<resultMap id="userMap" type="com.model.Userr">
  <id property="id" column="id"/>
  <result property="username" column="username"/>
  <result property="age" column="age"/>
  <result property="score" column="score"/>
</resultMap>

<sql id="SELECT_CONTENT">
    id,username,age,score
</sql>
<select id="selectUserAgeById" parameterType="java.lang.Integer" resultMap="userMap">
	SELECT <include refid="SELECT_CONTENT"/> FROM user WHERE id = #{id}
</select>
  • trim 可以在自己包含的内容前加上某些前缀,也可以在其后加上某些后缀
prefix: 前缀属性,若标签内不为空则在 SQL 中添加上前缀;
prefixOverrides: 前缀覆盖属性,若标签中有多余的前缀,将会被覆盖(其实就是丢弃该前缀);
suffix: 后缀属性,若标签内不为空则在 SQL 中添加上后缀;
suffixOverrides: 后缀覆盖属性,若标签中有多余的后缀,将会被覆盖(其实就是丢弃该后缀)。

<update id="updateUsernameAndScoreById">
  UPDATE imooc_user
  <trim prefix="SET" suffixOverrides=",">
    <if test="username != null">
      username = #{username},
    </if>
    <if test="id != null">
      id = #{id}
    </if>
  </trim>
  WHERE id = #{id}
</update>

批处理

// ExecutorType设置
SIMPLE 就是普通的执行器(默认);
REUSE 执行器会重用预处理语句(prepared statements);
BATCH 执行器将重用语句并执行批量更新。

SqlSession session = MyBatisUtils.getSqlSessionFactory().openSession(ExecutorType.BATCH);
PersonMapper personMapper = session.getMapper(PersonMapper.class);
for (int i = 1100; i < 2000; i++) {
    Person person = new Person("boss" + i, i + "aa@q.com", "x");
    //应用批处理
    personMapper.addPerson(person);
}
session.commit();
session.close();

Mybatis插件-拦截器

  • ParameterHandler:处理SQL参数对象
  • ResultSetHandler:处理SQL返回的结果集对象
  • StatementHandler:数据库处理对象,用于执行sql语句
  • Executor:Mybatis执行器

Mybatis解析动态sql原理分析

https://www.cnblogs.com/fangjian0423/p/mybaits-dynamic-sql-analysis.html

posted @   Ranger-dev  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示