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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!