ibatis

Posted nannan0226

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ibatis相关的知识,希望对你有一定的参考价值。

Tip:mapper.xml中sql语句不允许出现分号!

1、ibatis中#和$符号的区别

  $中间的变量就是直接替换成值的。

   #会根据变量的类型来进行替换。

  使用场景:

  (1)对于变量部分, 应当使用#, 这样可以有效的防止sql注入,具体执行时,# 都是用到了prepareStement,这样对效率也有一定的提升

            #方式一般用于传入插入/更新的值或查询/删除的where条件

  (2) $只是简单的字符拼接而已,对于非变量部分, 那只能使用$, 实际上, 在很多场合,$也是有很多实际意义的

             $方式一般用于传入数据库对象.例如传入表名.

             例如:

             select  *  from  $tableName$  对于不同的表执行统一的查询

             update  $tableName$  set  name = #name#  每个实体一张表,改变不用实体的状态

             特别说明, $只是字符串拼接,所以要特别小心sql注入问题。

  (3)能同时用#和$的时候,最好用#

2、ibatis何时使用CDATA?
  在xml元素中,"<"和"&"是非法的,"<"会产生错误,因为解析器会把该字符解释为新元素的开始."&"也会产生错误,因为解析器会把该字符解释为字符实体的开始。

所以这时候会用"<![CDATA[    ]]>" 括起来。

3、批量插入,iterate标签。其中 COMPUTE_MSEL 是FUNCTION

    <insert id="batchInsert" parameterClass="java.util.List">
        insert all
        <iterate conjunction=" ">
            into MONITOR_T_STA_TRACEDAILY
            (TXNTRACENUMBER,
            TXNCODE,
            TXNREQUESTCHANNELID,
            TXNBOCBANKREQUESTTIME,
            TXNBOCBANKREQUESTDATE,
            TXNBOCBANKRESPONSETIME,
            TXNBOCBANKRESPONSEDATE,
            TXNRETURNCODE,
            TXNRETURNMESSAGE,
            RESPONSESECONDS,
            CREATETIME)
            values    
        <![CDATA[    
           (#recordList[].txntracenumber#,
            #recordList[].txncode#,
            #recordList[].txnrequestchannelid#,
            #recordList[].txnbocbankrequesttime#, 
            #recordList[].txnbocbankrequestdate#,
            #recordList[].txnbocbankresponsetime#,
            #recordList[].txnbocbankresponsedate#,
            #recordList[].txnreturncode#,
            #recordList[].txnreturnmessage#,
            COMPUTE_MSEL(
                #recordList[].txnbocbankrequestdate#,
                #recordList[].txnbocbankrequesttime#,
                #recordList[].txnbocbankresponsedate#,
                #recordList[].txnbocbankresponsetime#),
            sysdate)
        ]]>
        </iterate>
        select * from dual
    </insert>

 

4、批量插入时,当插入数据量太大时,会报 Cause: java.sql.SQLException: ORA-01745: 无效的主机/绑定变量名

这时候采用,分批插入的方式,如下:

public Long insertBatch(List<StaTraceDaily> list){
        //每批次插入数量
        int batchCount = 1000;
        //游标
        int index = 0;
        //批次
        int batchNum = 1;
        try {
        for(;;){
            if(index+batchCount>=list.size()){
                //一次可全部插入
                    batchInsert(list.subList(index,list.size()));
                System.out.println("第"+batchNum+"批:插入"+(list.size()-index)+"条");
                break;
            }else {
                //需要多次插入
                List<StaTraceDaily> staTraceDailyList = list.subList(index, index + batchCount);
                batchInsert(staTraceDailyList);
                index = index+batchCount;
                System.out.println("第"+batchNum+"批:插入"+batchCount+"条");
            }
            batchNum++;
        }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("over~,总共插入"+list.size()+"条,插入了"+batchNum+"批");
        return null;
    }

 

 

5、事务
Tip:
事务不能嵌套。在调用 commit()或 rollback()之前,从同一线程多次调用.startTransaction,将引起抛出异常。
对于每个 SqlMap 实例,每个线程最多只能打开一个事务。

例:

UserDao.insertUser (user); // Starts transaction

user.setName("wh");

UserDao.updateUser (user); // Starts a new transaction

 

因为没有显式地启动事务,iBatis会认为这是两次事务,分别从连接池中取两次Connection。

 

try {

daoManager.startTransaction();

UserDao.insertUser (user);

user.setName("wh");

UserDao.updateUser(user);

otherDao.doSomething(other);

...

daoManager.commitTransaction();

} finally {

daoManager.endTransaction();

}

 

这样就保持了原子性,整体为一个事务,要么全部执行成功,否则回滚。

 

 

 

以上是关于ibatis的主要内容,如果未能解决你的问题,请参考以下文章

Ibatis组合键关联查询

NoClassDefFoundError: com/ibatis/sqlmap/engine/transaction/external/ExternalTransactionConfig处理(示例代码

iBatis框架基本使用

ibatis 怎么返回oracle游标

Mybatis笔记三:iBatis与MyBatis区别

IBATIS