如今有學生和老師兩張表老師的Mapperweb
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.abc.mapper.TeacherMapper">
<resultMap type="com.abc.domian.Teacher" id="supervisorResultMap">
<id property="id" column="oid"/>
<result property="name" column="name"/>
<result property="gender" column="gender"/>
<result property="researchArea" column="research_area"/>
<result property="title" column="title"/>
<!-- <collection property="supStudent" resultMap="com.abc.mapper.StudentMapper.StudentResultMap"></collection> -->
<collection property="supStudent" column="id" select="com.abc.mapper.StudentMapper.getStudentByTeacherId" resultMap="com.abc.mapper.StudentMapper.StudentResultMap"></collection>
</resultMap>
<select id="getById" parameterType="int" resultMap="supervisorResultMap">
select t.id as oid ,t.name,t.gender,t.research_area,t.title,s.id,s.name as s_name,s.gender,s.major,s.grade,s.supervisor_id from student s , teacher t where s.supervisor_id = t.id
and t.id=#{id}
</select>
<select id="getAllTeacher" parameterType="map" resultMap="supervisorResultMap">
select * from teacher
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.abc.mapper.StudentMapper">
<resultMap type="com.abc.domian.Student" id="StudentResultMap">
<id property="id" column="id"/>
<result property="name" column="s_name"/>
<result property="gender" column="gender"/>
<result property="major" column="major"/>
<result property="grade" column="grade"/>
<association property="supervisor" resultMap="com.abc.mapper.TeacherMapper.supervisorResultMap">
</association>
</resultMap>
<select id="getById" parameterType="int" resultMap="StudentResultMap">
select * from student where id = #{id}
</select>
<!-- #name 中那麼大小寫敏感 useGeneratedKeys設置爲true是由數據庫自動生成逐漸 keyProperty 指定把得到到的主鍵值注入 到Student的id屬性-->
<insert id="add" parameterType="com.abc.domian.Student" useGeneratedKeys="true" keyProperty="id">
insert into student(name,gender,major,grade) values(#{name},#{gender},#{major},#{grade})
</insert>
<update id="update" parameterType="com.abc.domian.Student" >
update student set gender = #{gender} where id= #{id}
</update>
<!-- org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.abc.mapper.StudentMapper.delete 若是id和Mapper不匹配的話會拋出上述的錯誤 -->
<delete id="delete" parameterType="com.abc.domian.Student">
delete from student where id = #{id}
</delete>
<select id="getStudnetAndTeacher" parameterType="int" resultMap="StudentResultMap">
select * from student s ,teacher t where s.supervisor_id = t.id and s.id = #{id}
</select>
<insert id="addStudent" parameterType="com.abc.domian.Student" useGeneratedKeys="true" keyProperty="id">
insert into student(name,gender,major,grade,supervisor_id)
values(#{name},#{gender},#{major},#{grade},#{supervisor.id})
</insert>
<select id="getStudentByTeacherId" parameterType="string" resultMap="StudentResultMap">
select * from student where supervisor_id = #{id}
</select>
</mapper>
2.一、關聯查詢時效率的問題---經過老師查找學生getById的形式
配置文件:sql
<resultMap type="com.abc.domian.Teacher" id="supervisorResultMap">
<id property="id" column="oid"/>
...
<collection property="supStudent" column="id" select="com.abc.mapper.StudentMapper.getStudentByTeacherId" resultMap="com.abc.mapper.StudentMapper.StudentResultMap"></collection>
</resultMap>
<select id="getById" parameterType="int" resultMap="supervisorResultMap">
select t.id as oid ,t.name,t.gender,t.research_area,t.title,s.id,s.name as s_name,s.gender,s.major,s.grade,s.supervisor_id from student s , teacher t where s.supervisor_id = t.id
and t.id=#{id}
</select>
<resultMap type="com.abc.domian.Student" id="StudentResultMap">
<id property="id" column="id"/>
...
<association property="supervisor" resultMap="com.abc.mapper.TeacherMapper.supervisorResultMap">
</association>
</resultMap>
經過上面的配置咱們能夠看出來;老師查詢學生的時候,使用經過select的配置進行查詢的,若是咱們經過這種方式來查詢學生是會致使sql語句的增多;咱們查看控制檯後,發現輸出的內容爲:數據庫
select t.id as oid ,t.name,t.gender,t.research_area,t.title,s.id,s.name as s_name,s.gender,s.major,s.grade,s.supervisor_id from student s , teacher t where s.supervisor_id = t.id and t.id=? select * from student where supervisor_id = ? select * from student where supervisor_id = ? select * from student where supervisor_id = ? select * from student where supervisor_id = ?
sql語句的個數明顯不少,所以不建議經過該方式進行查詢;
解決辦法:
若是咱們將老師的mapper映射文件:apache
<collection property="supStudent" column="id" select="com.abc.mapper.StudentMapper.getStudentByTeacherId" resultMap="com.abc.mapper.StudentMapper.StudentResultMap"></collection>
修改成:mybatis
<collection property="supStudent" resultMap="com.abc.mapper.StudentMapper.StudentResultMap"></collection>
在進行查詢的時候咱們發現會只輸出一句話;app
select t.id as oid ,t.name,t.gender,t.research_area,t.title,s.id,s.name as s_name,s.gender,s.major,s.grade,s.supervisor_id from student s , teacher t where s.supervisor_id = t.id and t.id=?
在進行關聯映射的時候儘可能不要使用collection中的select語句,這樣會致使查詢語句增多的問題;能夠本身書寫sql語句,讓mybatis進行映射dom
2.2 關聯查詢別稱起到的做用
根據輸出的內容我麼還能夠發現另一些問題:
一、經過自定義的sql語句進行查詢時管理的查詢出的對象沒有null
二、經過select的配置查詢的記錄是由null只出現的;
ide
當咱們吧select * from teacher這條語句進行替換成自定義的sql時;ui
<select id="getAllTeacher" parameterType="map" resultMap="supervisorResultMap"> select t.id as oid ,t.name,t.gender,t.research_area,t.title,s.id,s.name as s_name,s.gender,s.major,s.grade,s.supervisor_id from student s , teacher t where s.supervisor_id = t.id </select>
使用Mybatis時,儘可能使用一條sql語句去完成查詢spa
2.3 關聯是對參數的賦值問題
驗證關聯查詢的時候使用的時sql名稱仍是屬性名稱,sql語句查詢時參數的賦值依據
參數的賦值結果是由parameterType="map"類型決定的若是爲對象,那麼從屬性中得到,若是爲map,參數有map中的鍵決定
2.4 關聯是對參數的賦值問題
若是我想經過老師的專業,來查詢學士,注意下面兩天sql語句的不一樣:
SELECT s.id, t.id , s.name , t.gender, t.research_area, t.title, t.name, s.gender, s.major, s.grade, s.supervisor_id FROM student s, teacher t WHERE s.supervisor_id = t.id and t.research_area = '1'
SELECT t.id , s.name , t.gender, t.research_area, t.title, s.id, t.name, s.gender, s.major, s.grade, s.supervisor_id FROM student s, teacher t WHERE s.supervisor_id = t.id and t.research_area = '1'
數據庫中的sql條數爲
使用一條sql語句時,注意要返回的結果是誰,若是返回多的一方,請將多的一方id放置到第一列,若是返回的是少的一方,請將少的一方id放置到第一列,
即:根據 resultMap="StudentResultMap" 對象的id放置第一列
2.5 賦值的參數類型有誰決定
由parameterType="map"去決定值
2.6若是使用了關聯查詢,而且配置了column,查詢時參數的設置
使用column活着,column對應的屬性或者該屬性對應的列 均可以查詢出結果集sql
2.7 實體類有相同的字段,查詢數據會被覆蓋
在查詢時,有學生和老師兩個對象,可是學生中的name和老師的那麼屬性是一致的,使用關聯對象進行查詢的時候,就會遇到學生的name值被覆蓋給了老師如圖:
查詢到的老師的姓名都是學生的,這個時候有兩種解決辦法:
a、 經過修改數據庫,將學生和老師的兩個字段都進行修改;讓他們的字段不同,這樣映射也就不會有錯誤;
b、另一種方式是不修改數據庫的字段,修改映射文件中的result
<id column="tea_id" property="id" jdbcType="INTEGER" />
<result column="tea_name" property="name" jdbcType="VARCHAR" />
<result column="tea_gender" property="gender" jdbcType="VARCHAR" />
<result column="tea_research_area" property="researchArea" jdbcType="VARCHAR" />
<result column="tea_title" property="title" jdbcType="VARCHAR" />
以及
<sql id="Base_Column_List" >
id as tea_id, name as tea_name, gender as tea_gender, research_area as tea_research_area, title as tea_title
</sql>
來完成修改,固然查詢的sql語句也是須要修改的
<select id="queryStudentAndTeacher" resultMap="BaseResultMap" useCache="true" >
SELECT
s.id,
s.`name`,
s.gender,
s.major,
s.grade,
s.supervisor_id ,
t.id as tea_id,
t.`name` as tea_name,
t.gender as tea_gender,
t.research_area as tea_research_area,
t.title as tea_title
FROM
student s
LEFT JOIN teacher t ON s.supervisor_id = t.id
</select>
3 資料
/* Navicat MySQL Data Transfer Source Server : localhost_3306 Source Server Version : 50528 Source Host : localhost:3306 Source Database : courseman Target Server Type : MYSQL Target Server Version : 50528 File Encoding : 65001 Date: 2015-04-21 16:54:27 */
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `gender` varchar(255) DEFAULT NULL, `major` varchar(255) DEFAULT NULL, `grade` varchar(255) DEFAULT NULL, `supervisor_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('1', '李林', '男', '計算機科學與技術', '2011', '1');
INSERT INTO `student` VALUES ('2', '陳明', '男', '軟件技術', '2012', '1');
INSERT INTO `student` VALUES ('3', '李林1', '男', '計算機科學與技術', '2011', '2');
INSERT INTO `student` VALUES ('4', '陳明2', '男', '軟件技術', '2012', '2');
-- ----------------------------
-- Table structure for teacher
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `gender` varchar(255) DEFAULT NULL, `research_area` varchar(255) DEFAULT NULL, `title` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of teacher
-- ----------------------------
INSERT INTO `teacher` VALUES ('1', '陳老師', '男', '計算機', '暫無');
INSERT INTO `teacher` VALUES ('2', '郝老師', '男', '無語', '五');