Mybatis与Oracle个人使用总结

一、Oracle不支持反单引号

平时都习惯性的使用MySQL习惯行的加上了“`”这个符号,结果提示报错

二、Maven仓库没Oracle的jar包

由于涉及到版权问题,Maven仓库没Oracle的jar包,有也是比较老的版本,不正确引入打包后运行会报错。
在pom.xml加入如下代码即可,具体路径修改为自己jar包所在位置。
以Springboot项目为例

<dependency>
   <groupId>oracle</groupId>
   <artifactId>ojdbc6</artifactId>
   <version>11.2.0</version>
   <scope>system</scope>
   <systemPath>${project.basedir}/src/main/resources/lib/ojdbc6.jar</systemPath>
</dependency>

另外一定还要在build标签中加入如下代码,否则会引入失败

<plugin>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-maven-plugin</artifactId>
   <!-- 将本地jar包引入 -->
   <configuration>
     <includeSystemScope>true</includeSystemScope>
   </configuration>
</plugin>

三、Oracle的批量插入

象MySQL批量插入可以写成
INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....), (值1, 值2,....), (值1, 值2,....)
而Oracle这样写会报错的,改为如下格式即可,size大于500会失败
单表批量插入:

INSERT ALL
  INTO table (column1, column2, column_n) VALUES (expr1, expr2, expr_n)
  INTO table (column1, column2, column_n) VALUES (expr1, expr2, expr_n)
  INTO table (column1, column2, column_n) VALUES (expr1, expr2, expr_n)
SELECT * FROM dual;

多表批量插入:

INSERT ALL
  INTO table (column1, column2) VALUES (expr1, expr2)
  INTO table (column1, column2) VALUES (expr1, expr2)
  INTO table (column1, column2,column_n) VALUES (expr1, expr2, expr_n)
SELECT * FROM dual;

在与Mybatis使用中,我在网上还查到了两种方法供参考

(1)第一种方式:利用标签,将入参的list集合通过UNION ALL生成虚拟数据,从而实现批量插入

<insert id="insertBatchLaTContactRecord" parameterType="java.util.Map">
 <selectKey resultType="java.lang.Long" keyProperty="dto.id" order="BEFORE">
    select seq_LA_T_CONTACT_RECORD.nextval as id from dual
 </selectKey>
   insert into la_t_contact_record
   (   
     id        ,
     contract_id     ,
     contacter_add_name    ,
     contacter_add_type    ,
     contact_add_phone    ,
     contact_add_home_address  ,
     contact_add_work    ,
     contact_add_work_address  ,
     create_by      ,
     create_time     ,
     modify_by      ,
     modify_time     ,
     validate_state     ,
     sys_source      ,
     isquery        
   )
  select seq_LA_T_CONTACT_RECORD.NEXTVAL,A.* from( 
 <foreach collection="list" item="dto" index="index" separator="UNION ALL">
  select 
     #{dto.contractId,jdbcType=VARCHAR}
     ,#{dto.contacterAddName,jdbcType=VARCHAR}
     ,#{dto.contacterAddType,jdbcType=VARCHAR}
     ,#{dto.contactAddPhone,jdbcType=VARCHAR}
     ,#{dto.contactAddHomeAddress,jdbcType=VARCHAR}
     ,#{dto.contactAddWork,jdbcType=VARCHAR}
     ,#{dto.contactAddWorkAddress,jdbcType=VARCHAR}
     ,#{dto.createBy,jdbcType=DECIMAL}
     ,systimestamp
     ,#{dto.modifyBy,jdbcType=DECIMAL}
     ,#{dto.modifyTime,jdbcType=TIMESTAMP}
     ,'1'
     ,#{dto.sysSource,jdbcType=VARCHAR}
     ,#{dto.isquery,jdbcType=VARCHAR}
  from dual
 </foreach>) A
</insert>

注意:入参必须是list集合,sql语句中没有values;

(2)第二种方式:利用存储过程实现批量插入

<insert id="insertPlanRepaymentOtherfeeBatch" parameterType="java.util.List">
  begin
  <foreach collection="list" item="item" index="index">
   insert into lb_t_plan_repayment_otherfee
   (
   id        ,
   key       ,
   value       ,
   term       ,
   contract_id,
   PAY_ORDER,
   FEE_NAME,
   INTO_ID
   )
   values(SEQ_LB_T_PLAN_REPAY_OTHERFEE.nextval
   ,#{item.key,jdbcType=VARCHAR}
   ,#{item.value,jdbcType=VARCHAR}
   ,#{item.term,jdbcType=DECIMAL}
   ,#{item.contractId,jdbcType=VARCHAR}
   ,#{item.payOrder,jdbcType=DECIMAL}
   ,#{item.feeName,jdbcType=VARCHAR}
   ,#{item.intoId,jdbcType=VARCHAR}
   );
  </foreach>
  end;
 </insert>

注意:入参仍然是list集合,sql中有values,本质是利用存储过程实现批量插入;

四、Mybatis中动态查询字段

我之前写的是
SELECT #{id} FROM table
结果发现有的地方会莫名其妙报错,后来仔细检查才发现,#{id}这种写法是Preparestament实现的会自动转义成字符串,所以在查字段这里需要使用如下写法
SELECT ${id} FROM table
${id}是由Statement实现,这里没转义所以没问题
所以在查询字段类需要使用${id} ,而在where条件后为防止SQL注入须使用#{id}这种写法

五、Oracle 在查询使用in时参数大于1000个时会报错

在使用in查询时
select * from table where id in(expr1, expr2, ......)
在这里的入参大于1000个时会报错,解决办法可以使用or进行连接,例如:
select * from table where id in(expr1, expr2, ......) or id in(expr1, expr2, ......)

六、Mybatis返回Map时,查询结果为空的字段不返回

(1)查询sql添加每个字段的判断空
mysql可以使用
IFNULL(column,'') as column
oracle则为
nvl(column, '代替字段或者值')
(2)ResultType利用实体返回,不用map
(3)Springboot项目可以在Application.properties配置文件中加入
mybatis.configuration.call-setters-on-nulls=true
或者在config文件中加

@Bean(name = "baseSqlSessionFactory")
@Primary
public SqlSessionFactory setSqlSessionFactory(@Qualifier("baseDataSource") DataSource dataSource) throws Exception {
    SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
    bean.setDataSource(dataSource);
    Interceptor[] plugins =  new Interceptor[]{pageHelper()};
    bean.setPlugins(plugins);
    //------------------------------------------------加入的代码开始------------------------------------------------
    org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
    configuration.setCallSettersOnNulls(true);
           bean.setConfiguration(configuration);
    //------------------------------------------------加入的代码结束------------------------------------------------
    bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/base/*.xml"));
    return bean.getObject();
}

SSM项目在mybatis配置文件中加入
<setting name="callSettersOnNulls" value="true"/>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值