多表聯查 resultMap複雜關系
一對一
模型:
一個人有一個身份證
create table person(
pid int primary key auto_increment,
pname varchar(20),
address varchar(20)
);
create table card(
cid int primary key auto_increment,
cnum varchar(20),
fk_pid int
);
insert person( pname, address) values ('張三','中州'),('李四','商州'),('王五','下州')
insert card(cnum, fk_pid) values ('110',1),('120',2),('119',3);

personMapper.xml
<?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.ujiuye.dao.PersonDao">
<select id="getAll" resultMap="newPerson">
/* 第一種,第二種sql*/
/*select p.*,c.* from person p,card c where p.pid=c.fk_pid*/
/*第三種sql*/
select * from person
</select>
<resultMap id="newPerson" type="person">
<id column="pid" property="pid"/>
<result property="pname" column="pname"/>
<result column="address" property="address"/>
<!--第一種一對一-->
<!-- <association property="card" javaType="card">
<id property="cid" column="cid"/>
<result column="cnum" property="cnum"/>
</association>-->
<!--第二種一對一,引用别人的resultMap-->
<!-- <association property="card" javaType="card" resultMap="com.ujiuye.dao.CardDao.newCard">
</association>-->
<!--第三種一對一 調用别人的sql ,傳person的pid-->
<association property="card" column="pid"
javaType="card" select="com.ujiuye.dao.CardDao.getByFK">
</association>
</resultMap>
</mapper>
cardMapper.xml
<?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.ujiuye.dao.CardDao">
<select id="getByFK" parameterType="int" resultType="card">
select * from card where fk_pid=#{0}
</select>
<resultMap id="newCard" type="card">
<id property="cid" column="cid"/>
<result property="cnum" column="cnum"/>
</resultMap>
</mapper>
一對多
模型:
一個學生有多本書
Student
Book
知識點:
Collection:集合
property實體類中集合屬性名
column傳給新sql的值
ofType:集合的類型
resultMap:結果集
Select:調用的sql語句
表:
create table student(
sid int primary key auto_increment,
sname varchar(10)
);
create table book(
bid int primary key auto_increment,
bname varchar(10),
fk_sid int
);
insert student(sname)values ('張三'),('李四'),('王五');
insert book(bname, fk_sid) values ('java',1),('php',1),('c++',2),('python',2)
實體:
public class StudentBean {
private int sid;
private String sname;
private List<BookBean> books;
public class BookBean {
private int bid;
private String bname;
StudentMapper.xml
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.ujiuye.dao.StudentDao">
<select id="getAllStudent" resultMap="stu">
/* 第一種和第二種的sql*/
/* select s.*,b.* from student s,book b where s.sid=b.fk_sid;*/
select *from student
</select>
<resultMap id="stu" type="com.ujiuye.bean.StudentBean">
<id column="sid" property="sid"/>
<result column="sname" property="sname"/>
<!--第一種 一對多集合必須用ofType-->
<!--<collection property="books" ofType="com.ujiuye.bean.BookBean">
<id property="bid" column="bid"/>
<result property="bname" column="bname"/>
</collection>-->
<!--第二種一對多-->
<!-- <collection property="books" ofType="com.ujiuye.bean.BookBean"
resultMap="com.ujiuye.dao.BookDao.bookMapper"></collection>-->
<!--第三種一對多-->
<collection property="books" column="sid" ofType="com.ujiuye.bean.BookBean"
select="com.ujiuye.dao.BookDao.getBooksByFK"></collection>
</resultMap>
</mapper>
bookMapper.xml
<?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.ujiuye.dao.BookDao">
<select id="getBooksByFK" resultMap="bookMapper">
select *from book where fk_sid=#{0}
</select>
<resultMap id="bookMapper" type="com.ujiuye.bean.BookBean">
<id column="bid" property="bid"/>
<result column="bname" property="bname"/>
</resultMap>
</mapper>
測試類:
@Test
public void test2() throws IOException {
InputStream is=Resources.getResourceAsStream("mybatis-conf.xml");
SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(is);
SqlSession session = ssf.openSession();
StudentDao mapper = session.getMapper(StudentDao.class);
List<StudentBean> list= mapper.getAllStudent();
System.out.println(list);
}
多對多
模型:
Teacher----course 多對多
中間表 teac_cour
多對多
拆分成一對多 多個一對一
建立老師表:teacher
課程表:course
中間表: teac_course
實體:
public class TeacherBean {
private int tid;
private String tname;
private List<Teac_Course> ts;
public class CourseBean {
private int cid;
private String cname;
public class Teac_Course {
private CourseBean course;
private TeacherBean teacherBean;
}
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.ujiuye.dao.TeacherDao">
<select id="getAll" resultMap="newTeacher">
select * from teacher t,teac_course ts,course c where t.tid=ts.tid and ts.cid=c.cid
</select>
<resultMap id="newTeacher" type="com.ujiuye.bean.TeacherBean">
<id column="tid" property="tid"/>
<result column="tname" property="tname"/>
<collection property="ts" ofType="com.ujiuye.bean.Teac_Course">
<association property="course" javaType="com.ujiuye.bean.CourseBean">
<id column="cid" property="cid"/>
<result property="cname" column="cname"/>
</association>
</collection>
</resultMap>
</mapper>
測試結果:
@Test
public void test3() throws IOException {
InputStream is=Resources.getResourceAsStream("mybatis-conf.xml");
SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(is);
SqlSession session = ssf.openSession();
TeacherDao mapper = session.getMapper(TeacherDao.class);
List<TeacherBean> list= mapper.getAll();
System.out.println(list);
}
動态sql
Jdbc拼接sql
Public void getByCondition(String name,String address){
String sql=”select*from person where 1=1”;
If(name!=null){
Sql+=” and name=’”+name”’”;
}
If(address!=null){
Sql+=” and address=’”+address”’”;
}
…
}
在java中判斷之後拼接sql語句,他麻煩,不安全,mybtis已經幫你幹了這件事情
Where标簽
Where标簽替代了sql中where 而且自動幫你屏蔽掉緊跟着where後面的and 或者是or
裡面還可加條件
<select id="getByCondition" resultMap="newPerson">
select * from person
<where>
/*多了一個and或者orwhere标簽會自動幫你删掉緊跟着where後面and或者or*/
or pname=#{0}
</where>
</select>
If标簽
根據入參靈活的判斷,加入相應的條件
注意:
入參是獨立參數不是對象或者map 參數加别名
如此那是對象擷取map #{屬性名}
<select id="getByCondition2" resultType="com.ujiuye.bean.PersonBean">
select *from person
<where>
<!--test中可以使用java中的方法-->
<if test="pname!=null and pname.length()>0">
and pname like #{pname}
</if>
<if test="paddress!=null and paddress.length()>0">
or address=#{paddress}
</if>
</where>
</select>
choose标簽
相當于 java 中 switch 或者 if…ifelse …ifelse …else
<select id="getByCondition3" parameterType="com.ujiuye.bean.PersonBean" resultType="person">
select *from person
<where>
<choose>
<when test="pid!=0">
and pid=#{pid}
</when>
<when test="pname!=null">
and pname=#{pname}
</when>
<otherwise>
and address=#{address}
</otherwise>
</choose>
</where>
</select>
Set标簽
Update person set pname=”李四”, address=”山東”, where pid=2;
Set 可以直接去掉最後一個逗号
trim标簽
Trim不是去除空格的去除prefix 後面多餘的内容
可以代替where或set 用到的機會很少
<select id="getByCondition4" parameterType="person" resultType="person">
select *from person
<trim prefix="where" prefixOverrides="and|or">
<if test="pname!=null">
and pname=#{pname}
</if>
<if test="address!=null">
and address=#{address}
</if>
</trim>
</select>
Foreach 循環批量操作
可以循環的周遊參數中的集合
批量删除 delete from person where pid in(1,2,3)
Values(),(),()
<insert id="addList" parameterType="java.util.List">
insert person(pname,address) values
<foreach collection="st" item="p" separator=",">
(#{p.pname},#{p.address})
</foreach>
</insert>
<delete id="delBatch">
delete from person where pid in
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</delete>
Collection:如果入參類型時集合直接寫list,或者起參數别名
Item:每次周遊到的對象
Open:以什麼開始
Close:以什麼結束
Separator:分割器,以什麼分割