MyBatis的动态SQL详解
mybatis注解动态sql原理
mybatis注解动态sql原理
MyBatis是一种基于Java语言的持久层框架,提供了一种使用
注解的方式来编写SQL语句,称为MyBatis注解。
动态SQL
是MyBatis中一个重要的特性,可以根据不同的条件生成不同的SQL语句。
MyBatis通过提供注解来实现动态SQL。
注解是一种元数据,
可以通过在方法或参数上添加注解来指定SQL语句的一些特性。
MyBatis注解提供了多种条件注解,用于动态生成SQL语句。
动态SQL的原理如下:
1. 在Java代码中,我们可以通过添加不同的注解来指定SQL
语句的不同条件,比如条件判断、循环等。
2. MyBatis会解析这些注解,并根据注解中的条件生成对应的SQL语句。
例如,如果有一个条件判断的注解,MyBatis会根
据条件判断的结果来生成对应的SQL语句。
3. 生成的SQL语句会被传递给数据库进行执行。
动态SQL的好处是可以根据不同的条件生成不同的SQL语句,从而实现更灵活的查询功能。
同时,使用注解编写SQL语句,可以减少编写XML配置文件的工作量,提高开发效率。
总结起来,动态SQL是通过使用注解来指定SQL语句的不同
条件,MyBatis会根据注解中的条件生成对应的SQL语句,从而实现灵活的查询功能。
mybatis 动态sql if用法
电子合同存证服务合同甲方(以下简称“甲方”):公司名称:法定代表人姓名:注册地址:乙方(以下简称“乙方”):公司名称:法定代表人姓名:注册地址:鉴于甲方拥有一定的电子合同存证服务能力,乙方希望委托甲方为其提供电子合同存证服务,各方经友好协商,达成如下协议:第一条服务内容1.1甲方应根据乙方的需求,为其提供电子合同存证服务,具体服务内容如下:(1)检验、验证和签署电子合同的真实性和完整性;(2)为电子合同提供可追溯的时间戳;(3)提供电子合同存证的相关证明文件;(4)确保电子合同数据的安全性和保密性;(6)其他甲方与乙方约定的服务。
1.2甲方应按照服务内容及时、准确地向乙方提供相关服务。
乙方应根据甲方的要求提供相应的合同、协议等信息,以便甲方进行存证操作。
1.3乙方委托甲方存证的电子合同应符合国家法律法规规定的合法合同,甲方不对电子合同的内容、效力和合法性承担责任。
第二条服务费用及支付方式2.1乙方向甲方支付的服务费用为每份电子合同存证服务收费XXXX元。
2.2服务费用的支付方式为:(1)乙方应在甲方提供存证服务后的7个工作日内,将应付费用以现金/银行转账/电汇等方式支付至甲方指定的账户;(2)乙方应提供相应的付款凭证给予甲方,以便甲方核查。
2.3如乙方逾期未支付服务费用,甲方有权采取如下措施之一或多项:(1)中止电子合同存证服务;(2)要求乙方支付延迟履行的违约金;(3)要求乙方支付逾期履行的滞纳金;(4)追究乙方的违约责任。
第三条保密义务3.1甲方应对乙方委托存证的电子合同数据严格保密,不得泄露、篡改或非法使用。
3.2甲方不得将乙方的电子合同数据提供给任何第三方,除非取得乙方书面同意或法律法规另有规定。
3.3乙方如发现甲方存在泄露、篡改或非法使用电子合同数据等违法违规行为,有权要求甲方承担相应的法律责任,并取得相应的赔偿。
第四条风险责任4.1由于电子合同存证服务所涉及的信息传输和数据存储,可能面临各种风险,包括但不限于网络故障、黑客攻击、系统崩溃等。
mybatis之动态sql(超详细)
mybatis之动态sql(超详细)动态SQL可以根据具体的参数条件,来对SQL语句进⾏动态拼接。
⽐如在以前的开发中,由于不确定查询参数是否存在,许多⼈会使⽤类似于where 1 = 1来作为前缀,然后后⾯⽤AND拼接要查询的参数,这样,就算要查询的参数为空,也能够正确执⾏查询,如果不加1 = 1,则如果查询参数为空,SQL语句就会变成SELECT * FROM student where,SQL不合法。
mybatis⾥的动态标签主要有if<!-- ⽰例 --><select id="find"resultType="student"parameterType="student">SELECT * FROM student WHERE age >= 18<if test="name != null and name != ''">AND name like '%${name}%'</if></select>当满⾜test条件时,才会将<if>标签内的SQL语句拼接上去。
choose<!-- choose 和 when , otherwise 是配套标签类似于java中的switch,只会选中满⾜条件的⼀个--><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 != null">AND author_name like #{}</when><otherwise>AND featured = 1</otherwise></choose></select>sql<!-- List<User> findByList(List<Integer> list); --><select id="findByList"resultType="er"parameterType="java.util.List"> SELECT * FROM user<include refid="rnm"></include></select><sql id="rnm"><where><if test="list != null and list.size() > 0">AND id in<foreach collection="list"item="id"open="("separator=","close=")">#{id}</foreach></if></where></sql>trimwhere<where>标签只会在⾄少有⼀个⼦元素返回了SQL语句时, 才会向SQL语句中添加WHERE,并且如果WHERE之后是以AND或OR开头,会⾃动将其删掉。
MyBatis执行动态SQL语句详解
MyBatis执⾏动态SQL语句详解⼤家基本上都知道如何使⽤ MyBatis 执⾏任意 SQL,使⽤⽅法很简单,例如在⼀个 XXMapper.xml 中:<select id="executeSql" resultType="map">${_parameter}</select>你可以如下调⽤:sqlSession.selectList("executeSql", "select * from sysuser where enabled = 1");或者你可以在 XXMapper.java 接⼝中定义如下⽅法:List<Map> executeSql(String sql);然后使⽤接⼝调⽤⽅法:xxMapper.executeSql("select * from sysuser where enabled = 1");上⾯这些内容可能都会,下⾯在此基础上再复杂⼀点。
假如像上⾯SQL中的enabled = 1我想使⽤参数⽅式传值,也就是写成 enabled = #{enabled},如果你没有遇到过类似这种需求,可能不明⽩为什么要这么写,举个例⼦,要实现⼀种动态查询,可以在前台通过配置 SQL,提供⼀些查询条件就能实现⼀个查询的功能(为了安全,这些配置肯定是开发或者实施做的,不可能让⽤户直接操作数据库)。
针对这个功能,使⽤ MyBatis 实现起来相当容易。
配置 SQL 肯定要执⾏,⽤上⾯讲的这种⽅式肯定可以执⾏ SQL,如何提供参数呢?参数就是enabled = #{enabled}中的#{enabled}部分。
如果再多⼀些条件,⼀个配置好的 SQL 如下:select * from sysuserwhere enabled = #{enabled}and userName like concat('%',#{userName},'%')这种情况下,该怎么⽤ MyBatis 实现呢?⾸先 XML 中修改如下:<select id="executeSql" resultType="map">${sql}</select>接⼝中的⽅法修改为:List<Map> executeSql(Map map);然后调⽤⽅法:Map map = new HashMap();//这⾥的 sql 对应 XML 中的 ${sql}map.put("sql", "select * from sysuser "+ " where enabled = #{enabled} "+ " and userName like concat('%',#{userName},'%')");//#{enabled}map.put("enabled", 1);//#{userName}map.put("userName", "admin");//接⼝⽅式调⽤List<Map> list = xxMapper.executeSql(map);//sqlSession⽅式调⽤sqlSession.selectList("executeSql", map);有了这个SQL之后,就可以将 enabled 和 userName 作为条件提供给⽤户。
Mybatis中的动态SQL语句解析
Mybatis中的动态SQL语句解析这篇⽂章主要介绍了Mybatis中的动态SQL语句解析,⽂中通过⽰例代码介绍的⾮常详细,对⼤家的学习或者⼯作具有⼀定的参考学习价值,需要的朋友可以参考下 Mybatis中配置SQL有两种⽅式,⼀种是利⽤xml ⽅式进⾏配置,⼀种是利⽤注解进⾏配置。
Mybatis使⽤注解配置SQL,但是由于配置功能受限,⽽且对于复杂的SQL⽽⾔可读性很差,所以很少使⽤。
Mybatis常⽤xml配置的⽅式,使⽤xml的⼏个简单的元素,便能完成动态SQL的功能,⼤量的判断都可以在mybaties的映射xml⾥⾯配置,以达到许多需要⼤量代码才能实现的功能,⼤⼤减少了代码量,体现了Mybatis的灵活、⾼度可配置性和维护性。
元素作⽤备注if判断语句单条件分⽀判断choose(when,otherwise)相当于Java中的switch和case语句多条件分⽀判断trim辅助元素,⽤于处理特定的SQL拼装问题⽤于处理SQL拼装的问题foreach循环语句在in语句等列表条件常⽤if元素 if元素是最常⽤的判断语句,相当于Java中国的 if 语句,它常常与test属性联合使⽤。
<select id="findRole1" parameterType="string" resultMap="roleResultMap">select role_no, role_name, note from t_role where 1=1<if test="roleName != null and roleName !=''">and role_name like concat('%', #{roleName}, '%')</if></select> 当参数roleName传递进映射器时,如果参数不为空,则采取构造对 roleName 的模糊查询,否则就不要去构造这个条件。
MyBatis动态SQL————MyBatis动态SQL标签的用法
MyBatis动态SQL————MyBatis动态SQL标签的⽤法1.MyBatis动态SQLMyBatis 的强⼤特性之⼀便是它的动态 SQL,即拼接SQL字符串。
如果你有使⽤ JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦。
拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。
利⽤动态 SQL 这⼀特性可以彻底摆脱这种痛苦。
通常使⽤动态 SQL 不可能是独⽴的⼀部分,MyBatis 当然使⽤⼀种强⼤的动态 SQL 语⾔来改进这种情形,这种语⾔可以被⽤在任意的 SQL 映射语句中。
动态 SQL 元素和使⽤ JSTL 或其他类似基于 XML 的⽂本处理器相似。
在 MyBatis 之前的版本中,有很多的元素需要来了解。
MyBatis 3 ⼤⼤提升了它们,现在⽤不到原先⼀半的元素就可以了。
MyBatis 采⽤功能强⼤的基于 OGNL 的表达式来消除其他元素。
2.动态SQL标签:if,choose (when, otherwise),trim (where, set),foreach2.1 if标签:直接上代码<select id="queryByIdAndTitle"resultType="Blog">SELECT * FROM BLOGWHERE 1=1<if test="id!= null and title!=null">AND id=#{id} and title=#{title}</if></select>注:if标签⼀般⽤于⾮空验证,如上例,若id为空,if标签⾥的代码,将不会执⾏,反之,则会执⾏。
2.2 choose(when,otherwise)标签:直接上代码<select id="queryBy"resultType="Blog">SELECT * FROM BLOG WHERE 1=1<choose><when test="title != null">AND title like #{title}</when><otherwise>AND id= 1</otherwise></choose></select>注:choose(when,otherwise)标签相当于switch(case,default) ,如上例,若title 为空,when标签⾥的代码,将不会执⾏,默认执⾏otherwise 标签⾥⾯的代码。
ibaties 动态sql 解析
ibaties 动态sql 解析iBATIS (现在已经更名为MyBatis) 是一款流行的Java 持久化框架,具有强大的动态SQL 解析功能。
动态SQL 在开发过程中经常用到,它允许我们创建灵活的SQL 查询,根据不同的条件生成不同的SQL 语句。
本文将以"iBATIS 动态SQL 解析" 为主题,详细介绍如何使用iBATIS 动态SQL 解析功能进行动态SQL 查询。
第一步: 环境准备在开始使用iBATIS 的动态SQL 解析功能之前,首先需要准备开发环境。
我们需要安装Java JDK 和一个Java 开发环境,例如Eclipse 或者IntelliJ IDEA。
另外,还需要在项目中引入iBATIS 的相关依赖库。
第二步: 配置数据源和iBATIS在准备好开发环境后,接下来需要配置数据源和iBATIS。
首先,我们需要连接到数据库,可以选择MySQL、Oracle 或者其他主流的数据库。
在项目中,可以通过配置数据源的方式连接到数据库。
接下来,需要在项目中引入iBATIS 的配置文件,通常命名为"SqlMapConfig.xml"。
在该配置文件中,我们需要配置数据库连接信息、iBATIS 的相关设置以及动态SQL 查询语句的配置。
第三步: 创建实体类和映射文件在配置好数据源和iBATIS 后,接下来需要创建实体类和映射文件。
实体类是与数据库中的表对应的Java 类,我们需要定义实体类的属性和相应的getter 和setter 方法。
映射文件是iBATIS 中的核心组件,用于描述数据库表和实体类之间的映射关系。
在映射文件中,我们需要定义SQL 查询语句,包括静态SQL 和动态SQL。
其中,动态SQL 部分使用iBATIS 的"动态SQL 标签" 实现。
第四步: 使用动态SQL在准备好实体类和映射文件后,我们可以开始使用iBATIS 的动态SQL 功能。
MyBatis源码解析----MyBatis动态SQL底层原理分析
MyBatis源码解析----MyBatis动态SQL底层原理分析前⾔废话不多说,直接进⼊⽂章。
我们在使⽤mybatis的时候,会在xml中编写sql语句。
⽐如这段动态sql代码:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15<update id="update"parameterType="er"> UPDATE users<trim prefix="SET"prefixOverrides=","><if test="name != null and name != ''">name = #{name}</if><if test="age != null and age != ''">, age = #{age}</if><if test="birthday != null and birthday != ''">, birthday = #{birthday}</if></trim>where id = ${id}</update>mybatis底层是如何构造这段sql的?这⽅⾯的知识⽹上资料不多,于是就写了这么⼀篇⽂章。
下⾯带着这个疑问,我们⼀步⼀步分析。
介绍MyBatis中⼀些关于动态SQL的接⼝和类SqlNode接⼝,简单理解就是xml中的每个标签,⽐如上述sql的update,trim,if标签:1 2 3public interface SqlNode {boolean apply(DynamicContext context); }SqlSource Sql源接⼝,代表从xml⽂件或注解映射的sql内容,主要就是⽤于创建BoundSql,有实现类DynamicSqlSource(动态Sql 源),StaticSqlSource(静态Sql源)等:1 2 3public interface SqlSource {BoundSql getBoundSql(Object parameterObject); }BoundSql类,封装mybatis最终产⽣sql的类,包括sql语句,参数,参数源数据等参数:XNode,⼀个Dom API中的Node接⼝的扩展类。
mybatis动态sql语法
mybatis动态sql语法在使用MyBatis进行数据库操作时,使用动态SQL可以有效地处理不同查询条件下的不同SQL语句。
MyBatis提供了一套灵活的动态SQL语法,使得我们能够根据需要动态生成SQL语句,以满足各种查询需求。
本文将详细介绍MyBatis动态SQL语法的使用。
一、if语句if语句是MyBatis中最常用的动态SQL语法之一。
通过if语句,我们可以根据条件判断来生成不同的SQL片段。
示例代码如下:```<select id="getUserList" resultType="User">SELECT *FROM userWHERE 1 = 1<if test="username != null and username != ''">AND username = #{username}</if><if test="age != null">AND age = #{age}</if></select>```在上述代码中,我们使用了if语句来生成动态的WHERE子句。
首先,我们判断username字段是否为空,如果不为空,则将其加入WHERE子句;然后,我们判断age字段是否为空,如果不为空,则同样将其加入WHERE子句。
通过这种方式,我们可以根据不同的查询条件动态生成不同的SQL语句。
二、choose语句choose语句也是常用的动态SQL语法之一。
它类似于Java中的switch语句,根据条件判断来选择执行不同的分支。
示例代码如下:```<select id="getUserList" resultType="User">SELECT *FROM user<where><choose><when test="username != null and username != ''">AND username = #{username}</when><when test="age != null">AND age = #{age}</when><otherwise>AND status = 1</otherwise></choose></where></select>```在上述代码中,我们使用choose语句来生成动态的WHERE子句。
Mybatis解析动态sql原理分析
Mybatis解析动态sql原理分析1.MyBatis⼀般使⽤步骤1.1获取Configuration实例或编写配置⽂件//获取Configuration实例的样例TransactionFactory transactionFactory = new JdbcTransactionFactory();//定义事务⼯⼚Environment environment =new Environment("development", transactionFactory, dataSource);Configuration configuration = new Configuration(environment);configuration.addMapper(BlogMapper.class);配置⽂件的编写请看21.2⽣成SqlSessionFactory实例(⼀个数据库对应⼀个SqlSessionFactory)//通过Configuration实例⽣成SqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);//通过xml配置⽂件⽅式⽣成SqlSessionFactoryString resource = "org/mybatis/example/Configuration.xml";Reader reader = Resources.getResourceAsReader(resource);sqlSessionFactory= new SqlSessionFactoryBuilder().build(reader);1.3⽣成SqlSession实例//样例SqlSession session = sqlSessionFactory.openSession();1.4执⾏sql各种操作//样例try {Blog blog = (Blog) session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);} finally {session.close();}2.MyBatis的配置⽂件解析2.1配置⽂件的基本结构configuration —— 根元素properties —— 定义配置外在化settings —— ⼀些全局性的配置typeAliases —— 为⼀些类定义别名typeHandlers —— 定义类型处理,也就是定义java类型与数据库中的数据类型之间的转换关系objectFactoryplugins —— Mybatis的插件,插件可以修改Mybatis内部的运⾏规则environments —— 配置Mybatis的环境environmenttransactionManager —— 事务管理器dataSource —— 数据源databaseIdProvidermappers —— 指定映射⽂件或映射类2.2 properties元素——定义配置外在化<!--样例--><properties resource="org/mybatis/example/config.properties"><property name="username" value="dev_user"/><property name="password" value="F2Fa3!33TYyg"/></properties>配置外在化的属性还可以通过SqlSessionFactoryBuilder.build()⽅法提供,如:SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, props);配置外在化的优先级是 build⽅法->resource属性指定的⽂件->property元素2.3 settings元素——Mybatis的⼀些全局配置属性设置参数描述有效值默认值cacheEnabled这个配置使全局的映射器启⽤或禁⽤缓存。
mybatis动态sql解析
1.MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑。
MyBatis中用于实现动态SQL的元素主要有:•if•choose(when,otherwise)•trim•where•set•foreachif就是简单的条件判断,利用if语句我们可以实现某些简单的条件选择。
先来看如下一个例子:Xml代码1.<select id="dynamicIfTest" parameterType="Blog" resultType="Blog">2. select * from t_blog where 11 = 13. <if test="title != null">4. and title = #{title}5. </if>6. <if test="content != null">7. and content = #{content}8. </if>9. <if test="owner != null">10. and owner = #{owner}11. </if>12.</select>这条语句的意思非常简单,如果你提供了title参数,那么就要满足title=#{title},同样如果你提供了Content和 Owner的时候,它们也需要满足相应的条件,之后就是返回满足这些条件的所有Blog,这是非常有用的一个功能,以往我们使用其他类型框架或者直接使用 JDBC的时候,如果我们要达到同样的选择效果的时候,我们就需要拼SQL语句,这是极其麻烦的,比起来,上述的动态SQL就要简单多了。
choose元素的作用就相当于JAVA中的switch语句,基本上跟JSTL中的choose 的作用和用法是一样的,通常都是与when和otherwise搭配的。
myBatis--动态SQL
myBatis--动态SQL⼀、介绍动态 SQL是MyBatis强⼤特性之⼀。
极⼤的简化我们拼装SQL的操作。
动态 SQL 元素和使⽤ JSTL 或其他类似基于 XML 的⽂本处理器相似。
MyBatis 采⽤功能强⼤的基于 OGNL 的表达式来简化操作。
⼆、动态SQL1.if注意:在查询的时候有些条件没有带上,以⾄于SQL语句拼装会出现问题:①where后⾯写上 1=1 ,所有的if条件都要以 and 开头②使⽤<where>标签将所有的条件包含在标签中;但是这种⽅式只适合and或者or在语句前2.choose分⽀选择 (when, otherwise):带了break的switch-case3.trim字符串截取 (where封装查询条件, set封装修改条件)4.foreach(1)遍历(2).批量保存⽅式⼀:⽅式⼆:开启分隔多条查询三、OGNL表达式1.OGNL2.bind可以将OGNL 的值绑定在⼀个变量上,⽅便以后引⽤这个变量的值四、两个内置参数myBatis默认的两个内置参数:1. _parameter:代表整个参数如果是⼀个参数:代表这个参数本⾝如果是多个参数:例如map集合,那么急代表这个集合2. _databaseId:如果配置了DatabaseIdProvider标签,则_databaseId就是代表当前数据库的别名五、sql标签抽取可重⽤的SQL⽚段,⽅便后续的引⽤;1.SQL抽取:经常要查询或者更新的列名,抽取出来进⾏引⽤2.include标签:将抽取好的部分进⾏引⽤3.include标签还可以⾃定义字段使⽤<property>标签,要使⽤${⾃定义的参数}取值。
mybatis动态sql test用法
mybatis动态sqltest用法==========概述--MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。
动态SQL则是MyBatis中的一个重要特性,它允许你在运行时构建SQL语句。
本篇文章将介绍MyBatis动态SQL的Test用法,帮助你更好地理解和使用动态SQL。
一、动态SQL的类型--------在MyBatis中,动态SQL主要由三种类型构成:1.`if`:根据条件判断,决定是否包含某个SQL片段。
2.`choose`、`when`、`otherwise`:类似于Java中的switch-case结构,根据条件执行不同的SQL片段。
3.`foreach`:用于迭代集合,生成批量插入的SQL语句。
二、Test用法详解--------Test是MyBatis提供的一个标签,用于在XML映射文件中构建动态SQL。
它的用法非常灵活,可以结合其他标签来构建复杂的SQL语句。
###1.使用Test构建条件判断可以使用Test标签结合if标签来构建条件判断的SQL语句。
例如:```xml<selectid="findActiveUsers"resultType="User">SELECT*FROMusersWHEREstatus=1<Testcondition="status==1">ANDage>30</Test></select>```在上面的例子中,如果status字段的值为1,则会在SQL语句中添加一个条件`ANDage>30`。
###2.使用Test构建循环语句可以使用Test标签结合foreach标签来构建循环语句,用于批量插入或更新数据。
例如:```xml<insertid="insertUsers"parameterType="list">INSERTINTOusers(name,age)<foreachcollection="list"item="user"index="index"separator=",">VALUES(<Test>${}</Test>,<Test>${user.age}</Test>)</foreach></insert>```在上面的例子中,foreach标签会遍历名为list的参数,并使用Test标签拼接出一个个SQL插入语句。
mybatis动态sql原理
mybatis动态sql原理MyBatis是一个优秀的Java持久层框架,它具有很强的动态SQL 功能。
动态SQL可以让我们在SQL语句中根据需要动态地添加或删除一些语句段,从而生成一条最终的SQL语句。
那么,MyBatis动态SQL 的实现原理是什么呢?下面将从以下几个方面阐述。
1. SQL语句的解析MyBatis解析SQL语句时,会将所有的“#{}”或“${}”里面的内容都当做参数来处理,最终会转换成JDBC能够识别的SQL语句。
其中,#{}是MyBatis所定义的预编译语句,可以有效避免SQL注入的问题;而${}则是直接把参数的值嵌入到SQL语句中,存在注入的风险。
2. 动态SQL标签的使用MyBatis提供了多个动态SQL标签,如if、choose、when、otherwise、foreach等,通过它们,我们可以根据条件动态生成SQL 语句中的各种语句段。
其中,if标签可以实现简单的条件判断;foreach标签可以用于遍历集合或数组;choose、when、otherwise标签可以模拟Java中的switch语句。
3. 动态SQL标签的嵌套MyBatis允许动态SQL标签的嵌套使用,这也是其实现动态SQL 功能的关键之一。
我们可以将多个if标签、foreach标签、choose标签等组合使用,生成更加复杂、灵活的SQL语句。
4. 动态SQL的缓存机制MyBatis使用了缓存机制来提高动态SQL执行的效率。
具体来说,MyBatis首先将SQL语句的字符串作为key,以SqlSource的形式作为value进行缓存;当第一次执行该SQL语句时,MyBatis会根据缓存中的SqlSource对象生成MappedStatement对象并缓存起来。
这样,当下次再次执行相同的SQL语句时,MyBatis就可以从缓存中直接获取MappedStatement对象,提高了性能。
总之,MyBatis动态SQL的实现是建立在SQL语句解析、动态SQL标签的使用、标签的嵌套、以及缓存机制等多个方面的基础上的。
mybatis动态sql的原理
mybatis动态sql的原理
MyBatis 的动态 SQL 是通过 XML 配置文件或注解的方式实现的,它的主要原理如下:
1. 解析 SQL 配置文件:MyBatis 首先会解析 XML 配置文件,将其中定义的 SQL 语句和参数信息解析出来。
2. 根据参数生成 SQL:使用解析得到的 SQL 语句模板和参数信息,MyBatis 会根据参数的值动态生成最终的 SQL 语句。
在生成 SQL 过程中,MyBatis 会根据不同的情况判断使用哪些语句片段和条件。
3. 执行 SQL:MyBatis 将生成的 SQL 语句交给数据库进行执行,并获取执行结果。
4. 将结果映射到 Java 对象:MyBatis 通过配置文件或注解中定义的映射关系,将查询结果映射到相应的 Java 对象中,便于后续的数据操作和处理。
动态 SQL 的原理主要是通过在 SQL 配置文件中定义逻辑判断和循环等语句片段,结合参数值进行条件判断和 SQL 拼接,从而生成最终的 SQL 语句。
这样可以根据不同的条件动态调整 SQL 语句,实现灵活的查询和更新操作。
同时,MyBatis 还提供了 OGNL 表达式语言的支持,使得在 SQL 配置文件中可以通过表达式对参数进行进一步的处理和计算。
Mybatis动态SQL简单了解Mybatis简介(四)
Mybatis动态SQL简单了解Mybatis简介(四)动态SQL概况MyBatis 的强⼤特性之⼀便是它的动态 SQL在Java开发中经常遇到条件判断,⽐如:if(x>0){//执⾏⼀些逻辑........}Mybatis应⽤中,SQL映射通常位于XML⽂件内,在执⾏前需要将XML中的映射转换为最终要执⾏的SQL在转换中是否可以根据输⼊动态的处理SQL?这就是动态SQL,⽐如<select id="findActiveBlogWithTitleLike"resultType="Blog">SELECT * FROM BLOGWHERE state = ‘ACTIVE’<if test="title != null">AND title like #{title}</if></select>上⾯的<if test="title != null"> 就是动态SQL处理,将会根据实际传递的title的值,动态的决定SQL的内容,是否包含最后⾯的AND Mybatis的动态SQL元素不多,但是简单⾼效,Mybatis的动态SQL元素类似JSTL类型主要有三种:条件判断内容处理循环处理对于每种不同的类型⼜有各⾃的格式和属性条件处理if是最基本的⼀种形式,语意为:如果xxx就xxx通过最基本的if可以构造很复杂的条件测试语句,相当于if(){}choose是特殊化的if,相当于if(){}else{}你可以添加多个if,⽐如if(){}if(){}if(){}else{}通常对于⼀个choose是可以拆分为多个if条件的,但是很显然,某些场景下,使⽤if else的形式⽐多个if 要更加简单清晰if和choose⾥⾯when后的条件都是使⽤test进⾏设置的内容处理trim⽤于动态内容头尾的处理,可以添加前缀prefix或者添加后缀suffix也可以移除匹配的指定的前缀prefixOverrides,或者移除匹配的指定的后缀suffixOverrides简⾔之可以借助于trim对拼接内容的头尾进⾏处理where相当于<trim prefix="WHERE" prefixOverrides="AND |OR ">表⽰在最前⾯添加where,如果最开始是AND 或者OR 将会进⾏删除set相当于<trim prefix="SET" suffixOverrides=",">表⽰在最前⾯添加set,如果最后⾯是⼀个逗号, 将他删除循环遍历foreach⽤于动态的循环拼接,相当于for循环动态拼接内容for(int i =0;i<list.size;i++){String s +=“...”;}对于foreach,需要指明需要遍历循环的参数名称,通过collection指定需要指定循环变量,也就是在循环中使⽤哪个变量指代,相当于Object o = list.get(i); 使⽤item指定的就是这个o还可以指定变量⽤于记录索引,通过这个索引变量可以获得迭代的次数索引,通过index对于open, separator, close,就是在字符串拼接的开头,中间,结尾,添加的分割符信息。
MyBatis--动态SQL(bind的用法)
MyBatis--动态SQL(bind的⽤法) bind标签可以使⽤OGNL表达式创建⼀个变量并将其绑定到上下⽂中。
在前⾯的UserMapper.xml有⼀个selectByUser⽅法,这个⽅法⽤到了like查询条件。
使⽤concat函数连接字符串,在MySQL中,这个函数⽀持多个参数,但在Oracle中⽀持两个参数。
由于不同数据库之间的语法差异,如果更换数据库,有些SQL语句可能就需要重写。
针对这种情况,可以使⽤bind标签来避免由于更换数据库带来的⼀些⿇烦 bind标签的两个属性都是必选项,name为绑定到上下⽂的变量名,value为OGNL表达式。
创建⼀个bind标签的变量后,就可以在下⾯直接使⽤,使⽤bind拼接字符串不仅可以避免因更换数据库⽽修改SQL,也能防⽌SQL注⼊。
多数据库⽀持: bind标签并不能解决更换数据库带来的所有问题,那么还可以通过什么⽅式⽀持不同的数据库?这需要⽤到if标签以及由MyBatis提供的databaseIdProvider数据库⼚商标识配置。
这⾥的DB_VENDOR会通过DatabaseMetaData#getDatabaseProductName()返回的字符串进⾏设置。
由于通常情况下这个字符串都⾮常长⽽且相同的产品的不同版本会返回不同的值,所以通常通过设置属性别名来使其变短,代码如下: 上⾯列举了常见的数据库产品名称,在有property配置时,databaseId将被设置为第⼀个能匹配数据库产品名称的属性键对应的值,如果没有匹配的属性则会被设置为null。
如果getDatabaseProductName()返回Microsoft SQL Server,databaseId将被设置为sqlserver。
当基于不同数据库运⾏时,MyBatis会根据配置找到合适的SQL去执⾏。
数据库的更换可能只会引起某个SQL语句的部分不同,可以使⽤if标签配合默认的上下⽂中的_databaseId参数这种写法去实现。
mybatis动态sql的解析流程
mybatis动态sql的解析流程MyBatis是一种Java持久化框架,它提供了许多灵活而强大的功能,其中包括动态SQL的解析流程。
动态SQL允许开发人员根据不同的条件生成不同的SQL语句,从而实现更灵活的查询。
首先,MyBatis会解析XML或注解中的SQL语句,并将其转换为一个内部的SQL对象。
这个SQL对象包含了原始的SQL语句以及一些额外的信息。
然后,MyBatis会根据用户提供的参数,动态地构建SQL语句。
在动态SQL的解析流程中,我们通常使用以下几种元素和技术:1. if元素:通过在SQL语句中使用if元素,我们可以根据条件判断动态地包含或排除某些部分。
例如:```xml<select id="getUserById" parameterType="int" resultType="User">SELECT * FROM userWHERE id = #{id}<if test="name != null">AND name = #{name}</if></select>```在上述例子中,如果用户传递了name参数,则条件将会成立,SQL语句中将包含一个额外的AND子句。
2. choose、when和otherwise元素:这些元素允许我们根据条件选择不同的路径。
例如:```xml<select id="getUserList" parameterType="User" resultType="User">SELECT * FROM user<choose><when test="name != null">WHERE name = #{name}</when><when test="age != null">WHERE age = #{age}</when><otherwise>WHERE gender = 'male'</otherwise></choose></select>```在上述例子中,根据用户传递的参数,选择不同的WHERE子句。
MyBatis动态SQL全面详解
MyBatis动态SQL全⾯详解⽬录前⾔动态sql1.先看⼀下模块⽬录结构2.物理建模和逻辑建模3. 引⼊依赖4.全局配置⽂件5.sql共性抽取⽂件6.mapper接⼝if静态sql:动态sql:where⽤if标签的动态sql:where和if的动态sql:trimtrim的动态sqltrim标签:settrim的动态sql:set的动态sqlset标签的作⽤:choose、when、otherwise动态sqlforeach1.动态sql2.动态sql批量查询:foreach标签测试程序前⾔前⾯mysql都是通过静态sql进⾏查询的,但是如果业务复杂的时候,我们会遇到引号问题,或者多⼀个空格,这就使得sql代码编写错误了,所以为了解决这个问题,我们有了动态sql。
Mybatis框架的动态SQL技术是⼀种根据特定条件动态拼装SQL语句的功能,它存在的意义是为了解决拼接SQL语句字符串时的痛点问题。
具体是通过标签来实现的。
动态sql1.先看⼀下模块⽬录结构在类路径的resources下的mapper包下创建sql.xml⽂件(共性抽取)2.物理建模和逻辑建模这⾥省略物理建模步骤,要求数据库的表与pojo类要对应。
package pojo;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;@Data@AllArgsConstructor@NoArgsConstructorpublic class Employee {private Integer empId;private String empName;private Double empSalary;}3. 引⼊依赖把之前的log4j复制到类路径resouces下,另外我们引⼊依赖后的pom.xml如下:<?xml version="1.0" encoding="UTF-8"?><project xmlns="/POM/4.0.0"xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>day03-mybatis02-dynamic</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.8</version><scope>provided</scope></dependency><!-- Mybatis核⼼ --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.7</version></dependency><!-- junit测试 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!-- MySQL驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.3</version><scope>runtime</scope></dependency><!-- log4j⽇志 --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency></dependencies></project>4.全局配置⽂件<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configurationPUBLIC "-////DTD Config 3.0//EN""/dtd/mybatis-3-config.dtd"><configuration><!--驼峰映射--><settings><setting name="mapUnderscoreToCamelCase" value="true"/></settings><!--类型别名映射--><typeAliases><package name="pojo"/></typeAliases><!--环境配置--><environments default="dev"><environment id="dev"><transactionManager type="JDBC"></transactionManager><dataSource type="POOLED"><property name="username" value="root"/><property name="password" value="888888"/><property name="url" value="jdbc:mysql://localhost:3306/mybatis-example"/><property name="driver" value="com.mysql.jdbc.Driver"/></dataSource></environment></environments><!--路径映射--><mappers><mapper resource="mapper/sql.xml"/><package name="mapper"/></mappers></configuration>注意:这⾥有驼峰映射,别名映射,路径映射和路径映射。
mybatis dynamic sql 用法
mybatis dynamic sql 用法MyBatis的动态SQL用于根据不同条件动态生成SQL语句,以便进行灵活的数据库操作。
下面是MyBatis动态SQL的用法示例:1. 使用if标签使用if标签可以根据条件判断是否包含某个SQL语句片段。
```<select id="getUserList" resultMap="userResultMap">SELECT * FROM usersWHERE 1=1<if test="username != null and username != ''">AND username = #{username}</if><if test="email != null and email != ''">AND email = #{email}</if></select>```2. 使用choose、when和otherwise标签使用choose、when和otherwise标签可以根据多个条件选择执行不同的SQL语句片段。
```<select id="getUserList" resultMap="userResultMap">SELECT * FROM users<where><choose><when test="username != null and username != ''">AND username = #{username}</when><when test="email != null and email != ''">AND email = #{email}</when><otherwise>AND status = 1</otherwise></choose></where></select>```3. 使用foreach标签使用foreach标签可以根据集合进行循环,动态生成SQL语句片段。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
MyBatis的动态SQL详解MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑。
MyBatis中用于实现动态SQL的元素主要有:∙if∙choose(when,otherwise)∙trim∙where∙set∙foreachif就是简单的条件判断,利用if语句我们可以实现某些简单的条件选择。
先来看如下一个例子:01<selectid="dynamicIfTest"parameterType="Blog"resultType="Blog">02 select * from t_blog where 1 = 103 <iftest="title != null">05 and title = #{title}06 </if>07 <iftest="content != null">08 and content = #{content}09 </if>10 <iftest="owner != null">11 and owner = #{owner}12 </if>14</select>这条语句的意思非常简单,如果你提供了title参数,那么就要满足title=#{title},同样如果你提供了Content和Owner的时候,它们也需要满足相应的条件,之后就是返回满足这些条件的所有Blog,这是非常有用的一个功能,以往我们使用其他类型框架或者直接使用JDBC的时候,如果我们要达到同样的选择效果的时候,我们就需要拼SQL语句,这是极其麻烦的,比起来,上述的动态SQL就要简单多了。
choose元素的作用就相当于JAVA中的switch语句,基本上跟JSTL中的choose的作用和用法是一样的,通常都是与when和otherwise搭配的。
看如下一个例子:0 1<selectid="dynamicChooseTest"parameterType="Blog"resultType="Blog" >2select * from t_blog where 1 = 103 <choose>05 <whentest="title != null">06 and title = #{title}07 </when>08 <whentest="content != null">09 and content = #{content}10 </when>11 <otherwise>13 and owner = "owner1"14 </otherwise>15 </choose>16</select>when元素表示当when中的条件满足的时候就输出其中的内容,跟JAVA中的switch效果差不多的是按照条件的顺序,当when中有条件满足的时候,就会跳出choose,即所有的when和otherwise条件中,只有一个会输出,当所有的我很条件都不满足的时候就输出otherwise中的内容。
所以上述语句的意思非常简单,当title!=null的时候就输出and titlte = #{title},不再往下判断条件,当title为空且content!=null的时候就输出and content =#{content},当所有条件都不满足的时候就输出otherwise中的内容。
where语句的作用主要是简化SQL语句中where中的条件判断的,先看一个例子,再解释一下where的好处。
01<selectid="dynamicWhereTest"parameterType="Blog"resultType="Blog">02 select * from t_blog03 <where>04 <iftest="title != null">05 title = #{title}06 </if>07 <iftest="content != null">09 and content = #{content}10 </if>11 <iftest="owner != null">12 and owner = #{owner}13 </if>14 </where>15</select>where元素的作用是会在写入where元素的地方输出一个where,另外一个好处是你不需要考虑where元素里面的条件输出是什么样子的,MyBatis会智能的帮你处理,如果所有的条件都不满足那么MyBatis就会查出所有的记录,如果输出后是and 开头的,MyBatis会把第一个and忽略,当然如果是or开头的,MyBatis也会把它忽略;此外,在where元素中你不需要考虑空格的问题,MyBatis会智能的帮你加上。
像上述例子中,如果title=null,而content != null,那么输出的整个语句会是select * from t_blog where content = #{content},而不是select * from t_blog where and content = #{content},因为MyBatis会智能的把首个and 或or 给忽略。
trim元素的主要功能是可以在自己包含的内容前加上某些前缀,也可以在其后加上某些后缀,与之对应的属性是prefix和suffix;可以把包含内容的首部某些内容覆盖,即忽略,也可以把尾部的某些内容覆盖,对应的属性是prefixOverrides和suffixOverrides;正因为trim有这样的功能,所以我们也可以非常简单的利用trim来代替where元素的功能,示例代码如下:01<selectid="dynamicTrimTest"parameterType="Blog"resultType="Blog">02 select * from t_blog03 <trimprefix="where"prefixOverrides="and |or">05 <iftest="title != null">06 title = #{title}07 </if>08 <iftest="content != null">09 and content = #{content}10 </if>11 <iftest="owner != null">13 or owner = #{owner}14 </if>15 </trim>16</select>set元素主要是用在更新操作的时候,它的主要功能和where元素其实是差不多的,主要是在包含的语句前输出一个set,然后如果包含的语句是以逗号结束的话将会把该逗号忽略,如果set包含的内容为空的话则会出错。
有了set元素我们就可以动态的更新那些修改了的字段。
下面是一段示例代码:01<updateid="dynamicSetTest"parameterType="Blog">02 update t_blog03 <set>04 <iftest="title != null">05 title = #{title},06 </if>07 <iftest="content != null">0809 content = #{content},10 </if>11 <iftest="owner != null">12 owner = #{owner}14 </set>15 where id = #{id}16</update>上述示例代码中,如果set中一个条件都不满足,即set中包含的内容为空的时候就会报错。
foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。
foreach元素的属性主要有item,index,collection,open,separator,close。
item表示集合中每一个元素进行迭代时的别名,index指定一个名字,用于表示在迭代过程中,每次迭代到的位置,open表示该语句以什么开始,separator表示在每次进行迭代之间以什么符号作为分隔符,close表示以什么结束,在使用foreach的时候最关键的也是最容易出错的就是collection 属性,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的,主要有一下3种情况:1. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list2. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array3. 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,实际上如果你在传入参数的时候,在MyBatis里面也是会把它封装成一个Map的,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key下面分别来看看上述三种情况的示例代码:1.单参数List的类型:1<selectid="dynamicForeachTest"resultType="Blog">2 select * from t_blog where id in3 <foreachcollection="list"index="index"item="item"open="("separa tor=","close=")">5 </foreach>67</select>上述collection的值为list,对应的Mapper是这样的1publicList<Blog>dynamicForeachTest(List<Integer> ids);测试代码:01@Test02publicvoiddynamicForeachTest() {03 SqlSession session = Util.getSqlSessionFactory().openSession();04 BlogMapperblogMapper = session.getMapper(BlogMapper.class);05 List<Integer> ids = newArrayList<Integer>();06 ids.add(1);07 ids.add(3);08 ids.add(6);09 List<Blog> blogs = blogMapper.dynamicForeachTest(ids);10 for(Blog blog : blogs)11 System.out.println(blog);12 session.close();13}2.单参数array数组的类型:1<selectid="dynamicForeach2Test"resultType="Blog">2 select * from t_blog where id in3 <foreachcollection="array"index="index"item="item"open="("separ ator=","close=")">4 #{item}5 </foreach>6</select>上述collection为array,对应的Mapper代码:1publicList<Blog> dynamicForeach2Test(int[] ids);对应的测试代码:01@Test02publicvoiddynamicForeach2Test() {03 SqlSession session = Util.getSqlSessionFactory().openSession();04 BlogMapperblogMapper = session.getMapper(BlogMapper.class);05 int[] ids = newint[] {1,3,6,9};06 List<Blog> blogs = blogMapper.dynamicForeach2Test(ids);07 for(Blog blog : blogs)08 System.out.println(blog);09 session.close();10}3.自己把参数封装成Map的类型1<selectid="dynamicForeach3Test"resultType="Blog">2 select * from t_blog where title like "%"#{title}"%" and id in3 <foreachcollection="ids"index="index"item="item"open="("separat or=","close=")">4 #{item}5 </foreach>67</select>上述collection的值为ids,是传入的参数Map的key,对应的Mapper代码:1publicList<Blog> dynamicForeach3Test(Map<String, Object>params);对应测试代码:01@Test02publicvoiddynamicForeach3Test() {03 SqlSession session = Util.getSqlSessionFactory().openSession();04 BlogMapperblogMapper = session.getMapper(BlogMapper.class);05 finalList<Integer> ids = newArrayList<Integer>();06 ids.add(1);07 ids.add(2);08 ids.add(3);09 ids.add(6);10 ids.add(7);11 ids.add(9);12 Map<String, Object>params = newHashMap<String, Object>();13 params.put("ids", ids);14 params.put("title", "中国");15 List<Blog> blogs = blogMapper.dynamicForeach3Test(params);16 for(Blog blog : blogs)17 System.out.println(blog);18 session.close();19}。