Mybatis/ibatis基础知识

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

1、#和$符号的区别

  • #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by "111", 如果传入的值是id,则解析成的sql为order by "id".
  • $将传入的数据直接显示生成在sql中。如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id, 如果传入的值是id,则解析成的sql为order by id.
  •  #方式能够很大程度防止sql注入
  • $方式无法防止Sql注入。
  • $方式一般用于传入数据库对象,例如传入表名.

    例如:

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

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

  • 一般能用#的就别用$.

2、ibatis何时使用CDATA?


  在xml元素中,"<"和"&"是非法的,"<"会产生错误,因为解析器会把该字符解释为新元素的开始,"&"也会产生错误,因为解析器会把该字符解释为字符实体的开始。

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

3、在ibatis中,批量插入,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、ibatis,批量插入时,当插入数据量太大时,会报 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();

}

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

 

原文地址:https://www.cnblogs.com/amunamuna/p/8664338.html