天天看點

架構專題 Mybatis進階及使用總結 + 案例

多表聯查 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);
           
架構專題 Mybatis進階及使用總結 + 案例
架構專題 Mybatis進階及使用總結 + 案例

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);
    }
           
架構專題 Mybatis進階及使用總結 + 案例

動态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:分割器,以什麼分割

繼續閱讀