在平时的开发中,我们表中的字段名和表对应实体类的属性名称不一定都是完全相同的,下面来演示一下这种情况下的如何解决字段名与实体类属性名不相同的冲突。
一、准备演示需要使用的表和数据
CREATE TABLE `person` (
`p_id` int(11) NOT NULL AUTO_INCREMENT,
`p_name` varchar(255) DEFAULT NULL,
`p_age` int(11) DEFAULT NULL,
PRIMARY KEY (`p_id`)
) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8;
INSERT INTO `person` VALUES ('1', '1111', '24');
INSERT INTO `person` VALUES ('2', '2222', '24');
INSERT INTO `person` VALUES ('3', '3333', '24');
INSERT INTO `person` VALUES ('24', '666', '20');
二、定义实体类
public class Person {
private int id; // id -- p_id
private String name; // name --p_name
private int age; // age -- p_age
public Person() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
三、编写测试代码
3.1、编写PersonMapper接口
public interface PersonMapper {
public Person getPersonById(int id);
public Person selectPerson(int id);
public Person selectPersonResultMap(int id);
}
3.2、编写SQL的xml映射文件
1、创建一个personMapper.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">
<!-- namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离 注意:使用mapper代理方法开发,namespace有特殊重要的作用 -->
<mapper namespace="com.baowei.mapper.PersonMapper">
<!-- 根据id查询得到一个order对象,使用这个查询是查询不到我们想要的结果的, 这主要是因为实体类的属性名和数据库的字段名对应不上的原因,因此无法查询出对应的记录 -->
<select id="getPersonById" parameterType="int"
resultType="com.baowei.entity.Person">
select * from person where p_id=#{id}
</select>
<!-- 根据id查询得到一个order对象,使用这个查询是可以正常查询到我们想要的结果的, 这是因为我们将查询的字段名都起一个和实体类属性名相同的别名,这样实体类的属性名和查询结果中的字段名就可以一一对应上 -->
<select id="selectPerson" parameterType="int"
resultType="com.baowei.entity.Person">
select p_id id, p_name name,p_age age from
person where
p_id=#{id}
</select>
<!-- 根据id查询得到一个order对象,使用这个查询是可以正常查询到我们想要的结果的, 这是因为我们通过<resultMap>映射实体类属性名和表的字段名一一对应关系 -->
<select id="selectPersonResultMap" parameterType="int"
resultMap="personResultMap">
select * from person where p_id=#{id}
</select>
<!--通过<resultMap>映射实体类属性名和表的字段名对应关系 -->
<resultMap type="com.baowei.entity.Person" id="personResultMap">
<!-- 用id属性来映射主键字段 -->
<id property="id" column="p_id" />
<!-- 用result属性来映射非主键字段 -->
<result property="name" column="p_name" />
<result property="age" column="p_age" />
</resultMap>
</mapper>
2、在SqlMapConfig.xml文件中注册映射Mapper对象
<!-- 加载 映射文件 -->
<mappers>
<package name="com.baowei.mapper" />
</mappers>
3.3、编写单元测试代码
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import com.baowei.entity.Person;
import com.baowei.mapper.PersonMapper;
public class Test2 {
@Test
public void testGetPersonById1() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
Person person = mapper.getPersonById(1);
System.out.println(person);
}
@Test
public void testGetPersonById2() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
Person person = mapper.selectPerson(1);
System.out.println(person);
}
@Test
public void testGetPersonById3() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
Person person = mapper.selectPersonResultMap(1);
System.out.println(person);
}
}
执行单元测试的结果:
1、testGetPersonById1方法执行查询后返回一个null。
2、testGetPersonById2方法和testGetPersonById3方法执行查询后可以正常得到想要的结果。
四、总结
上面的测试代码演示当实体类中的属性名和表中的字段名不一致时,使用MyBatis进行查询操作时无法查询出相应的结果的问题以及针对问题采用的两种办法:
解决办法一: 通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致,这样就可以表的字段名和实体类的属性名一一对应上了,这种方式是通过在sql语句中定义别名来解决字段名和属性名的映射关系的。
解决办法二: 通过<resultMap>来映射字段名和实体类属性名的一一对应关系。这种方式是使用MyBatis提供的解决方式来解决字段名和属性名的映射关系的。