如果我们的表的字段名和实体类的属性名不一致的话
- 我们都知道,数据库中查询结果是通过其字段名然后找到属性名再反射赋值
- 如果字段名和属性名不一致,那么怎么通过字段名找到属性名呢?
方法
-
起别名,在查询的时候起别名,别名和属性名一致
select emp_id empId,emp_name empName from t_emp where emp_id = #{empId}
-
因为mysql字段命名(表名_字段名)和java属性命名(驼峰命名)规则不一致,所以经常有字段名和属性名不一致的情况,我们可以在mybatis核心配置文件中设置一个全局配置,可以映射字段名和属性名
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
- 这样设置mybatis全局中,会自动将字段名映射为驼峰命名
-
使用resultMap自定义映射处理
- 首先我们要在映射文件里自定义resultMap标签
<resultMap id="empResultMap" type="Emp">
<id column="emp_id" property="empId"></id>
<result column="emp_name" property="empName"></result>
<result column="age" property="age"></result>
<result column="gender" property="gender"></result>
</resultMap>
- 解释一下
- resultMap id 表示你在使用resultMap是方便指定是哪个resultMap,type就是映射属性的实体类
- 标签中的id 表示处理 主键映射 column表示我们要处理的从数据库中查询出来的字段名 property表示当前我们处理的实体类的属性名
- result 表示处理普通字段的映射 其他与id同理
-
多对一映射关系处理
- 记好一个准则 对一就是对一个对象 对多就是一个集合
- 现在我有一个Emp类和一个Dept类,Emp和Dept是多对一的关系
- 所以Emp类中有一个属性是
private Dept dept
,但是emp表对应的Emp类中的这个dept属性该怎么映射呢- 一开始我们想用多表连接查询来进行映射,我们的确能查询到Emp类中dept对象属性的属性值如deptId,depName等,但是我们无法将这些属性值映射到Emp类中的dept对象属性中去,还是无法为dept属性赋值
- 三种处理方式
- 级联方式处理
<resultMap id="EmpResultMap" type="Emp">
<id column="emp_id" property="empId"></id>
<result column="emp_name" property="empName"></result>
<result column="age" property="age"></result>
<result column="gender" property="gender"></result>
<result column="dept_id" property="dept.deptId"></result>
<result column="dept_name" property="dept.deptName"></result>
</resultMap>
- 通过这种方式为Emp中的dept属性赋值,通过多表查询。
- association处理
- 使用association处理实体类中实体类类型属性
<resultMap id="EmpResultMap" type="Emp">
<id column="emp_id" property="empId"></id>
<result column="emp_name" property="empName"></result>
<result column="age" property="age"></result>
<result column="gender" property="gender"></result>
<association property="dept" javaType="Dept">
<id column="dept_id" property="deptId"></id>
<result column="dept_name" property="deptName"></result>
</association>
</resultMap>
- 上面的javatype就是实体类型属性的类名(别名)
- 在assciation标签里面处理查询到的数据库字段和实体类属性的属性之间的关系
- 分步查询处理
- 一定要理清查询的顺序,它不需要多表查询,先查什么后查什么
- 这个比较难搞一点,现在我有一个t_emp表和t_dept表,emp表中每条数据都有一个dept_id来表示它属于哪个dept,通过分步查询来获取它所属部门的详细信息(部门名称等)
- 首先根据emp_id查询到对应的记录
<select id="getEmpById" resultMap="EmpResultMap">
select * from t_emp where emp_id = #{empId}
</select>
- 在resultMap中定义好映射关系
<resultMap id="EmpResultMap" type="Emp">
<id column="emp_id" property="empId"></id>
<result column="emp_name" property="empName"></result>
<result column="age" property="age"></result>
<result column="gender" property="gender"></result>
<association property="dept" select="com.cn.zt.mybatis.mappers.DeptMapper.selectDeptById" column="dept_id"
</association>
</resultMap>
- 先解释一下 这里还是要用到asscation标签,但是用法不一样,这次是在asscation中添加属性而不是在asscaation标签内添加映射关系
- property属性还是用来表示属性名,这里的属性是dept实体类属性
- select属性表示sql标识符(namespace+select的id) 这个是分步查询的精髓,他表示了下一步该用到哪个查询语句
- column属性表示下一个sql语句要用的条件(参数)
- 下一条查询语句
<select id="selectDeptById" resultType="Dept">
select * from t_dept where dept_id = #{deptId}
</select>
- 通过这条查询返回dept给emp中dept属性赋值
- 流程大概是这样,我详细点
- 首先在测试方法中调用
Emp empById = mapper.getEmpById(1);
Emp getEmpById(@Param("empId") int empId);
- 然后到映射文件中
<select id="getEmpById" resultMap="EmpResultMap">
select * from t_emp where emp_id = #{empId}
</select>
- 再到
Dept seletDeptById(@Param("deptId") int deptId);
- 然后到映射文件中
<select id="selectDeptById" resultType="Dept">
select * from t_dept where dept_id = #{deptId}
</select>
- 首先在测试方法中调用
- 分步查询的优点 [[延迟加载]]
- 级联方式处理
-
一对多映射关系处理
- 使用collection标签(处理集合类型属性)
- 举个例子,我一个Dept类中有一个Emp集合,一对多关系
- 使用方法 和 asscation标签 类似
- 使用resultMap来处理映射关系
<resultMap id="resultMapList" type="Dept">
<id column="dept_id" property="deptId"></id>
<result column="dept_name" property="deptName"></result>
<collection property="empList" ofType="Emp">
<id column="emp_id" property="empId"></id>
<result column="emp_name" property="empName"></result>
<result column="age" property="age"></result>
<result column="gender" property="gender"></result>
</collection>
</resultMap>
- 有些不同的地方就在于collection标签中的 ofType属性设置为映射的集合属性中的实体类型
- 然后就是多表查询映射
- 使用分步查询
- 过程类似多对一映射分步查询,再演示一遍
- 举例子,Dept类中有个Emp集合,一对多映射
- 首先
- 第一步用deptId查到对应记录并赋值到dept对象中
Dept selectDept(@Param("deptId") int deptId);
- 映射文件写法
<select id="selectDept" resultMap="resultMapList">
select * from t_dept where dept_id = #{deptId}
</select>
<resultMap id="resultMapList" type="Dept">
<id column="dept_id" property="deptId"></id>
<result column="dept_name" property="deptName"></result>
<collection property="empList" select="com.cn.zt.mybatis.mappers.EmpMapper.getEmpListBydeptId" column="dept_id">
</collection>
</resultMap>
- 下一步t_emp中deptId符合条件的记录,并以集合方式放回
List<Emp> getEmplistBydeptId(@Param("deptId") int deptId);
- 对应映射文件写法
<select id="getEmpListBydeptId" resultType="Emp">
select * from t_emp where dept_id = #{deptId}
</select>
- 最后该集合会被赋值到dept的集合类属性中
- 第一步用deptId查到对应记录并赋值到dept对象中
- 使用collection标签(处理集合类型属性)