三張表,通過班級 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屬性指明集合中的數據類型,
好啦,大家動手試試。