错误一

错误提示

org.apache.ibatis.exceptions.PersistenceException: 
### Error updating database.  Cause: java.sql.SQLSyntaxErrorException: ORA-00911: 无效字符

### The error may exist in mapper/UserMapper.xml
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: insert into t_user(name,age) values(?,?);
### Cause: java.sql.SQLSyntaxErrorException: ORA-00911: 无效字符

mapper配置信息

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xy.mybatis.mapper.UserMapper">
    
    <insert id="insertUser">
        insert into t_user(name, age)
        values (#{name}, #{age});
    </insert>
</mapper>

错误原因

Mybatis连接Oracle数据库其sql语句不能添加分号(;)

修改配置

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xy.mybatis.mapper.UserMapper">

    <insert id="insertUser">
        insert into t_user(name, age)
        values (#{name}, #{age})
    </insert>
</mapper>

错误二

错误提示

org.apache.ibatis.exceptions.PersistenceException: 
### Error updating database.  Cause: java.sql.SQLSyntaxErrorException: ORA-00984: 列在此处不允许

### The error may exist in mapper/UserMapper.xml
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: insert into t_user(name, age)         values (smith, 28)
### Cause: java.sql.SQLSyntaxErrorException: ORA-00984: 列在此处不允许

mapper配置信息

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xy.mybatis.mapper.UserMapper">
    
    <insert id="insertUser">
        insert into t_user(name, age)
        values (${name}, ${age})
    </insert>
</mapper>

错误原因

错误的使用了#和$导致sql语句出错

'#'占位符的特点

  1. MyBatis处理 #{ } 占位符,使用的 JDBC 对象是PreparedStatement 对象,执行sql语句的效率更高。
  2. 使用PreparedStatement 对象,能够避免 sql 注入,使得sql语句的执行更加安全。
  3. { } 常常作为列值使用,位于sql语句中等号的右侧;#{ } 位置的值与数据类型是相关的。

'$'占位符的特点

  1. MyBatis处理 ${ } 占位符,使用的 JDBC 对象是 Statement 对象,执行sql语句的效率相对于 #{ } 占位符要更低。
  2. ${ } 占位符的值,使用的是字符串连接的方式,有 sql 注入的风险,同时也存在代码安全的问题。
  3. ${ } 占位符中的数据是原模原样的,不会区分数据类型。
  4. { } 占位符常用作表名或列名,这里推荐在能保证数据安全的情况下使用 ​{ }。

修改配置为

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xy.mybatis.mapper.UserMapper">

    <insert id="insertUser">
        insert into t_user(name, age)
        values (#{name}, #{age})
    </insert>
</mapper>

其他注意事项

  • Mapper接口如果返回的是List如List,即便是sql语句本身返回是空集合,接口的返回结果的集合size均为1,且唯一的值为泛型类型的默认值。
  • oracle+ibatis若返回值类型为Map,且查询字段有别名,若想通过别名get到对应的value值,sql语句在定义别名时需将别名用双引号包裹起来,因为oracle在返回时将全部字段转为大写了,或者在get的时候用大写的字段作为key值。