动态SQL

if、choose(when,otherwise)、trim(where,set)、foreach

if标签:

<!--public List<StudentBean> getStudentsForIf(StudentBean student);-->

<select id="getStudentsForIf" resultType="com.learncmzy.pojo.StudentBean">
		select * from t_student where 1=1
		<!-- test中使用的是OGNL表达式,从参数中取的值 -->
		<if test="id != null and id != ''">
			and id=#{id}
		</if>
		<if test="cnname != null and cnname.trim() != ''">
			and cnname=#{cnname}
		</if>
		<if test="sex != null and sex!= ''">
			and sex=#{sex}
		</if>
	</select>

where标签:
使用上述方式是手动在where 后面添加1=1条件,免得如果第一个参数不存在,sql语法错误。还可以使用where标签,同时使用where 标签它只能去除and在条件前面的,不能在后面的,如下形式:

<select id="getStudentsForIf" resultType="com.learncmzy.pojo.StudentBean">
		select * from t_student 
		<where>
		<!-- test中使用的是OGNL表达式,从参数中取的值 -->
		<if test="id != null and id != ''">
			id=#{id}
		</if>
		<if test="cnname != null and cnname.trim() != ''">
			and cnname=#{cnname}
		</if>
		<if test="sex != null and sex!= ''">
			and sex=#{sex}
		</if>
		</where>
	</select>


<!--下面这种方式是可能会引起sql语法错误的,where标签无法可能无法去除多余的and-->
<select id="getStudentsForIf" resultType="com.learncmzy.pojo.StudentBean">
		select * from t_student 
		<where>
		<!-- test中使用的是OGNL表达式,从参数中取的值 -->
		<if test="id != null and id != ''">
			id=#{id} and
		</if>
		<if test="cnname != null and cnname.trim() != ''">
			cnname=#{cnname} and
		</if>
		<if test="sex != null and sex!= ''">
			 sex=#{sex}
		</if>
		</where>
	</select>

trim标签:
prefix:前缀,trim标签体中整个字符串拼接完后,给拼接完后的字符串添加一个前缀
prefixOverrides:前缀覆盖,去掉整个字符串前面多余指定的字符串
suffix:给拼接完后的整个字符换添加一个后缀
suffixOverrides:后缀覆盖,去掉整个字符串后面多余的指定字符串

<select id="getStudentsForTrim" resultType="com.learncmzy.pojo.StudentBean">
		select * from t_student 
		<trim prefix="where"  suffixOverrides="and">
			<!-- test中使用的是OGNL表达式,从参数中取的值 -->
			<if test="id != null and id != ''">
				id=#{id} and
			</if>
			<if test="cnname != null and cnname.trim() != ''">
				cnname=#{cnname} and
			</if>
			<if test="sex != null and sex!= ''">
				sex=#{sex}
			</if>
		</trim>
	</select>

choose标签:分支选择

<select id="getStudentsForChoose" resultType="com.learncmzy.pojo.StudentBean">
		select * from t_student 
		<where>
			<choose>
				<when test="id != null and id != ''">
					where id=#{id}
				</when>
				<when test="cnname != null and cnname.trim() != ''">
					where cnname=#{cnname}
				</when>
				<otherwise>
					1=1
				</otherwise>
			</choose>
		</where>
	</select>

set标签:用于更新操作sql,可以自动处理set标签中的sql语句,将多余的逗号自动清理,当然也可以用trim标签实现同样的功能。

<update id="updateStudent">
		update t_student 
		<set>
			<if test="cnname != null and cnname.trim() != ''">
				cnname=#{cnname},
			</if>
			<if test="note != null and note != ''">
				note=#{note}
			</if>
		</set>
		
		<where>
			id=#{id}
		</where>
	</update>

foreach标签:
collection :传递一个 List 实例或者数组作为参数对象传给 MyBatis。当你这么做的时 候,MyBatis 会自动将它包装在一个 Map 中,用名称在作为键。List 实例将会以“list” 作为键,而数组实例将会以“array”作为键。
item:将遍历出的元素赋值给指定的变量,使用#{变量名}就能取出变量的值,也就是当前遍历出的元素。
separator:每个元素之间的分隔符
open:遍历出所有结果拼接一个开始的字符
close:遍历出所有结果拼接一个结束的字符
index:索引,遍历list的时候index就是索引,item就是当前值
遍历map的时候index表示的就是map的key,item就是map的值

public List<StudentBean> getStudentsForForeach(List<Integer> ids);

<select id="getStudentsForForeach" resultType="com.learncmzy.pojo.StudentBean">
		select * from t_student where id in
             //注意因为是List类型,所以collection中的值是mybatis自动封装了的,就是list,index中的值也是封装的,就是index
		<foreach collection="list" item="item_id" separator="," open="(" close=")" index="index">
			#{item_id}
		</foreach>
	</select>

使用foreach批量保存:

<insert id="addStudents">
		insert into t_student(cnname,sex,note,class_info) values
             //这里separator设置用于区分多条()之间的逗号。
		<foreach collection="list" item="student" separator=",">
			(#{student.cnname},#{student.sex},#{student.note},#{student.classInfo.id})	
		</foreach> 
	</insert>

上面的语句在执行的时候实际上是转换成下面的sql,mysql支持插入多条的语法:

insert into t_student(cnname,sex,note,class_info) values (?,?,?,?) , (?,?,?,?)
Preparing: insert into t_student(cnname,sex,note,class_info) values (?,?,?,?) , (?,?,?,?) 
==> Parameters: name1(String), FMALE(String), aaaaa(String), 1(Integer), name2(String), FMALE(String), bbbbb(String), 1(Integer)

mysql批量保存还有下面这种形式:这种方式需要数据库连接属性allowMultiQueries设置为true,以支持同时执行多条sql语句。分号分隔也可以用于批量更新,删除。

<insert id="addStudents">
	<foreach collection="list" item="student" separator=";">
		insert into t_student(cnname,sex,note,class_info) values
			(#{student.cnname},#{student.sex},#{student.note},#{student.classInfo.id})	
	</foreach> 
</insert>

oralce的批量插入方式:

begin
    insert into tableName() values();
    insert into tableName() values();
    insert into tableName() values();
end;


<insert id="addStudentsOracle" databaseId="oralce">
		begin
		<foreach collection="list" item="item" >
			insert into t_student(cnname,sex,note,class_info) values(#{student.cnname},#{student.sex},#{student.note},#{student.classInfo.id});
		</foreach>
		end;
	</insert>


oracle可以利用中间表批量插入

两个内置参数:
不只是方法传递过来的参数可以被用来判断,取值等,mybatis默认还有两个内置参数
_parameter:代表整个参数
单个参数:_parameter就是这个参数
多个参数:参数会被封装为一个map,_parameter就是代表这个map
_databaseId:如果全局配置中配置了databaseIdProvider标签。_databaseId就是代表当前数据库的别名。

使用_databaseId来判断数据库,从而执行相应数据库sql语句,在没有使用_databaseId的情况下,通常需要写两个方法,在映射sql语句中配置databaseId指明该映射sql使用哪种数据库,当使用_databaseId可以直接用于判断。

<select id="getStudentsForForeach" resultType="com.learncmzy.pojo.StudentBean">
		<if test="_databaseId == mysql">
			select * from t_student
		</if>
		<if test="_databaseId == oralce">
			select * from students
		</if>
	</select>

由于_parameter默认是代表参数,所以可以根据这个来判断参数的情况,从而执行相应的查询如下:

	<select id="getStudentsForForeach" resultType="com.learncmzy.pojo.StudentBean">
		<if test="_databaseId == mysql">
			select * from t_student 
			<if test="_parameter != null">
				where cnname=#{cnname}
			</if>
		</if>
		<if test="_databaseId=oralce">
			select * from students
			<if test="_parameter != null">
				where cnname=#{cnname}
			</if>
		</if>
	</select>

bind标签:可以讲OGNL表达式的值绑定到一个变量中,方便后面引用这个变量的值,如使用like查询的时候,需要在查询条件加%,可以如下使用:

	<select id="getStudentsForBind" resultType="com.learncmzy.pojo.StudentBean">
		<bind name="_cnname" value="'%'+cnname+'%'"/>
		select * from t_student where cnname like #{_cnname}
	</select>

sql标签:抽取可重用的sql,方便后面引用,同时在sql标签中使用判断语句,引用_parameter和_databaseId默认参数。
sql抽取,经将要查询的列明,或者插入用的列明抽取出来方便应用
通过include标签引用,iinclude还可以自定义一些property,sql标签内部就能使用自定义的属性,在sql标签内部就可以使用${prop},prop就是include标签中property的name值,#{}这种方式是不能在sql标签中使用的,sql标签中是不能预编译的。
如下所示

	<sql id="sqlTest">
		<if test="_parameter != null">
			cnname,sex,note,class_info,${prop}
		</if>
	</sql>
	
	<insert id="addStudents">
		insert into t_student(
			<include refid="sqlTest">
				<property name="prop" value="addColName"/>
			</include>
		) values
		<foreach collection="list" item="student" separator=",">
			(#{student.cnname},#{student.sex},#{student.note},#{student.classInfo.id})	
		</foreach> 
	</insert>

内容概要:本文档定义了一个名为 `xxx_SCustSuplier_info` 的视图,用于整合和展示客户(Customer)和供应商(Supplier)的相关信息。视图通过连接多个表来获取组织单位、客户账户、站点使用、位置、财务代码组合等数据。对于客户部分,视图选择了与账单相关的记录,并提取了账单客户ID、账单站点ID、客户名称、账户名称、站点代码、状态、付款条款等信息;对于供应商部分,视图选择了有效的供应商及其站点信息,包括供应商ID、供应商名称、供应商编号、状态、付款条款、财务代码组合等。视图还通过外连接确保即使某些字段为空也能显示相关信息。 适合人群:熟悉Oracle ERP系统,尤其是应付账款(AP)和应收账款(AR)模块的数据库管理员或开发人员;需要查询和管理客户及供应商信息的业务分析师。 使用场景及目标:① 数据库管理员可以通过此视图快速查询客户和供应商的基本信息,包括账单信息、财务代码组合等;② 开发人员可以利用此视图进行报表开发或数据迁移;③ 业务分析师可以使用此视图进行数据分析,如信用评估、付款周期分析等。 阅读建议:由于该视图涉及多个表的复杂连接,建议读者先熟悉各个表的结构和关系,特别是 `hz_parties`、`hz_cust_accounts`、`ap_suppliers` 等核心表。此外,注意视图中使用的外连接(如 `gl_code_combinations_kfv` 表的连接),这可能会影响查询结果的完整性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值