重温并整理一些mybatis容易出错的问题
一、当实体类中的属性名和表中的字段名不一样
处理方式常用两种
第1种: 通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。
<!--字段不一样处理①,sql别名-->
<select id="resultMapping1" resultType="com.zhan.mybatis.entity.User">
select user_age age from user where sex = #{sex};
</select>
第2种: 通过来映射字段名和实体类属性名的一一对应的关系【手动映射】。
<!--字段不一样处理②,手动映射-->
<select id="resultMapping2" resultMap="UserMap">
select user_age, username from user where sex = #{sex};
</select>
<resultMap id="UserMap" type="com.zhan.mybatis.entity.User">
<id property="id" column="id"/>
<result property="age" column="user_age"/>
<result property="username" column="username"/>
</resultMap>
这里有个注意事项:
用resultMap的查询语句里面的字段必须要和数据库的一致,不然会报错
org.apache.ibatis.exceptions.PersistenceException:
Error querying database. Cause: java.sql.SQLSyntaxErrorException: Unknown column ‘age’ in ‘field list’
如果不想指名返回字段,直接查*, 如select * from user where sex = #{sex};
二、#{}和${}的使用注意
${}是字符串替换,#{}是预处理;
Mybatis在处理${}时,就是把${}直接替换成变量的值。
而Mybatis在处理#{}时,会对sql语句进行预处理,将sql中的#{}替换为?,然后调用PreparedStatement的set方法来赋值;
如:select * from user where name = #{userName};预处理将#{userName}替换成了?,即select * from user where name = ?
如果是 select * from user where name = ${userName};处理时直接编程 select * from user where name = 真正的值
使用#{}可以有效的防止SQL注入,提高系统安全性,首选这种方式
三、高版本MySQL的驱动问题,如 MySQL8.0
驱动改成com.mysql.cj.jdbc.Driver
如,数据库配置文件
<configuration>
<environments default="mysql">
<environment id="mysql">
<!--配置事务的类型,使用本地事务策略-->
<transactionManager type="JDBC"></transactionManager>
<!--是否使用连接池 POOLED表示使用链接池,UNPOOLED表示不使用连接池-->
<dataSource type="POOLED">
<!--低版本 <property name="driver" value="com.mysql.jdbc.Driver"/>-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/db"/>
<property name="username" value=""/>
<property name="password" value=""/>
</dataSource>
</environment>
</environments>
<mappers>
.....
</mappers>
</configuration>
相对于的pom配置(如果系统报错)
<!--mybatis核心包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!--mysql驱动包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
如果idea一直报错
Unable to reload Maven project
请重新搭建工程,可能是就版本工程有些配置没删,应该是idea的bug
四、模糊查询注意
应该将like的值全部放在#{}中,而不是在sql拼接%%符号
正确:select * from user where username like #{name}
错误:select * from user where username like '%${username}%'
注意,如果报错
There is no getter for property named ‘username’ in ‘class> java.lang.String’
就讲参数改成对象传入
dao 是 List<User> like(User user);
mapping 是 select * from user where username like '%${username}%'
其中 User 对象包含字段 username