三张表,通过班级 clsId=3001 查找班级和学生的信息
1. 建表 表结构如下
create table student
(
stuId number(4) primary key,
stuName varchar2(20) not null,
stuSex varchar2(4),
stuBirthday date,
classId number(4)
);
create table classes
(
clsId number(4) primary key,
clsName varchar2(20) not null,
teacherId number(4)
);
create table teacher
(
teacherId number(4) primary key,
teacherName varchar2(20) not null,
workYear number(2),
professional varchar2(20)
);
插入一些测试数据
2. entity包下新建三个实体类和三个 同名Mapper.xml
3. mapper包内新建三个同名Mapper接口,现在不做任何处理
4. mybatis.xml 中的配置
<mappers>
<mapper resource="com/yc/mybitis/entity/ClassesMapper.xml"/>
<mapper resource="com/yc/mybitis/entity/StudentMapper.xml"/>
<mapper resource="com/yc/mybitis/entity/TeacherMapper.xml"/>
</mappers>
<!-- 定义类型的别名 -->
<typeAliases>
<!-- 只能为一种类型指定别名 -->
<!--<typeAlias type="com.yc.mybitis.entity.User" alias="User"/>-->
<!-- 给指定包的所有类定义别名, 别名就是与不带包的类名相同 -->
<package name="com/yc/mybitis/entity"/>
</typeAliases>
5. mybatis工具类编写 MybatisUtil
public class MybatisUtil {
private static Logger log=LoggerFactory.getLogger(MybatisUtil.class);
private static SqlSessionFactory factory;
static{
try {
log.debug("加载mybatis.xml的配置文件");
InputStream in =Resources.getResourceAsStream("mybatis.xml");
log.debug("加载mybatis.xml的配置文件成功");
log.debug("通过配置文件的数据构建sql session工厂");
factory=new SqlSessionFactoryBuilder().build(in);
log.debug("通过配置文件的数据构建sql session工厂 【成功】" );
log.debug("生产sqlsession 工厂对象");
} catch (IOException e) {
e.printStackTrace();
log.debug("加载mybatis.xml的配置文件失败",e);
}
}
public static SqlSession getSession(){
//原来这么些
//InputStream in=MybatisUtil.class.getClassLoader().getResourceAsStream("mybatis.xml");
//mybatis这么写
SqlSession session=null;
session=factory.openSession();
log.debug("生产sqlsession 工厂对象 成功");
return session;
}
/**
*
* @param isAutoCommit :true: 自动提交事务, false 手动事务
* @return
*/
public static SqlSession getSession(boolean isAutoCommit){
SqlSession session=null;
session=factory.openSession( isAutoCommit );
log.debug("生产sqlsession 工厂对象 成功");
return session;
}
}
6. 查询要求:
A、嵌套查询:
通过班级 clsId=3001 查找班级和学生的信息
select * from classes where clsId =3001
select * from student where classId =3001
ClassesMapper.xml中的配置
<mapper namespace="com.yc.mybatis.mapper.ClassesMapper">
<!-- 第一种 嵌套查询 记录多条,所以不能使用 association 必须选择 collection:表示多个结果-->
<resultMap type="Classes" id="ClassesMap">
<id column="clsId" property="clsId"/><!-- 指定取出字段值会取出多次,不指定就只会取出一次 -->
<collection property="stus" column="clsId" select="getStudents"></collection>
</resultMap>
<select id="getClassesById" parameterType="int" resultMap="ClassesMap">
select * from classes where clsId=#{clsId}
</select>
<select id="getStudents" resultType="Student">
select * from student where classId=#{clsId}
</select>
</mapper>
这一次的查询不需要用到 StudentMapper 和TeacherMapper,就不给出内容了
7. 接口 ClassesMapper.java只有一个方法,注意方法名需要和 ClassesMapper.xml中select语句指定的 id 一致
public interface ClassesMapper {
public Classes getClassesById(int clsid);
}
8. Junit单元测试
public class ClassesMapperTest {
private ClassesMapper classesMapper;
@Before
public void setUp() throws Exception {
classesMapper=MybatisUtil.getSession().getMapper(ClassesMapper.class);
}
@After
public void tearDown() throws Exception {
classesMapper=null;
}
@Test
public void testGetClassesById() {
Classes c=classesMapper.getClassesById(3001);
System.out.println(c);
}
}
9、运行测试类。成功。
6. 查询要求
B、嵌套结果:
select * from student s join classes c on c.clsId=3001 and s.classId=c.clsId
ClassesMapper.xml中的配置 ,为了避免大家混淆了两种写法,建议新建一个ClassesMapper02.xml
<mapper namespace="com.yc.mybatis.mapper.ClassesMapper02">
<!--
第二种 嵌套结果 记录多条,所以不能使用 association 必须选择 collection:表示多个结果
select * from student s join classes c on c.clsId=3001 and s.classId=c.clsId
-->
<resultMap type="Classes" id="ClassesMap03">
<id column="clsId" property="clsId" /><!--指定取出字段值会取出多次,不指定就只会取出一次-->
<result column="clsName" property="clsName" />
<collection property="stus" ofType="Student" resultMap="StudentMap">
<!--
ofType:指定 list集合中的数据类型
-->
</collection>
</resultMap>
<resultMap type="Student" id="StudentMap">
<id column="stuId" property="stuId" />
<result column="stuName" property="stuName" />
<result column="stuSex" property="stuSex" />
<result column="classId" property="classId" />
<!--<result column="stuBirthday" property="stuBirthday"/>-->
</resultMap>
<select id="getClassesById" parameterType="int" resultMap="ClassesMap03">
select * from student s join classes c on c.clsId=#{clsId} and
s.classId=c.clsId
</select>
</mapper>
7. 与嵌套查询的步骤相同,同样建议新建一个接口和测试类
8. 注意,要是新建了ClassesMapper.xml ,那么我们项目的主配置文件 mybatis.xml中的mappers也需要更改
<mappers>
<!--<mapper resource="com/yc/mybitis/entity/ClassesMapper.xml"/>-->
<mapper resource="com/yc/mybitis/entity/ClassesMapper02.xml"/>
<mapper resource="com/yc/mybitis/entity/StudentMapper.xml"/>
<mapper resource="com/yc/mybitis/entity/TeacherMapper.xml"/>
</mappers>
9. 测试成功。
上课走了个神,然后就错过了姜哥讲的小知识,然后就导致了项目出错,还好看懂了报错提示。不多说,我们看错误详解
数据类型不匹配导致反射出现异常,我们需要在collection 中使用 ofType属性指明集合中的数据类型,
好啦,大家动手试试。
版权声明:本文为博主原创文章,谢谢参考!有问题的地方,欢迎纠正,一起进步。
MyBatis之高级关联和集合映射(二、嵌套查询和嵌套结果小案例)
原文地址:http://blog.csdn.net/emilyrr/article/details/47027719