通过Mybatis处理多表关系
第一步:建表
为表添加外键 , 外键添加的位置要根据表的关系进行添加
- 1对1 外键加在哪一张都可以
- 1对多 外键加在多的一方
- 多对多 外键需要加在单独的关系表中
第二步:建实体类
为实体类添加关系属性
关系属性:就是将另一方 作为本类的一个属性存储
- 单向关系:只能从关系的一方找到另一方 , 一个类中添加关系属性
- 双向关系:可以通过任意一方找到另一方 , 两个类中都要添加关系属性
第三步:写Mapper文件
①、sql 需要进行表连接操作
②、书写ResultMap将结果映射到实体类中
<mapper namespace="oneandmore.EmpDAO"> <!-- namespace:要实现DAO接口的全限定名 -->
<resultMap id="EmpResultMap" type="Emp" > <!-- resultMap映射 id:结果集的名字 type:实体类的全限定名 -->
<id column="emp_id" property="id"/> <!-- 对查询结果的主键映射 column:映射的列 property:映射的属性名 -->
<result column="emp_name" property="name"/> <!-- 对查询结果其他列映射 column:映射的列 property:映射的属性名 -->
<result column="emp_salary" property="salary"/>
<!-- 映射关系属性
① 关系属性是集合:<collection> ofType:关系属性的类型 property:关系属性的引用名
② 关系属性是对象:<association> javaType:关系属性的类型 property:关系属性的引用名 -->
<association javaType="Dep" property="dep">
<id column="dep_id" property="id"/> <!-- 对查询结果的主键映射 column:映射的列 property:映射的属性名 -->
<result column="dep_name" property="name"/> <!-- 对查询结果其他列映射 column:映射的列 property:映射的属性名 -->
<result column="dep_location" property="location"/>
</association>
</resultMap>
<select id="selectEmpById" resultMap="EmpResultMap"> <!-- id:方法名 resultMap:结果集的名字 -->
select d.id as dep_id , d.name as dep_name , d.location as dep_location,
e.id as emp_id , e.name as emp_name , e.salary as emp_salary <!-- 表连接sql -->
from Dep d inner join Emp e
on e.dep_id = d.id
where e.id = #{id}
</select>
</mapper>
第四步:在Mybatis-config.xml中注册mapper文件
<!-- 通知Mybatis框架 mapper文件的位置 -->
<mappers>
<mapper resource="oneandmore/EmpMapper.xml"></mapper> <!-- mapper文件路径 -->
</mappers>
第五步:测试
@Test
public void testSelectById()throws Exception{
EmpDAO eDao = (EmpDAO) MybatisUtil.getMapper(EmpDAO.class);
Emp emp=eDao.selectEmpById(2);
System.out.println(emp.getId());
System.out.println(emp.getName());
System.out.println(emp.getSalary());
Dep dep = emp.getDep();
System.out.println(dep.toString());
}
附加:MybatisUtil工具类封装(线程绑定版)
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MybatisUtil {
private static SqlSessionFactory ssf;
//创建线程绑定对象
private static ThreadLocal<SqlSession> tl = new ThreadLocal<SqlSession>();
static{
//加载Mybatis框架运行参数 通过Resources读取框架配置信息 mybatis-config.xml
try {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//创建SqlSessionFactory对象
ssf = new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Mybatis Util 工具类读取配置文件出现异常!");
}
}
//供测试缓存使用 目的:,每次都获取一个新的连接 用于模拟用户
public static SqlSession getSqlSession(){
return ssf.openSession();
}
//获取SqlSession对象
public static SqlSession openSession(){
SqlSession ss = tl.get();
if(ss == null){
ss = ssf.openSession();
tl.set(ss);
}
return ss;
}
//关闭连接资源
public static void close(){
SqlSession ss = openSession();
ss.close();
//将连接从线程绑定对象中移除出去 tl.remove()
tl.remove();
}
//获取接口的实现类对象
public static Object getMapper(Class clazz){
//获取DAO接口的实现类
return openSession().getMapper(clazz);
}
//提交事务
public static void commit(){
openSession().commit();
close();
}
//回滚事务
public static void rollback(){
openSession().rollback();
close();
}
}