您的位置:首页 > 其它

MyBatis之高级关联和集合映射(二、嵌套查询和嵌套结果小案例)

2015-07-23 20:22 686 查看
三张表,通过班级 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的配置

<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属性指明集合中的数据类型,



好啦,大家动手试试。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: