MyBatis学习总结(四)——字段名与实体类属性名不相同的冲突的解决
表中的字段名和表对应实体类的属性名称不一定都是完全相同的,这种情况下的如何解决字段名与实体类属性名不相同的冲突。如下所示:
一、准备演示需要使用的表和数据
CREATE TABLE my_user(
user_id INT PRIMARY KEY AUTO_INCREMENT,
user_no VARCHAR(20),
user_age int
);
INSERT INTO my_user(user_no , user_age ) VALUES('myl', 15);
INSERT INTO my_user(user_no , user_age ) VALUES('test', 11);
二、定义实体类
package com.myl.entity; import java.util.Date; /** * @author myl * @date 2018年4月27日 上午6:35:17 */ public class User { //U实体类中属性名和my_user表中的字段名是不一样的 private int id; //id 对应 user_id private String no; //no 对应 user_no private int age; //age 对应 user_age public int getId() { return id; } public void setId(int id) { this.id = id; } public String getNo() { return no; } public void setNo(String no) { this.no = no; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "User [id=" + id + ", no=" + no + ", age=" + age + "]"; } }
三、编写测试代码
3.1、编写SQL的xml映射文件
1、创建一个orderMapper.xml文件,orderMapper.xml的内容如下:
<?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,namespace的值习惯上设置成包名+sql映射文件名,这样就能够保证namespace的值是唯一的 例如namespace="com.myl.mapping.userMapper"就是com.myl.mapping(包名)+userMapper(userMapper.xml文件去除后缀) --> <mapper namespace="com.myl.entity.userMapper"> <!-- 在select标签中编写查询的SQL语句, 设置select标签的id属性为getUser,id属性值必须是唯一的,不能够重复 使用parameterType属性指明查询时使用的参数类型,resultType属性指明查询返回的结果集类型 resultType="com.myl.entity.User"就表示将查询结果封装成一个User类的对象返回 User类就是users表所对应的实体类 --> <!--不能得到正常结果,因为实体类的属性名和数据库的字段名对应不上的原因,因此无法查询出对应的记录--> <select id="getUserByB" parameterType="int" resultType="com.myl.entity.User"> select * from my_user where user_id=#{id} </select> <!-- 不能得到正常结果,因为实体类的属性名和数据库的字段名对应不上的原因,因此无法查询出对应的记录 --> <select id="getAllUserByB" resultType="com.myl.entity.User"> select * from my_user </select> <!--得到正常结果,根据id查询得到一个user对象--> <select id="getUser" parameterType="int" resultType="com.myl.entity.User"> select user_id id,user_no no,user_age age from my_user where user_id=#{id} </select> <!-- 得到正常结果,查找所有数据 --> <select id="getAllUser" resultType="com.myl.entity.User"> select user_id id,user_no no,user_age age from my_user </select> <!--得到正常结果, 通过<resultMap>映射实体类属性名和表的字段名一一对应关系 --> <select id="getUserByResultMap" parameterType="int" resultMap="UserResultMap"> select * from my_user where user_id=#{id} </select> <!-- 得到正常结果,通过<resultMap>映射实体类属性名和表的字段名一一对应关系 --> <select id="getAllUserByResultMap" resultMap="UserResultMap"> select * from my_user </select> <!--通过<resultMap>映射实体类属性名和表的字段名对应关系 --> <resultMap type="com.myl.entity.User" id="UserResultMap"> <!-- 用id属性来映射主键字段 --> <id property="id" column="user_id"></id> <!-- 用result属性来映射非主键字段 --> <result property="no" column="user_no"/> <result property="age" column="user_age"/> </resultMap> </mapper>
2、在mybatisConf.xml文件中注册userMapper.xml映射文件
<mappers> <!-- 注册userMapper.xml文件, userMapper.xml位于me.myl.mapping这个包下,所以resource写成me/myl/mapping/userMapper.xml --> <mapper resource="com/myl/mapping/userMapper.xml"/> </mappers>
3.2、编写单元测试代码
package com.myl; import java.util.List; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import com.myl.entity.User; import com.myl.util.MybatisUtil; /** * 测试 CRUD * @author myl * @date 2018年4月27日 上午6:29:42 */ public class TestCRUD { @Test public void getUserByIdByB() { SqlSession sqlSession = MybatisUtil.getSession(); /** * 执行操作,getUser 为select的id属性值 */ User user = sqlSession.selectOne("getUserByB", 1); System.out.println(user); //使用sqlSession执行完sql之后,关闭sqlSession sqlSession.close(); //打印结果:null,也就是没有查询出相应的记录 } @Test public void getAllUserByB(){ SqlSession sqlSession = MybatisUtil.getSession(); /** * 执行查询操作,将查询结果自动封装成List<User>返回 * getAllUserByB 为select标签的id属性值 */ List<User> userList = sqlSession.selectList("getAllUserByB"); for(User user : userList){ System.out.println(user); } sqlSession.close(); //打印结果:null null null 也就是没有查询出相应的记录 } @Test public void getUserById() { SqlSession sqlSession = MybatisUtil.getSession(); /** * 执行操作,getUser 为select的id属性值 */ User user = sqlSession.selectOne("getUser", 1); System.out.println(user); //打印结果:User [id=1, no=myl, age=22] //使用sqlSession执行完sql之后,关闭sqlSession sqlSession.close(); } @Test public void getAllUser(){ SqlSession sqlSession = MybatisUtil.getSession(); /** * 执行查询操作,将查询结果自动封装成List<User>返回 * getAllUser 为select标签的id属性值 */ List<User> userList = sqlSession.selectList("getAllUser"); for(User user : userList){ System.out.println(user); //打印结果:User [id=1, no=myl, age=22] 多个 } sqlSession.close(); } @Test public void getUserByIdByResultMap() { SqlSession sqlSession = MybatisUtil.getSession(); /** * 执行操作,getUser 为select的id属性值 */ User user = sqlSession.selectOne("getUserByResultMap", 1); System.out.println(user); //打印结果:User [id=1, no=myl, age=22] //使用sqlSession执行完sql之后,关闭sqlSession sqlSession.close(); } @Test public void getAllUserResultMap(){ SqlSession sqlSession = MybatisUtil.getSession(); /** * 执行查询操作,将查询结果自动封装成List<User>返回 * getAllUser 为select标签的id属性值 */ List<User> userList = sqlSession.selectList("getAllUserByResultMap"); for(User user : userList){ System.out.println(user); //打印结果:User [id=1, no=myl, age=22] 多个 } sqlSession.close(); } }
测试结果:
getUserByIdByB null (错误)
getAllUserByB 多个 null (错误)
getUserById User [id=1, no=myl, age=22] (正确)
getAllUser User [id=1, no=myl, age=22] 多个 (正确)
getUserByIdByResultMap User [id=1, no=myl, age=22] (正确)
getAllUserResultMap User [id=1, no=myl, age=22] 多个 (正确)
四、总结
测试代码演示当实体类中的属性名和表中的字段名不一致时,使用MyBatis进行查询操作时无法查询出相应的结果的问题以及针对问题采用的两种办法:
方法一: 通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致,这样就可以表的字段名和实体类的属性名一一对应上了,这种方式是通过在sql语句中定义别名来解决字段名和属性名的映射关系的。
方法二: 通过<resultMap>来映射字段名和实体类属性名的一一对应关系。这种方式是使用MyBatis提供的解决方式来解决字段名和属性名的映射关系的。