iBATIS中替换“IN”的⽅法
IN的危害
1. 由于in不⽀持变量绑定。所以,in语句必须使⽤“$变量$”来描述,为sql注⼊埋下了隐患。
2. 同样,sql语句解析和执⾏计划不能复⽤。
3. 由于执⾏计划不能复⽤,当发⽣很多次IN不同内容调⽤的时候,会把以前的经常复⽤的sql语句的执⾏计划cache给挤出去。如何消灭IN
1. 把in变成参数。
2. 固定参数的长度。
步骤
1. 创建函数 和  效果如下:
select * from SplitInt(1,2,3,4,5,6);
select * from SplitStr('a,b,c,d,e,6');
---------------------
:
CREATE FUNCTION [dbo].[SplitInt]
(
@SplitString varchar(8000)
)
RETURNS @SplitIntTable TABLE
(
[value] int
)
AS
BEGIN
DECLARE @Separator varchar(2);
sql语句替换表中内容
DECLARE @CurrentIndex int;
DECLARE @NextIndex int;
DECLARE @ReturnText int;
SELECT @CurrentIndex=1;
SELECT @Separator = ',';
WHILE(@CurrentIndex<=len(@SplitString))
BEGIN
SELECT @NextIndex=charindex(@Separator,@SplitString,@CurrentIndex);
IF(@NextIndex=0 OR @NextIndex IS NULL)
SELECT @NextIndex=len(@SplitString)+1;
SELECT @ReturnText=cast(substring(@SplitString,@CurrentIndex,@NextIndex-@CurrentIndex) as int);
INSERT INTO @SplitIntTable([value])
VALUES(@ReturnText);
SELECT @CurrentIndex=@NextIndex+1;
END
RETURN;
END
--------------------------------
:
CREATE  FUNCTION [dbo].[SplitStr]
CREATE  FUNCTION [dbo].[SplitStr]
(
@SplitString varchar(8000)
)
RETURNS @SplitStringsTable TABLE
(
[value] varchar(8000)
)
AS
BEGIN
DECLARE @Separator varchar(2);
DECLARE @CurrentIndex int;
DECLARE @NextIndex int;
DECLARE @ReturnText varchar(8000);-- nvarchar(4000)
SELECT @CurrentIndex=1;
SELECT @Separator = ',';
WHILE(@CurrentIndex<=len(@SplitString))
BEGIN
SELECT @NextIndex=charindex(@Separator,@SplitString,@CurrentIndex);
IF(@NextIndex=0 OR @NextIndex IS NULL)
SELECT @NextIndex=len(@SplitString)+1;
SELECT @ReturnText=substring(@SplitString,@CurrentIndex,@NextIndex-@CurrentIndex);
INSERT INTO @SplitStringsTable([value])
VALUES(@ReturnText);
SELECT @CurrentIndex=@NextIndex+1;
END
RETURN;
END
-----------------------------
2. 组织sql
⽼格式:
select t2.* from  lily_project T2 where t2.projectname in ('亚洲⼀号','测试')
新格式:
select t2.* from SplitStr('亚洲⼀号,测试') T1 , lily_project T2
where t1.value = t2.projectname
⽼格式:
select t2.* from  lily_project T2 where  t2.project_id in (67,2,3)
新格式:
select t2.* from SplitInt('67,2,3') T1 , lily_project T2
where t1.value = t2.project_id
3. 配置定长参数,由于Sql Server对于不同的参数长度,会产⽣不过的执⾏路径的KEY。所以,必须要统⼀参数长度。这个长度可以指
定为1,输⼊值超过1,不受影响。ibatis的inlineParameter⽆法设置参数长度,必须依靠ParameterMap来设置。所以,最终效果如下:
<parameterMap id="testjoin" class="string">
<parameter property="value" dbtype="varchar" size="1"/>
</parameterMap>
<select id="testJoinIn" parameterMap="testjoin" resultClass="project">
select t2.* from SplitInt(?) T1 , lily_project T2 where t1.value = t2.project_id
</select>
效果
经过测试,使⽤上⾯的语句能提⾼20%的效率。另外,单个语句执⾏⽆提⾼效果。
其它
受到启发,其它所有调⽤的时候。如果参数中有字符串的时候,⼀定要使⽤parameterMap形式,并且定义paramter的size

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。