Mybatis日常使用小结

mybatis 使用mysql索引_mybatis使用及SQL语句优化小结 【摘要】 MyBatis 作为一款优秀的持久层框架,它支持自定义SQL、存储过程以及高级映射。一、mybatis总结1.mybatis查询/更新语句,没有找到符合条件的记录,会返回什么?返回类型为String的, 实际返回null;返回类型为对象的:实际返回null;返回类型为列表等集合:实际返回空集合[];返回类型为Boolean:实际返回false当数据库语句插入条件不满足,会返回fals... 阅读详情

这里主要介绍自己在项目中使用到的动态sql和一些注意事项。

动态SQL

简介:动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

我这里引用Mybatis官网对于常见的用法和我自己项目中的实际sql。

if

使用动态 SQL 最常见情景是根据条件包含 where 子句的一部分。比如:

<select id="findActiveBlogWithTitleLike"
     resultType="Blog">
  SELECT * FROM BLOG
  WHERE state = ‘ACTIVE’
  <if test="title != null">
    AND title like #{title}
  </if>
</select>

这条语句提供了可选的查找文本功能。如果不传入 “title”,那么所有处于 “ACTIVE” 状态的 BLOG 都会返回;如果传入了 “title” 参数,那么就会对 “title” 一列进行模糊查找并返回对应的 BLOG 结果(细心的读者可能会发现,“title” 的参数值需要包含查找掩码或通配符字符)。

如果希望通过 “title” 和 “author” 两个参数进行可选搜索该怎么办呢?首先,我想先将语句名称修改成更名副其实的名称;接下来,只需要加入另一个条件即可。

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <if test="title != null">
    AND title like #{title}
  </if>
  <if test="author != null and author.name != null">
    AND author_name like #{author.name}
  </if>
</select>
choose、when、otherwise

有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。

还是上面的例子,但是策略变为:传入了 “title” 就按 “title” 查找,传入了 “author” 就按 “author” 查找的情形。若两者都没有传入,就返回标记为 featured 的 BLOG(这可能是管理员认为,与其返回大量的无意义随机 Blog,还不如返回一些由管理员挑选的 Blog)。

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>
trim、where、set

前面几个例子已经合宜地解决了一个臭名昭著的动态 SQL 问题。现在回到之前的 “if” 示例,这次我们将 “state = ‘ACTIVE’” 设置成动态条件,看看会发生什么。

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG
  WHERE
  <if test="state != null">
    state = #{state}
  </if>
  <if test="title != null">
    AND title like #{title}
  </if>
  <if test="author != null and author.name != null">
    AND author_name like #{author.name}
  </if>
</select>

如果没有匹配的条件会怎么样?最终这条 SQL 会变成这样:

SELECT * FROM BLOG
WHERE

这会导致查询失败。如果匹配的只是第二个条件又会怎样?这条 SQL 会是这样:

SELECT * FROM BLOG
WHERE
AND title like ‘someTitle’

这个查询也会失败。这个问题不能简单地用条件元素来解决。这个问题是如此的难以解决,以至于解决过的人不会再想碰到这种问题。

MyBatis 有一个简单且适合大多数场景的解决办法。而在其他场景中,可以对其进行自定义以符合需求。而这,只需要一处简单的改动:

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG
  <where>
    <if test="state != null">
         state = #{state}
    </if>
    <if test="title != null">
        AND title like #{title}
    </if>
    <if test="author != null and author.name != null">
        AND author_name like #{author.name}
    </if>
  </where>
</select>

自己项目中使用的类似的:

<select id="getTotalByParams" resultType="Integer"
		parameterType="BlogQuery">
		select count(*) from hi_blog
		<where>
			<if test="title!= null and title != ''">
				title like "%"#{title}"%"
			</if>
			<if test="typeId != null and typeId != ''">
				and type_id = #{typeId}
			</if>
			<if test="isRecommend != null and isRecommend != ''">
				and is_recommend = #{isRecommend}
			</if>
		</where>


	</select>

where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。

如果 where 元素与你期望的不太一样,你也可以通过自定义 trim 元素来定制 where 元素的功能。比如,和 where 元素等价的自定义 trim 元素为:

<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ...
</trim>

prefixOverrides 属性会忽略通过管道符分隔的文本序列(注意此例中的空格是必要的)。上述例子会移除所有 prefixOverrides 属性中指定的内容,并且插入 prefix 属性中指定的内容。

用于动态更新语句的类似解决方案叫做 set。set 元素可以用于动态包含需要更新的列,忽略其它不更新的列。比如:

<update id="updateAuthorIfNecessary">
  update Author
    <set>
      <if test="username != null">username=#{username},</if>
      <if test="password != null">password=#{password},</if>
      <if test="email != null">email=#{email},</if>
      <if test="bio != null">bio=#{bio}</if>
    </set>
  where id=#{id}
</update>

这个例子中,set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。

来看看与 set 元素等价的自定义 trim 元素吧:

<trim prefix="SET" suffixOverrides=",">
  ...
</trim>

注意,我们覆盖了后缀值设置,并且自定义了前缀值。

foreach

动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。比如:

<select id="selectPostIn" resultType="domain.blog.Post">
  SELECT *
  FROM POST P
  WHERE ID in
  <foreach item="item" index="index" collection="list"
      open="(" separator="," close=")">
        #{item}
  </foreach>
</select>

foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符,看它多智能!

提示 你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。

注意事项

暂时用到的sql优化
  1. 查询时用到如select * from table之类的,最好将*改为全部的列名,以免*通过映射转为列名时的时间消耗。
  2. 在where语句中尽量将能排除大量数据的条件写在靠前的地方
注意
  1. 模糊查询时不用’’,要使用""。
    示例:
<select id="getTotalByParams" resultType="Integer"
		parameterType="BlogQuery">
		select count(*) from hi_blog
		<where>
			<if test="title!= null and title != ''">
				title like "%"#{title}"%"
			</if>
			<if test="typeId != null and typeId != ''">
				and type_id = #{typeId}
			</if>
			<if test="isRecommend != null and isRecommend != ''">
				and is_recommend = #{isRecommend}
			</if>
		</where>


	</select>

因为#{…}解析成sql语句时候,会在变量外侧自动加单引号’ ',所以这里 % 需要使用双引号" ",不能使用单引号 ’ ',不然会查不到任何结果。

  1. 当数据库字段与实体类字段不匹配时,怎么处理:此时就不能在select标签中使用resultType了,因为不匹配,所以需要一个映射将两者之间关联起来,示例如下:
<resultMap type="Type" id="TypeMap">
		<result property="id" column="id" />
		<result property="typeName" column="type_name" />

</resultMap>

<select id="listType" resultMap="TypeMap">
		select id,type_name
		from hi_type
</select>

select标签中的resultMap的值为resultMap标签的id, 而resultMap中property代表实体类的属性,而column代表数据库对应表中的列名。

  1. 当返回值是以下类型时:
    1、基本类型 :resultType=基本类型
    2、List类型: resultType=List中元素的类型
    3、Map类型 : resultType =map

  1. 当传参时传不同类型的两个参数怎么办,我现在项目中用的最简便方式:
// dao层的方法
Integer updateType(@Param("id") Long id, @Param("typeName") String typeName);

// 对应mapper的SQL
<update id="updateType">
		update hi_type t set t.type_name = #{typeName} where
		t.id = #{id}
</update>

  1. 别名的使用事项:使用了别名就不能使用原名了, 可以通过空格或者as给表起别名但是注意如果操作的数据库是Oracle的话,只能使用空格,as不符合Oracle的语法。 还有在mysql中的delete语句中,使用别名会有所变化:
// 在delete后面还要加别名名称,有几个别名写几个
delete t from hi_type t where t.id = #{id} 
// 下面写法会报错
delete from hi_type t where t.id = #{id} 
  1. select,insert,update,delete标签使用:insert/update/delete标签只是一个模板,在做操作时,其实是以SQL语句为核心的 。即在做增删时 insert/update/delete标签可通用 ,但做查询时只能用select标签,我们提倡什么操作就用什么标签 。还有在mybatis中如果是select标签中使用update语句不会有返回值,,,所以得改为update

  1. 在使用项目中有时需要使用top功能,即根据某列排序后查询出最前面的几行,在SQLServer中由top这个功能, 而mysql中通过分页中 的limit即可实现,不过和分页功能不同的是只需要传一个size参数即可,即查询top多少的数据,示例:
<select id ="listBlogTop" resultMap="BlogMap" parameterType="Integer"> 
		select id,title from hi_blog where is_published = 1 and is_recommend = 1  order by update_time desc limit #{size} </select>
  1. 插入时如果不插入id,则数据库中的表的id字段得设置自动增长。

  2. 如果自己项目中有很多根据一个参数查询的SQL,可以简化为一条SQL语句。
    如:

@Select("select * from user where id = #{id}")
User findById(@Param("id") long id);

@Select("select * from user where name = #{name}")
User findByName(@Param("name") String name);

@Select("select * from user where email = #{email}")
User findByEmail(@Param("email") String email);

// 其它的 "findByXxx" 方法

可以替换为:

@Select("select * from user where ${column} = #{value}")
User findByColumn(@Param("column") String column, @Param("value") String value);

其中 ${column} 会被直接替换,而 #{value} 会使用 ? 预处理。 这样,就能完成同样的任务:

User userOfId1 = userMapper.findByColumn("id", 1L);
User userOfNameKid = userMapper.findByColumn("name", "kid");
User userOfEmail = userMapper.findByColumn("email", "noone@nowhere.com");

这种方式也同样适用于替换表名的情况。

提示 用这种方式接受用户的输入,并用作语句参数是不安全的,会导致潜在的 SQL 注入攻击。因此,要么不允许用户输入这些字段,要么自行转义并检验这些参数。

Aspen Plus下载教程Aspen Plus V14 保姆级安装步骤(附安装包) 26、在WlmAdmin界面中,依次点击【Subnet Servers】、【admin】、【Add Feature】、【From a File】、【To Server and its File】。35、在产品选择页面,勾选需要安装的所有产品(重要:不要勾选【Aspen Online(Plant Data)】),然后点击【File Location】。回到桌面,点击任务栏的【开始菜单】,在【所有应用】中找到【Aspen Plus V14】软件图标,将其拖到桌面上创建快捷方式。9、这里可以更改软件的安装位置。 阅读详情

相关推荐

哨兵2号遥感影像解析全流程:步骤、算法与AI应用详解

未来,多源数据融合与边缘计算技术的应用将进一步拓展遥感解析的边界。波段合成:选择10m分辨率波段(如B2、B3、B4、B8)进行Layer Stacking,生成多光谱影像。| 分类与识别 | Scikit-Learn、PyTorch | SVM、CNN、K-Means聚类 | 地块分类、目标检测 || 数据预处理 | SNAP、Sen2Cor | 大气校正、几何校正 | L2A产品生成、格式转换 || 波段融合 | ENVI、GDAL | Layer Stacking、重采样 | 多光谱影像合成 |

zhz5214的博客 2714

MyBatis拦截器

JBDC的底层主要是三个接口对象,Connection、Statement、ResultSet。Connection用于建立与数据库的连接,Statement用于向数据库发送sql语句,ResultSet用于封装sql查询语句的结果。

zhzjn的博客 1178

杰理SDK入门教程(一):SDK的四种编译方式的使用

杰理SDK提供了四种主要编译方式:1) JL Studio官方IDE,适合初学者;2) VS Code轻量级编辑器,需在SDK根目录打开;3) 命令行/脚本编译,灵活支持自动化;4) Code::Blocks开源IDE。每种方式都有详细操作指南,开发者可根据需求选择,初学者推荐从JL Studio开始熟悉编译流程。环境配置注意事项和编译成功标识均有明确说明,确保开发效率。

qq_42014563的博客 1153

MyBatis常用注解

一、MyBatis常用注解 @Insert 增 例:@Insert("INSERT INTO 表名(字段名) VALUE(字段值) ") @Delete 删 例:@Delete("DELETE FORM 表名 WHERE 条件 ") @Update 改 例:@Insert("UPDATE 表名 SET 字段名=字段值 WHERE 条件 ") @Select 查 例:@Insert(...

Java编程基础 326

基于STM32设计的老人防摔倒报警设备(OneNet)_65

本文设计了一种基于STM32单片机的智能老人防摔倒报警设备。该系统结合MPU6050陀螺仪传感器实时监测老人的姿态变化,检测摔倒事件;通过SIM800C通信模块发送短信通知紧急联系人,并将GPS定位信息上传至云端平台,确保家属能够及时了解老人的准确位置。

1万+

前端技能树,面试复习第 54 天—— 手写代码:情景题

前端修罗场提供全网最专业的前端优质文章与社区服务,为应届生,初中级前端工程师提供全面、优质的面试服务、技能提升、职场解惑服务!内容包含:前端面试辅导,前端面试题,前端交流,前端答疑,前端基础知识,前端知识体系,技能树搭建,Javascript,CSS,CSS3,HTML,React,Vue,小程序,前端简历,职业交流,远程工作,英文交流,英文提升,外企,互联网,国企,大厂,牛客面试题,掘金面试题,面经,优质前端文章分享...

前端进阶之路 | 中大厂、外企、国企内推 | 面试培训 | 简历修改 986

mybatis中update返回值是where条件匹配的记录数

转载:https://www.jianshu.com/p/80270b93082a mybatis 中的 update 返回值你真的明白吗

cg_Amaz1ng的博客 527

比NTP还牛逼的时间同步协议:1588v2,亚微秒级!

1588v2,又称为Precision Time Protocol Version 2,即精密时间协议的第二版本,或称为PTPv2,是一种精密时间同步协议标准,旨在实现网络中设备之间的高精度时间同步。该协议由IEEE标准组织发布,并在网络测量和控制系统中得到广泛应用。1588v2的主要目的是在计算机网络中提供高度准确的时间同步。它可用于确保不同设备之间的时钟同步,从而协调它们的操作。这对于需要协同工作的系统、无线通信基站等具有关键性的应用非常重要。

网络技术联盟站 4282

mybatis 多租户,新增时加注入字段,查改删添加where条件

mybatis 多租户,新增时加注入字段,查改删添加where条件

weixin_41423378的博客 1991

零差云控 ZeroErr eRob 电机 CAN、CANopen、EtherCAT、ROS2 机器人开发详细教程

TwinCAT 3(Windows 控制与自动化技术)是 Beckhoff 提供的开发平台,可将任何兼容 PC 转变为实时控制系统,用于管理各种类型的工业自动化系统,如 PLC(可编程逻辑控制器)、运动控制、机器人等。

机器人控制与仿真应用 1万+

【WRFDA教程第一期】运行观测预处理程序(OBSPROC)

运行观测预处理程序(OBSPROC)

WW、forever的博客 1900

四、mybatis第四节

在我们日常使用中,缺少不了分页查询,就好比你百度时,那么多的数据,肯定需要分页来处理。那么我们就可以用分页插件来帮我们快速实现分页查询操作首先了解一下分页查询的sql语句: 其中的page代表你想要查询的页码数,pageSize代表你想要每页显示的数据个数。 那么我们该如何使用分页插件呢?具体步骤如下:(1)在pom.xml中引入pageHelper的依赖jar包 (2) 在mybatis.xml中设置pageHelper的拦截器(写在configuration标签内)

lrs998563的博客 1132

Oracle11g下载与安装(windows)

一、Oracle11g下载 二、安装准备 三、执行安装步骤 四、测试连接 附:Oracle11g服务说明

欢迎订阅我的“JAVA全栈开发笔记(全)”专栏,价格优惠,仅需19.9元。 2万+

开发日常小结(28):Mybatis 分页插件 -- PageHelper 使用小结

2018年7月23日09:50:01 【1、背景】 1)aop切面编程,spring框架提供的招牌菜之一(另一个是ioc,依赖注入),用于提供对模块化程序的切面处理; 2)需求:一个是使用dataTable的服务器模式,通过物理分页,获取数据;二是对于某些数据,我们想让最新的Mysql数据显示在dataTable的最前面,(可以理解为id最大的数据排序最前面)   【2、构思】 1)使...

Diligence is the mother of success. 440

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

【Mybatis -日常使用记录】

标签定义公共的 SQL 片段,并为其指定一个唯一的id。这个id将在后续的<include>标签中被引用。= null"></if>-- 可以继续添加其他公共条件 -->

迷迷糊糊,懵懵懂懂 5406

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

MyBatis的IFNULL的使用小结

Mybatis-MySQL 中使用IFNULL(p1,p2)函数 但是有一些需要注意的地方. 假设数据 title: student id name age 1 Ann 18 2 Bom 19 3 Hehe SELECT name,age FROM student WHERE id = 3; 此时查询结果就是 name age hehe 使用I...

weixin_38137028的博客 2万+

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Mybatis 小结

封装了JDBC Statement操作,负责对JDBC statement 的操作,如设置参数、将Statement结果集转换成List集合。对用户传递的参数转换成JDBC Statement 所需要的参数。资源加载模块java数据类型和jdbc数据类型之间的映射和转换。根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回。动态生成的SQL语句及相应的参数信息。10.

weixin_42679286的博客 466

Mybatis-Plus在日常的具体使用

版本字段的类型通常为 Integer 或 Long,在更新数据时,MyBatis-Plus 会自动对该字段的值进行检查和递增。3.启动类中配置@MapperScan(“com.shen.sh.mapper”)来扫描位置也可以在yml文件中配置文件来扫描。如果版本号不一致,则说明数据已经被其他事务修改,此时应当放弃更新,提示用户数据已被修改。如果版本号一致,则说明数据没有被其他事务修改,可以执行更新操作,并将版本号加 1。System.out.println(“更新失败,数据可能已经被其他用户修改”);

yhl50333的博客 806

MyBatis小结

1.@param_mybatis的参数绑定 @param("给绑定的参数起一个名字") 对于参数为复杂的类型---Map Map就是实体<K,V>,通过@param注解value的属性值作为键,参数为值,通过#{}来访问键从而获取对应的的参数值. 2.自定义继承自mybatis的连接池数据源工厂类 连接池的特点: 1)创建一些固定的可重用的连接对象,重复利用它们,当某个连接对象被某个持有的线程使用完毕之后,然后归还连接池中; 2)保证线程安全. 自定义继承自mybatis的连接池

qq_52619957的博客 6191

Mybatis日常使用总结

目录 1、mybatis xml中大于等于的写法 2、运行时报参数错误 3、Mybatis自动生成key值 4、使用where标签 5、返回map类型对象 6、使用choose when then 1、mybatis xml中大于等于的写法 1、用了转义字符把>和<替换掉 如:WHERE 1 = 1 AND start_date &lt;= CURRENT_...

liyongjian12的博客 610

Mybatis的初级使用小结

mybatis的尚硅谷笔记Mybatis的insertMyBatis的批量insertMyBatis的动态insertMybatis的普通insert方法Mybatis的selectMyBatis的select 动态条件MyBatis的动态select service拼接条件Mybatis的updateMybatis的普通updateMybatis的动态updateMybatis的deleteMybatis的单条删除Mybatis的批量删除Mybatis的标签<sql> 和< include&.

weixin_44226752的博客 681

MyBatis使用小结

1. MyBatis 1.1. 作用 MyBatis是持久层框架,它是支持JDBC的!简化了持久层开发! 使用MyBatis时,只需要通过接口指定数据操作的抽象方法,然后配置与之关联的SQL语句,即可完成! 持久化存储:在程序运行过程中,数据都是在内存(RAM,即内存条)中的,内存中的数据不是永久存储的,例如程序可以对这些数据进行销毁,或者由于断电也会导致内存中所有数据丢失!而把数据存储到硬盘中...

TTC0605的博客 470

Mybatis代码笔记小结

根据站长的Mybatis部分内容 敲代码后的注释小结 Mybatis基础概念 MyBatis的传入参数parameterType类型分两种 基本数据类型:int,string,long,Date; 复杂数据类型:类和Map 如何获取参数中的值: 2.1 基本数据类型:#{value}或${value} 获取参数中的值 2.2 复杂数据类型:#{属性名}或KaTeX parse error: Expected 'EOF', got '#' at position 15: {属性

m0_50292871的博客 166

Mybatis使用小结

《诗经》有言:“靡不有初,鲜克有终。” 今天第一次使用Mybatis,感觉还不错,下面就今天的学习情进行一番总结。 什么是Mybatis框架 MyBatis 本是apache的一个开源项目Ibatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。iBAT

传传传传传传奇 392

Mybatis小结

Mybatis什么是框架?为什么使用框架?主流框架介绍jdbc问题总汇什么是Mybatis (是一个不完全的orm(对象关系映射)框架。)Mybatis中的xml文件等Mybatis执行过程面试小结 什么是框架? 可以理解为帮助我们实现了一部分功能,优点:减少代码量,提高开发效率 为什么使用框架? 每个优秀的框架都是对底层的代码做了轻量级的封装,目的是减少代码量,提高开发效率. JAVAEE三...

Tamandjey的博客 233

mybatis-plus使用小結

mybatis-plus 使用小结

腾蛟起凤吕学士 754
上一篇: 计算机网络学习之路
下一篇: 怎样解决启动Tomcat报错端口号被占用?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值