(1) 输入参数为单个值
<delete id="com.fashionfree.stat.accesslog.deleteMemberAccessLogsBefore" parameterClass="long"> delete from MemberAccessLog where accessTimestamp = #value# </delete>
(2) 输入参数为一个对象
<insert id="com.fashionfree.stat.accesslog.MemberAccessLog.insert" parameterClass="com.fashionfree.stat.accesslog.model.MemberAccessLog> insert into MemberAccessLog ( accessLogId, memberId, clientIP, httpMethod, actionId, requestURL, accessTimestamp, extend1, extend2, extend3 ) values ( #accessLogId#, #memberId#, #clientIP#, #httpMethod#, #actionId#, #requestURL#, #accessTimestamp#, #extend1#, #extend2#, #extend3# ) </insert>
(3) 输入参数为一个java.util.HashMap
<select id="com.fashionfree.stat.accesslog.selectActionIdAndActionNumber" parameterClass="hashMap" resultMap="getActionIdAndActionNumber"> select actionId, count(*) as count from MemberAccessLog where memberId = #memberId# and accessTimestamp > #start# and accessTimestamp <= #end# group by actionId </select>
(4) 输入参数中含有数组
<insert id="updateStatusBatch" parameterClass="hashMap"> update Question set status = #status# <dynamic prepend="where questionId in"> <isNotNull property="actionIds"> <iterate property="actionIds" open="(" close=")" conjunction=","> #actionIds[]# </iterate> </isNotNull> </dynamic> </insert>
说明:actionIds为传入的数组的名字;
使用dynamic标签避免数组为空时导致sql语句语法出错;
使用isNotNull标签避免数组为null时ibatis解析出错
(5)传递参数只含有一个数组
<select id="com.fashionfree.stat.accesslog.model.StatMemberAction.selectActionIdsOfModule" resultClass="hashMap"> select moduleId, actionId from StatMemberAction <dynamic prepend="where moduleId in"> <iterate open="(" close=")" conjunction=","> #[]# </iterate> </dynamic> order by moduleId </select>
说明:注意select的标签中没有parameterClass一项
另:这里也可以把数组放进一个hashMap中,但增加额外开销,不建议使用
(6)让ibatis把参数直接解析成字符串
<select id="com.fashionfree.stat.accesslog.selectSumDistinctCountOfAccessMemberNum" parameterClass="hashMap" resultClass="int"> select count(distinct memberId) from MemberAccessLog where accessTimestamp >= #start# and accessTimestamp < #end# and actionId in $actionIdString$ </select>
说明:使用这种方法存在sql注入的风险,不推荐使用
(7)分页查询 (pagedQuery)
<select id="com.fashionfree.stat.accesslog.selectMemberAccessLogBy" parameterClass="hashMap" resultMap="MemberAccessLogMap"> <include refid="selectAllSql"/> <include refid="whereSql"/> <include refid="pageSql"/> </select> <select id="com.fashionfree.stat.accesslog.selectMemberAccessLogBy.Count" parameterClass="hashMap" resultClass="int"> <include refid="countSql"/> <include refid="whereSql"/> </select> <sql id="selectAllSql"> select accessLogId, memberId, clientIP, httpMethod, actionId, requestURL, accessTimestamp, extend1, extend2, extend3 from MemberAccessLog </sql> <sql id="whereSql"> accessTimestamp <= #accessTimestamp# </sql> <sql id="countSql"> select count(*) from MemberAccessLog </sql> <sql id="pageSql"> <dynamic> <isNotNull property="startIndex"> <isNotNull property="pageSize"> limit #startIndex# , #pageSize# </isNotNull> </isNotNull> </dynamic> </sql>
说明:本例中,代码应为:
HashMap hashMap = new HashMap();
hashMap.put(“accessTimestamp”, someValue);
pagedQuery(“com.fashionfree.stat.accesslog.selectMemberAccessLogBy”, hashMap);
pagedQuery 方法首先去查找名为com.fashionfree.stat.accesslog.selectMemberAccessLogBy.Count 的mapped statement来进行sql查询,从而得到 com.fashionfree.stat.accesslog.selectMemberAccessLogBy查询的记录个数,
再进行所需的paged sql查询(com.fashionfree.stat.accesslog.selectMemberAccessLogBy),具体过程参见utils类中的相关代码
(8)sql语句中含有大于号>、小于号<
1. 将大于号、小于号写为: > < 如:
<delete id="com.fashionfree.stat.accesslog.deleteMemberAccessLogsBefore" parameterClass="long"> delete from MemberAccessLog where accessTimestamp <= #value# </delete>
2. 将特殊字符放在xml的CDATA区内:
<delete id="com.fashionfree.stat.accesslog.deleteMemberAccessLogsBefore" parameterClass="long"> <![CDATA[ delete from MemberAccessLog where accessTimestamp <= #value# ]]> </delete>
推荐使用第一种方式,写为< 和 > (XML不对CDATA里的内容进行解析,因此如果CDATA中含有dynamic标签,将不起作用)
(9)include和sql标签
将常用的sql语句整理在一起,便于共用:
<sql id="selectBasicSql"> select samplingTimestamp,onlineNum,year, month,week,day,hour from OnlineMemberNum </sql> <sql id="whereSqlBefore"> where samplingTimestamp <= #samplingTimestamp# </sql> <select id="com.fashionfree.accesslog.selectOnlineMemberNumsBeforeSamplingTimestamp" parameterClass="hashmap" resultClass="OnlineMemberNum"> <include refid="selectBasicSql" /> <include refid="whereSqlBefore" /> </select>
注意:sql标签只能用于被引用,不能当作mapped statement。如上例中有名为selectBasicSql的sql元素,试图使用其作为sql语句执行是错误的:
sqlMapClient.queryForList(“selectBasicSql”); ×
(10)随机选取记录
<sql id=”randomSql”> ORDER BY rand() LIMIT #number# </sql>
从数据库中随机选取number条记录(只适用于MySQL)
(11)将SQL GROUP BY分组中的字段拼接
<sql id=”selectGroupBy> SELECT a.answererCategoryId, a.answererId, a.answererName, a.questionCategoryId, a.score, a.answeredNum, a.correctNum, a.answerSeconds, a.createdTimestamp, a.lastQuestionApprovedTimestamp, a.lastModified, GROUP_CONCAT(q.categoryName) as categoryName FROM AnswererCategory a, QuestionCategory q WHERE a.questionCategoryId = q.questionCategoryId GROUP BY a.answererId ORDER BY a.answererCategoryId </sql>
注:SQL中使用了MySQL的GROUP_CONCAT函数
(12) 按照IN里面的顺序进行排序
①MySQL:
<sql id=”groupByInArea”> select moduleId, moduleName, status, lastModifierId, lastModifiedName, lastModified from StatModule where moduleId in (3, 5, 1) order by instr(',3,5,1,' , ','+ltrim(moduleId)+',') </sql>
②SQLSERVER:
<sql id=”groupByInArea”> select moduleId, moduleName, status, lastModifierId, lastModifiedName, lastModified from StatModule where moduleId in (3, 5, 1) order by charindex(','+ltrim(moduleId)+',' , ',3,5,1,') </sql>
说明:查询结果将按照moduleId在in列表中的顺序(3, 5, 1)来返回
MySQL : instr(str, substr)
SQLSERVER: charindex(substr, str)
返回字符串str 中子字符串的第一个出现位置
ltrim(str)
返回字符串str, 其引导(左面的)空格字符被删除
(13) resultMap
resultMap负责将SQL查询结果集的列值映射成Java Bean的属性值。
<resultMap class="java.util.HashMap" id="getActionIdAndActionNumber"> <result column="actionId" property="actionId" jdbcType="BIGINT" javaType="long"/> <result column="count" property="count" jdbcType="INT" javaType="int"/> </resultMap>
使用resultMap称为显式结果映射,与之对应的是resultClass(内联结果 映射),使用resultClass的最大好处便是简单、方便,不需显示指定结果,由iBATIS根据反射来确定自行决定。而resultMap则可以通 过指定jdbcType和javaType,提供更严格的配置认证。
(14) typeAlias
<typeAlias alias="MemberOnlineDuration" type="com.fashionfree.stat.accesslog.model.MemberOnlineDuration" /> <typeAlias>允许你定义别名,避免重复输入过长的名字。
(15) remap
<select id="testForRemap" parameterClass="hashMap" resultClass="hashMap" remapResults="true"> select userId <isEqual property="tag" compareValue="1"> , userName </isEqual> <isEqual property="tag" compareValue="2"> , userPassword </isEqual> from UserInfo </select>
此例中,根据参数tag值的不同,会获得不同的结果集,如果没有remapResults="true"属性,iBatis会将第一次查询时的结果集缓存,下次再执行时(必须还是该进程中)不会再执行结果集映射,而是会使用缓存的结果集。
因此,如果上面的例子中remapResult为默认的false属性,而有一段程序这样书写:
HashMap<String, Integer> hashMap = new HashMap<String, Integer>(); hashMap.put("tag", 1); sqlClient.queryForList("testForRemap", hashMap); hashMap.put("tag", 2); sqlClient.queryForList("testForRemap", hashMap);
则程序会在执行最后一句的query查询时报错,原因就是iBATIS使用了第一次查询时 的结果集,而前后两次的结果集是不同的:(userId, userName)和(userId, userPassword),所以导致出错。如果使用了remapResults="true"这一属性,iBATIS会在每次执行查询时都执行结果集映 射,从而避免错误的发生(此时会有较大的开销)。
(16) dynamic标签的prepend
dynamic标签的prepend属性作为前缀添加到结果内容前面,当标签的结果内容为空时,prepend属性将不起作用。
当dynamic标签中存在prepend属性时,将会把其嵌套子标签的第一个prepend属性忽略。例如:
<sql id="whereSql"> <dynamic prepend="where "> <isNotNull property="userId" prepend="BOGUS"> userId = #userId# </isNotNull> <isNotEmpty property="userName" prepend="and "> userName = #userName# </isNotEmpty> </dynamic> </sql>
此例中,dynamic标签中含有两个子标签<isNotNull> 和<isNotEmpty>。根据前面叙述的原则,如果<isNotNull>标签中没有prepend="BOGUS" 这一假的属性来让dynamic去掉的话,<isNotEmpty>标签中的and就会被忽略,会造成sql语法错误。
注意:当dynamic标签没有prepend属性时,不会自动忽略其子标签的第一个prepend属性。
相关推荐
在实际开发过程中,我们往往需要编写复杂的SQL语句,拼接稍有不注意就会导致错误,Mybatis给开发者提供了动态SQL,大大降低了拼接SQL导致的错误。 动态标签 if标签 if标签通常用那个胡where语句,update语句,insert...
- **DAO层**:数据访问对象,使用SqlSession与Batis框架交互,执行SQL语句。 - **Web层**:控制器或Servlet,接收请求并调用Service层,返回响应。 无需导入数据库就能运行,意味着这个项目可能使用了内存数据库如...
这个框架的主要目的是将SQL语句与Java代码分离,从而提供更加灵活和可维护的数据库访问层。以下是关于BATIS 2.0的一些关键知识点: ### 1. **SQL映射** SQL映射是iBATIS的核心概念,它定义了如何在Java代码和SQL...
Dynamic Sql是指在运行时动态构建SQL语句的能力,这种能力对于处理复杂的查询或根据不同的业务逻辑生成不同的SQL语句非常有用。ibatis框架自2.x版本起就提供了Dynamic Sql的支持,但在3.0版本中,这一功能得到了极大...
在IT领域,MyBatis是一个广泛应用的持久层框架,它允许开发者将SQL语句与Java代码相结合,提供了灵活的数据访问接口。本资源包包含了MyBatis的核心组件以及MySQL的驱动包,是学习和使用MyBatis进行数据库操作的重要...
- 创建对应的`StudentMapper.xml`文件,定义SQL语句和结果映射。在这里,你可以使用MyBatis的动态SQL功能,实现灵活的数据操作。 6. **SqlSessionFactory和SqlSession** - 使用`mybatis-config.xml`配置文件,...
在Java Web开发中,MyBatis是一个非常流行的持久层框架,它简化了数据库操作,将SQL语句与Java代码解耦。"Batis配置文件"是MyBatis框架的核心组成部分,用于定义数据源、事务管理、映射文件等关键设置。在本篇中,...
MyBatis允许开发者将SQL语句直接写在XML配置文件或注解中,与Java对象进行映射,从而实现了数据访问的便捷性。这种松耦合的设计使得SQL逻辑的编写和修改更加直观,同时也提高了代码的可读性和可维护性。在项目中,...
MyBatis是一个轻量级的持久层框架,它将SQL语句与Java代码分离,提供了动态SQL的功能。开发者可以在XML配置文件或者注解中编写SQL,MyBatis会根据这些SQL执行数据库操作,并将结果自动映射为Java对象。这种方式既...
在本示例中,Oracle10g将作为数据存储,Batis将通过JDBC接口与之交互,执行SQL语句进行数据操作。 集成步骤可能包括以下部分: 1. **环境配置**:安装JDK、Tomcat服务器、Oracle数据库,配置相关的环境变量。 2. *...
**iBatis(原Batis)** 是一个SQL映射框架,它允许开发者将SQL语句与Java代码分离,以提高代码的可维护性和可测试性。在本项目中,iBatis作为数据访问层,处理与Oracle数据库的交互。开发者可以通过XML配置文件或者...
- **SQL语句硬编码**:将SQL语句直接写在Java代码中,一旦SQL发生变化就需要重新编译代码,增加了维护成本。 - **参数设置**:在预编译SQL语句中设置参数时,参数的位置和值直接写在代码中,降低了灵活性。 - **结果...
在实际开发中,开发者通常会为每个数据表创建一个对应的`mapper.xml`文件,将SQL语句和结果映射写在这个文件中。然后在`mybatis-config.xml`中注册这些映射文件,使得MyBatis在运行时能够找到并执行相应的SQL操作。 ...
myBatis的核心思想是将SQL语句与Java代码分离,通过XML配置文件或者注解来定义SQL语句,使得数据库操作更加灵活,同时提高了代码的可读性和可维护性。myBatis的动态SQL功能非常强大,可以根据条件动态生成SQL语句,...
MyBatis则是一个轻量级的持久层框架,它允许开发者将SQL语句与Java代码直接结合,提供灵活的数据访问。而DWZ(Dynamic Web Zone)是一个基于jQuery的前端UI库,提供了丰富的组件和模板,用于快速构建用户界面。 ...
这使得iBATIS更加灵活,同时也意味着开发人员需要更直接地处理SQL语句。 ### 关键特性 iBATIS支持多种高级功能,包括但不限于: - **懒加载**:这是一种延迟加载策略,即当确实需要某个对象时才加载它。这样可以...
1. **设计理念**:Ibatis的目标是简化数据访问层的开发,将SQL语句和Java代码分离,通过XML或注解方式定义SQL语句,提供更为灵活的数据库操作。 2. **配置**:Ibatis3.0的配置文件(mybatis-config.xml)包含了数据...
Mybatis允许开发者编写SQL语句,通过XML配置文件或注解将SQL与Java代码绑定,实现了SQL的动态执行和结果映射。相比于传统的JDBC,Mybatis提供了更直观的数据库操作方式,降低了SQL注入的风险,并且提高了代码的...
Mapper接口是业务逻辑与数据访问的桥梁,通过Mapper XML文件或注解,将Java方法与SQL语句关联起来。 在MyBatis中,DAO(Data Access Object)层是数据访问层,负责与数据库交互。DAO接口定义了对数据库的操作,而...
MyBatis是Java开发中的一个持久层框架,它允许开发者将SQL语句直接写在XML配置文件或注解中,实现了SQL与代码的分离,提高了开发效率和可维护性。本教程以“炒鸡炒鸡简单”为特点,旨在帮助初学者快速理解和掌握...