myBatis功能详解

一、myatis开发环境搭建
1.新建Java项目
将mybatis的jar包和mysql的jar包复制到src目录下
然后选中这2个包右击build path—>add to build path
这个2个包会自动转到
这里写图片描述
mybatis的jar包下载

https://github.com/mybatis/mybatis-3/releases

2.建立数据库users,建立表user(id,userName,userPwd)

3.引入mybatis的主配置文件mybatis-config.xml(名字在代码中要用到)

百度解决

http://mybatis.github.io/mybatis-3/getting-started.html

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE configuration  
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  
  "http://mybatis.org/dtd/mybatis-3-config.dtd">  
<configuration>  

    <!-- 对事务的管理和连接池的配置 -->  
    <environments default="development">  
        <environment id="users">   <!—users为数据库的名称 -->
            <transactionManager type="JDBC" />  
            <dataSource type="POOLED">  
                <property name="driver" value="com.mysql.jdbc.Driver" />  
                <property name="url" value="jdbc:mysql://localhost/users" />  
                <property name="username" value="root" />  
                <property name="password" value="" />  
            </dataSource>  
        </environment>  
    </environments>  

    <!-- mapping 文件路径配置 -->  
    <mappers>  
        <!-- <mapper class="model.UserMapper" />   -->
        <mapper resource="model/userMapper.xml"/> --> 
    </mappers>  
</configuration>

4.将数据库连接信息写入单独的properties文件

(1)主配置文件中将连接参数修改为变量

<property name="driver" value="${db.driver}" />  
<property name="url" value="${db.url}" />  
<property name="username" value="${db.user}" />  
<property name="password" value="${db.password}" />  

(2)引入db.properties文件

<properties resource="db.properties"></properties>

(3)在src目录下添加db.properties文件

db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/users
db.user=root
db.password=123456

5.在model包下面编写实体类User
User(id,userName,userPwd)

6.在model包下面,编写userMapper.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="model.userMapper"> 
<!—parameterType定义传入参数id的数据类型, resultType 定义返回值的数据类型-->
    <select id="selectUser" parameterType="int" resultType="model.User">
        select * from User where id = #{id}
    </select>
</mapper>

注:写好map文件之后,要去mybatis-config.xml中去配置文件路径

<mappers>
        <mapper resource="model/userMapper.xml"/>  
    </mappers>  

7.编写测试程序

(1)编写MyBatis的工具类

import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class MybatisUtils {
    public static SqlSession openSession() throws IOException
    {
            String resource = "mybatis-config.xml";
            InputStream in = Resources.getResourceAsStream(resource);
            //名称必须必须与mybatis-config.xml文件中写的数据库名称一致
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in,"users");                return sessionFactory.openSession();
    }
}

(2)新建一个Junit test case类(在测试前请先在数据库中对应表中新建一个user)

package test;

import java.io.IOException;
import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import common.MybatisUtils;
import model.User;

public class Mytest {

    @Test
    public void testSelect() throws IOException {
        SqlSession session=MybatisUtils.openSession();
        String statement="model.userMapper.selectUser";
        User user=session.selectOne(statement, 1);
        System.out.println(user);
        session.close();
    }
    @Test
    public void testSelectAll() throws IOException {
        SqlSession session=MybatisUtils.openSession();
        String statement="model.userMapper.selectAll";
        List<User> list=session.selectList(statement);
        System.out.println(list);
        session.close();
    }   
    @Test
    public void testInsertUser() throws IOException {
        SqlSession session=MybatisUtils.openSession();
        String statement="model.userMapper.addUser";
        User user=new User();
        user.setName("巨");
        user.setPwd("654321");
        session.insert(statement, user);
        session.commit();
        session.close();
    }
    @Test
    public void testUpdateUser() throws IOException {
        SqlSession session=MybatisUtils.openSession();
        String statement="model.userMapper.updateUser";
        User user=new User();
        user.setId(3);
        user.setName("巨");
        user.setPwd("juligang");
        session.update(statement, user);
        session.commit();
        session.close();
    }
    @Test
    public void testDeleteUser() throws IOException {
        SqlSession session=MybatisUtils.openSession();
        String statement="model.userMapper.deleteUser";
        session.delete(statement, 3);
        session.commit();
        session.close();
    }
}

搭建好的项目最小目录
这里写图片描述
二、通过接口的方式访问增删改查方法
(1)新建一个UserMapper接口,接口中的方法与userMapper.xml中的sql命令标签的id一致。接口类和.xml文件默认在同一个包内,如果不在需要定义.xml的路径。
否则会报:Invalid bound statement (not found)
如:<select id="selectUser" parameterType="int" resultType="model.User">
select * from user where id = #{id}
</select>

id为selectUser,所以接口中的方法名称也是selectUser

package model;

import java.util.List;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

public interface UserMapper {
    public User selectUser(int id);
    public List<User> selectAll();
    public void addUser(User user);
    public void updateUser(User user);
    public void deleteUser(int id);
}

(2)修改mybatis-config.xml配置文件

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE configuration  
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  
  "http://mybatis.org/dtd/mybatis-3-config.dtd">  
<configuration>  
    <properties resource="db.properties"></properties>
    <!-- 对事务的管理和连接池的配置 -->  
    <environments default="development">  
        <environment id="booksystem">  
            <transactionManager type="JDBC" />  
            <dataSource type="POOLED">  
                <property name="driver" value="${db.driver}" />  
                <property name="url" value="${db.url}" />  
                <property name="username" value="${db.user}" />  
                <property name="password" value="${db.password}" />  
            </dataSource>  
        </environment>  
    </environments>  
    <!-- mapping 文件路径配置 -->  
    <mappers>  
         <!—  指明接口的路径 -->
         <mapper class="model.UserMapper"/>
    </mappers>  
   </configuration>

(3)userMapper.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="model.UserMapper">
    <select id="selectUser" parameterType="int" resultType="model.User">
        select * from user where id = #{id}
    </select>
    <select id="selectAll" resultType="model.User">
        select * from user
    </select>
    <insert id="addUser" parameterType="model.User">
        insert into user (name,pwd) values (#{name},#{pwd})
    </insert>
    <update id="updateUser" parameterType="model.User">
        update user set name=#{name},pwd=#{pwd} where id=#{id}
    </update>
    <delete id="deleteUser" parameterType="int">
        delete from user where id=#{id}
    </delete>
</mapper>

(4)新建一个Junit test case类

package test;

import java.io.IOException;
import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import common.MybatisUtils;
import model.User;
import model.UserMapper;

public class MapperTest {

    @Test
    public void testSelectUser() throws IOException {
        SqlSession session=MybatisUtils.openSession();
        UserMapper mapper=session.getMapper(UserMapper.class);
        User user=mapper.selectUser(1);
        session.close();
        System.out.println(user);
    }
    @Test
    public void testSelectAll() throws IOException {
        SqlSession session=MybatisUtils.openSession();
        UserMapper mapper=session.getMapper(UserMapper.class);
        List<User> list=mapper.selectAll();
        session.close();
        System.out.println(list);
    }
    @Test
    public void testInsertUser() throws IOException {
        SqlSession session=MybatisUtils.openSession();
        UserMapper mapper=session.getMapper(UserMapper.class);
        User user=new User();
        user.setName("巨");
        user.setPwd("1234");
        mapper.addUser(user);
        session.commit();
        session.close();
    }
    @Test
    public void testUpdateUser() throws IOException {
        SqlSession session=MybatisUtils.openSession();
        UserMapper mapper=session.getMapper(UserMapper.class);
        User user=new User();
        user.setId(5);
        user.setName("巨");
        user.setPwd("juligang");
        mapper.updateUser(user);
        session.commit();
        session.close();
    }
    @Test
    public void testDeleteUser() throws IOException {
        SqlSession session=MybatisUtils.openSession();
        UserMapper mapper=session.getMapper(UserMapper.class);
        mapper.deleteUser(5);
        session.commit();
        session.close();
    }
}

这样就实现了通过接口访问的形式进行增删改查操作

三、通过注解的方式实现增删改查操作
(1)修改UserMapper接口类

package model;

import java.util.List;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

public interface UserMapper {
    @Select("select * from user where id = #{id}")
    public User selectUser(int id);
    @Select("select * from user")
    public List<User> selectAll();
    @Insert("insert into user (name,pwd) values (#{name},#{pwd})")
    public void addUser(User user);
    @Update("update user set name=#{name},pwd=#{pwd} where id=#{id}")
    public void updateUser(User user);
    @Delete("delete from user where id=#{id}")
    public void deleteUser(int id);
}

(2)mybtis-config.xml文件不用变
(3)修改userMapper.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="model.UserMapper">

</mapper>

说明:这里的配置不能与注解方式冲突,2者只能选其一
(4)利用之前建立的Junit test case类进行测试

package test;

import java.io.IOException;
import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import common.MybatisUtils;
import model.User;
import model.UserMapper;

public class MapperTest {

    @Test
    public void testSelectUser() throws IOException {
        SqlSession session=MybatisUtils.openSession();
        UserMapper mapper=session.getMapper(UserMapper.class);
        User user=mapper.selectUser(1);
        session.close();
        System.out.println(user);
    }
    @Test
    public void testSelectAll() throws IOException {
        SqlSession session=MybatisUtils.openSession();
        UserMapper mapper=session.getMapper(UserMapper.class);
        List<User> list=mapper.selectAll();
        session.close();
        System.out.println(list);
    }
    @Test
    public void testInsertUser() throws IOException {
        SqlSession session=MybatisUtils.openSession();
        UserMapper mapper=session.getMapper(UserMapper.class);
        User user=new User();
        user.setName("巨");
        user.setPwd("1234");
        mapper.addUser(user);
        session.commit();
        session.close();
    }
    @Test
    public void testUpdateUser() throws IOException {
        SqlSession session=MybatisUtils.openSession();
        UserMapper mapper=session.getMapper(UserMapper.class);
        User user=new User();
        user.setId(5);
        user.setName("巨");
        user.setPwd("juligang");
        mapper.updateUser(user);
        session.commit();
        session.close();
    }
    @Test
    public void testDeleteUser() throws IOException {
        SqlSession session=MybatisUtils.openSession();
        UserMapper mapper=session.getMapper(UserMapper.class);
        mapper.deleteUser(5);
        session.commit();
        session.close();
    }
}

四、将SQL命令写入一个专门类中通过注解引入
在上面的基础上稍作修改
(1)新建一个Sqlprovider类

package model;

public class Sqlprovider {
    public String selectUser(){
        return "select * from user where id = #{id}";
    }
    public String selectAll(){
        return "select * from user";
    }
    public String addUser(){
        return "insert into user (name,pwd) values (#{name},#{pwd})";
    }
    public String updateUser(){
        return "update user set name=#{name},pwd=#{pwd} where id=#{id}";
    }
    public String deleteUser(){
        return "delete from user where id=#{id}";
    }
}

(2)修改UserMapper类中的注解

package model;

import java.util.List;

import org.apache.ibatis.annotations.SelectProvider;

public interface UserMapper {
    @SelectProvider(type=Sqlprovider.class,method="selectUser")
    public User selectUser(int id);
    @SelectProvider(type=Sqlprovider.class,method="selectAll")
    public List<User> selectAll();
    @SelectProvider(type=Sqlprovider.class,method="addUser")
    public void addUser(User user);
    @SelectProvider(type=Sqlprovider.class,method="updateUser")
    public void updateUser(User user);
    @SelectProvider(type=Sqlprovider.class,method="deleteUser")
    public void deleteUser(int id);
}

(3)类似于第三章的一样去测试

四、一对一关系的增删改查
(1)在数据库中新建student 和contact数据表
学生表
Student(id,name,sex,pwd,phone,grade,photo)

紧急联系人
Contact(id,name,sex,relation,phone)

两个表的连接关系

在Contact表中增加外键sid,指向Student的主键id
这里写图片描述
学生
id name
1 张三

联系人
id sid name
5 1 李四

外键(foreign key),主键(primary key)

参照完整性约束(外键约束)

外键会自动建立索引,设置该索引为唯一索引,即可实现一对一关联关系

学生-紧急联系人(一对一)

站在学生角度:getContact(),站在联系人角度:getStudent()

学生可以没有联系人,联系人不可能没有对应的学生。

准备工作:

1.建立项目Student&Contact,拷贝mybatis主配置文件,properties文件,MyBatisUtils工具类
2.建立实体类Student和Contact,注意在student类中要把Contact作为属性,反之Contact也要把student作为属性,如果需要测试时打印,需要在类中重写toString方法

Student.java
package model;
public class Student {
    private int id;
    private String name;
    private String sex;
    private String pwd;
    private String phone;
    private String grade;
    private String photo;
    private Contact contact;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    public String getGrade() {
        return grade;
    }
    public void setGrade(String grade) {
        this.grade = grade;
    }
    public String getPhoto() {
        return photo;
    }
    public void setPhoto(String photo) {
        this.photo = photo;
    }
    public Contact getContact() {
        return contact;
    }
    public void setContact(Contact contact) {
        this.contact = contact;
    }
    @Override
    public String toString() {
        return "Student [id=" + id + ", name=" + name + ", sex=" + sex + ", pwd=" + pwd + ", phone=" + phone
                + ", grade=" + grade + ", photo=" + photo + ", contact=" + contact + "]";
    }
}

Contact.java
package model;

public class Contact {
    private int id;
    private String name;
    private String sex;
    private String relation;
    private String phone;
    private Student student;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public String getRelation() {
        return relation;
    }
    public void setRelation(String relation) {
        this.relation = relation;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    public Student getStudent() {
        return student;
    }
    public void setStudent(Student student) {
        this.student = student;
    }
    @Override
    public String toString() {
        return "Contact [id=" + id + ", name=" + name + ", sex=" + sex + ", relation=" + relation + ", phone=" + phone
                + ", student=" + student + "]";
    }
}

3.建立StudentMapper.xml和ContactMapper.xml映射文件模板
StudentMapper.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="mapper.StudentMapper">
<!-- useGeneratedKeys="true" keyProperty="id"在student对象存入数据库之后,会把数据库分配的ID直接返回给student对象 -->
    <insert id="add" parameterType="model.Student" useGeneratedKeys="true" keyProperty="id">
        insert into student 
                        (
                             name,
                              sex,
                              pwd,
                            phone,
                            grade,
                            photo
                        ) 
                values 
                        (
                            #{name},
                            #{sex},
                            #{pwd},
                            #{phone},
                            #{grade},
                            #{photo}
                        )
</insert>
<!—由于返回的student对象中包含了联系人信息,所以要使用resultMap,而不是resulttype -->
    <select id="select" parameterType="int" resultMap="student">
        select 
            s.id sid,
            s.name sname,
            s.sex ssex,
            s.pwd spwd,
            s.phone sphone,
            s.grade sgrade,
            s.photo sphoto,
            c.id cid,
            c.name cname,
            c.sex csex,
            c.relation cralation,
            c.phone cphone
        from 
            student s
        left join
            contact c 
        ON 
            c.sid=s.id
        WHERE
            s.id=#{id}
    </select>
    <!-- 对上面的resultMap做一个说明,注意id要和上面的result名对应 -->
    <resultMap type="model.Student" id="student">
        <id property="id" column="sid"/>
        <result property="name" column="sname"/>
        <result property="sex" column="ssex"/>
        <result property="pwd" column="spwd"/>
        <result property="phone" column="sphone"/>
        <result property="grade" column="sgrade"/>
        <result property="photo" column="sphoto"/>
<!-- 由于student和contact是一对一的关系,所以使用association -->
        <association property="contact" javaType="model.Contact">
            <id property="id" column="cid"/>
            <result property="name" column="cname"/>
            <result property="sex" column="csex"/>
            <result property="relation" column="crelation"/>
            <result property="phone" column="cphone"/>
        </association>
    </resultMap>
    <delete id="delete" parameterType="int">
        delete from student where id=#{id}
    </delete>
    <update id="update1" parameterType="model.Student">
        update student set name=#{name},sex=#{sex} where id=#{id} 
    </update>
</mapper>

ContactMapper.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="mapper.ContactMapper">
    <insert id="add" parameterType="model.Contact">
        insert into contact 
                (
                     name,
                     sex,
                     relation,
                     phone,
                     sid
                 ) 
            values 
                (
                    #{name},
                    #{sex},
                    #{relation},
                    #{phone},
                    #{student.id}
                )
    </insert>
    <select id="select" parameterType="int" resultMap="contact">
        select 
            s.id sid,
            s.name sname,
            s.sex ssex,
            s.pwd spwd,
            s.phone sphone,
            s.grade sgrade,
            s.photo sphoto,
            c.id cid,
            c.name cname,
            c.sex csex,
            c.relation cralation,
            c.phone cphone
        from 
            contact c
        left join
            student s
        on
            c.sid=s.id
        where
            c.id=#{id}
    </select>
    <!-- 对上面的resultMap做一个说明,注意id要和上面的result名对应 -->
    <resultMap type="model.Contact" id="contact">
        <id property="id" column="cid"/>
        <result property="name" column="cname"/>
        <result property="sex" column="csex"/>
        <result property="relation" column="crelation"/>
        <result property="phone" column="cphone"/>
        <association property="student" javaType="model.Student">
            <id property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="sex" column="ssex"/>
            <result property="pwd" column="spwd"/>
            <result property="phone" column="sphone"/>
            <result property="grade" column="sgrade"/>
            <result property="photo" column="sphoto"/>  
        </association>
    </resultMap>
    <delete id="delete" parameterType="int">
        delete from contact where id=#{id}
    </delete>
    <update id="update1" parameterType="model.Contact">
        update contact set name=#{name},sex=#{sex} where id=#{id} 
    </update>
     <update id="update2" parameterType="model.Contact">
        update contact set sid=#{student.id} where id=#{id} 
    </update>
</mapper>

4.建立StudentMapper和ContactMapper接口

StudentMapper.java
package mapper;

import model.Student;

public interface StudentMapper {
    public void add(Student student);
    public Student select(int id);
    public void delete(int id);
    public void update1(Student student);
}


package mapper;

import model.Contact;

public interface ContactMapper {
    public void add(Contact contact);
    public Contact select(int id);
    public void delete(int id);
    //修改非关联字段
    public void update1(Contact contact);
    //修改关联字段
    public void update2(Contact contact);   
}

5.在mybatis-config.xml中添加接口声明

<mapper class="mapper.ContactMapper"/>
<mapper class="mapper.StudentMapper"/>

6.建表student和contact,设定其一对一的对应关系:设置外键为唯一(unique)
这里写图片描述
注:先建立好数据库,设置好映射关系,然后再去操作数据库

以上所有都已经准备好,接下来分别讲述增删改查功能
(1)增加数据
同时保存学生信息和紧急联系人的信息

1.学生信息单独保存。

2.保存联系人信息的时候,指定该联系人对应的学生,实际上指定联系人对应学生的ID。所以学生
信息保存之后,要想办法拿到赋给紧急联系人,否则会报错。

返回插入后生成的自增长属性值的办法,在insert标签上增加

useGeneratedKeys=”true” keyProperty=”id”

当Student对象写入到数据库之后,分配的ID值会立即返回给Student对象
//增加一组学生和联系人

@Test
    public void testInsert() throws IOException {
        SqlSession session=MybatisUtils.openSession();
        StudentMapper sMapper=session.getMapper(StudentMapper.class);
        Student student=new Student();
        student.setName("ccc");
        student.setSex("男");
        student.setPwd("123456");
        student.setPhone("15201916370");
        student.setGrade("一年级");
        sMapper.add(student);
        session.commit();

        ContactMapper cMapper=session.getMapper(ContactMapper.class);
        Contact contact=new Contact();
        contact.setName("ddd");
        contact.setPhone("13636709659");
        contact.setRelation("夫妻");
        contact.setSex("女");
        contact.setStudent(student);
        cMapper.add(contact);
        session.commit();
        session.close();
    }

(2)查询数据
1.StudentMapper中,实现getContact的功能(在Student中,实现getContact的功能)

分析:如果sql语句写成: select * from student where id=#{id}

这样获得的Student对象肯定是得不到联系人信息的。SQL语句中一定要包含联系人信息。

2.ContactMapper中,实现getStudent的功能(在Contact中,实现getStudent的功能)

<select id="select" parameterType="int" resultMap="student">
        select 
            s.id sid,
            s.name sname,
            s.sex ssex,
            s.pwd spwd,
            s.phone sphone,
            s.grade sgrade,
            s.photo sphoto,
            c.id cid,
            c.name cname,
            c.sex csex,
            c.relation cralation,
            c.phone cphone
<!-- 以上的信息会产生一个新表,新表的信息提取自下面的t和c表 -->
        from 
            student s
        left join
            contact c 
<!-- teacher左连接course会以提取teacher信息为主,如果没有course信息也会提取teacher信息 -->
        ON 
            c.sid=s.id
        WHERE
            s.id=#{id}
    </select>
<!-- 对上面的resultMap做一个说明,注意id要和上面的result名对应 -->
    <resultMap type="model.Student" id="student">
        <id property="id" column="sid"/>
        <result property="name" column="sname"/>
        <result property="sex" column="ssex"/>
        <result property="pwd" column="spwd"/>
        <result property="phone" column="sphone"/>
        <result property="grade" column="sgrade"/>
        <result property="photo" column="sphoto"/>
<!-- 由于student和contact是一对一的关系,所以使用association -->
        <association property="contact" javaType="model.Contact">
            <id property="id" column="cid"/>
            <result property="name" column="cname"/>
            <result property="sex" column="csex"/>
            <result property="relation" column="crelation"/>
            <result property="phone" column="cphone"/>
        </association>
    </resultMap>

查询结果:
这里写图片描述

//查询ID为2的学生信息(包含联系人),查询ID为2的联系人信息(包含对应的学生信息)

@Test
    public void testSelect() throws IOException
    {
        SqlSession session=MybatisUtils.openSession();
        StudentMapper sMapper=session.getMapper(StudentMapper.class);
        Student student=sMapper.select(2);
        System.out.println(student);

        ContactMapper cMapper=session.getMapper(ContactMapper.class);
        Contact contact=cMapper.select(2);
        System.out.println(contact);

        session.close();
    }

(3)删除数据
contact表通过sid,与student的id进行关联

sid是否可以为空,决定了是否允许没有对应学生的联系人存在

删除时有以下几种情况

1.删除联系人(从表:包含外键字段的表)

sid可能为空,sid可能是学生表中一个学生的id

2.删除学生(主表:包含主键字段的表)

a.学生没有对应的联系人
可以直接删除

b.学生有对应的联系人,有以下三种情况
外键设置为“删除时”No action
必须先删除与其相关联的联系人后,才能删除该学生

 级联删除
    在数据库中,外键设置为“删除时”cascade
 1)删除学生时,自动删除其联系人(不会通知,比较危险)

    在数据库中,外键设置为“删除时”set null
 2)删除学生时,其联系人的sid都被设置为null。
 如果设置了级联删除,那么可以直接删除该学生,其对应的联系人也会被删除,这种操作比较危险,一般不采用级联删除
@Test
    public void testDelete() throws IOException
    {
        //要删除Student,必须要先删除出其对应的联系人,因为Student被Contact表引用
        SqlSession session=MybatisUtils.openSession();
        //ContactMapper cMapper=session.getMapper(ContactMapper.class);
        //cMapper.delete(1);

        StudentMapper sMapper=session.getMapper(StudentMapper.class);
        sMapper.delete(5);
        session.commit();
        session.close();
    }

(4)修改数据
1.修改从表数据
非关联字段可以随便修改,
关联字段sid必须修改为student表中存在的(而且没有联系人的)学生的id或者修改为null(前提是contact表的sid已经设置为可空)。
2.修改主表数据
非主键字段可以随便修改
主键字段不能随便修改,一般也不需要修改
如果一定要修改,
(1)可以先切断其和关联数据的连接关系(比较麻烦),然后进行修改
(2)另外,还以采用级联更新的方式
主键字段的修改可以采用级联的方式
1)修改主键后,其对应的联系人的sid被设置为空
修改外键的属性“更新时”cascade
2) 修改主键后,其对应的联系人的sid被同时修改。

//修改非关联字段
@Test
    public void testUpdate1() throws IOException
    {
        SqlSession session=MybatisUtils.openSession();
        StudentMapper sMapper=session.getMapper(StudentMapper.class);
        Student student=new Student();
        student.setId(6);
        student.setName("康熙");
        student.setSex("男");
        sMapper.update1(student);

        ContactMapper cMapper=session.getMapper(ContactMapper.class);
        Contact contact=new Contact();
        contact.setId(4);
        contact.setName("华妃");
        contact.setSex("女");
        cMapper.update1(contact);
        session.commit();
        session.close();
    }
//修改关联字段
    @Test
    public void testUpdate2() throws IOException
    {
        SqlSession session=MybatisUtils.openSession();
        StudentMapper sMapper=session.getMapper(StudentMapper.class);
        ContactMapper cMapper=session.getMapper(ContactMapper.class);
        Contact contact=new Contact();
        contact.setId(4);
        contact.setStudent(sMapper.select(6));
        cMapper.update2(contact);
        session.commit();
        session.close();
    }

(5)增加mybatis日志功能

(1)新建log4j.properties文件复制到src目录下

# Global logging configuration  
    log4j.rootLogger=ERROR, stdout  
    # MyBatis logging configuration...  
    log4j.logger.javastudy=DEBUG  
    # Console output...  
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender  
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout  
    log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n 

注意这行代码
log4j.logger.javastudy=DEBUG

(2)加入log4j的jar包
添加到Build path中去

五、一对多的关系
一对多关系

教师-课程:一个教师,可以上多门课程,一门课程只能一个教师上。
站在教师角度:getClasses() 站在课程角度:getTeacher()

外键在多方

课程
course(id,name,type,hours,)
教师
teacher(id,name,sex,phone)

1.建表(和一对一建表完全相同,只是没有设置外键索引的唯一性)
建立teacher和course数据表
2.新建Teacher和Course类

Teacher.java
package model;

import java.util.List;

public class Teacher {
    private int id;
    private String name;
    private String sex;
    private String phone;
//因为一个老师可能对应多个课程,所以课程要定义为一个List
    private List<Course> courses;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    public List<Course> getCourses() {
        return courses;
    }
    public void setCourses(List<Course> courses) {
        this.courses = courses;
    }
    @Override
    public String toString() {
        return "Teacher [id=" + id + ", name=" + name + ", sex=" + sex + ", phone=" + phone + ", courses=" + courses
                + "]";
    }
}

Course.java
package model;

public class Course {
    private int id;
    private String name;
    private String type;
    private String hours;
    private Teacher teacher;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public String getHours() {
        return hours;
    }
    public void setHours(String hours) {
        this.hours = hours;
    }
    public Teacher getTeacher() {
        return teacher;
    }
    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }
    @Override
    public String toString() {
        return "Course [id=" + id + ", name=" + name + ", type=" + type + ", hours=" + hours + ", techer=" + teacher
                + "]";
    }
}

3.新建TeacherMapper和CourseMapper接口

TeacherMapper.Java
package mapper;

import model.Teacher;

public interface TeacherMapper {
    public void add(Teacher teacher);
    public Teacher select(int id);
    public void delete(int id);
    public void update1(Teacher teacher);
}
CourseMapper.java
package mapper;

import model.Course;

public interface CourseMapper {
    public void add(Course course);
    public Course select(int id);
    public void delete(int id);
    public void update(Course course);
}

4.编写TeacherMapper.xml和CourseMapper.xml文件
TeacherMapper.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="mapper.TeacherMapper">
    <insert id="add" parameterType="model.Teacher"  useGeneratedKeys="true" keyProperty="id">
        insert into teacher 
                (
                     name,
                     sex,
                     phone
                 ) 
            values 
                (
                    #{name},
                    #{sex},
                    #{phone}
                )
    </insert>
    <!-- 提取老师要是连课程一起提取,课程是List类型 -->
    <select id="select" parameterType="int" resultMap="teacher">
        select 
            c.id cid,
            c.name cname,
            c.type ctype,
            c.hours chours,
            t.id tid,
            t.name tname,
            t.sex tsex,
            t.phone tphone
        from 
            teacher t
        left join
            course c
        on
            c.tid=t.id
        WHERE
            t.id=#{id}
      </select>
    <!-- 对上面的resultMap做一个说明,注意id要和上面的result名对应 -->
    <resultMap type="model.Teacher" id="teacher">
        <id property="id" column="tid"/>
        <result property="name" column="tname"/>
        <result property="sex" column="tsex"/>
        <result property="phone" column="tphone"/>
        <!-- courses为Course类的属性 -->
        <collection property="courses" ofType="model.Course">
            <id property="id" column="cid"/>
            <result property="name" column="cname"/>
            <result property="type" column="ctype"/>
            <result property="hours" column="chours"/>  
        </collection>
    </resultMap>
    <delete id="delete" parameterType="int">
        delete from teacher where id=#{id}
    </delete>
    <update id="update" parameterType="model.Teacher">
        update teacher set name=#{name},sex=#{sex} where id=#{id} 
    </update>
</mapper>

CourseMapper.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="mapper.CourseMapper">
    <insert id="add" parameterType="model.Course">
        insert into course 
                (
                     name,
                     type,
                     hours,
                     tid
                 ) 
            values 
                (
                    #{name},
                    #{type},
                    #{hours},
                    #{teacher.id}
                )
    </insert>
    <select id="select" parameterType="int" resultMap="course">
        select 
            c.id cid,
            c.name cname,
            c.type ctype,
            c.hours chours,
            t.id tid,
            t.name tname,
            t.sex tsex,
            t.phone tphone
        from 
            course c
        left join
            teacher t
        on
            c.tid=t.id
        WHERE
            c.id=#{id}
    </select>
    <!-- 对上面的resultMap做一个说明,注意id要和上面的result名对应 -->
    <resultMap type="model.Course" id="course">
        <id property="id" column="cid"/>
        <result property="name" column="cname"/>
        <result property="type" column="ctype"/>
        <result property="hours" column="chours"/>
        <association property="teacher" javaType="model.Teacher">
            <id property="id" column="tid"/>
            <result property="name" column="tname"/>
            <result property="sex" column="tsex"/>
            <result property="phone" column="sphone"/>
        </association>
    </resultMap>
    <delete id="delete" parameterType="int">
        delete from course where id=#{id}
    </delete>
    <update id="update" parameterType="model.Course">
        update course set name=#{name},type=#{type} where id=#{id} 
    </update>
</mapper>

5.在mybatis-config.xml文件中添加

<mapper class="mapper.CourseMapper"/>
<mapper class="mapper.TeacherMapper"/>

(1)插入数据
一个老师:谭浩强,男,13901012345

两门课程 C语言入门教程,考查课,30
精通Java基础, 考试课,50

老师单独添加
添加课程的时候,把课程对应的老师添加进去

返回插入后生成的自增长属性值的办法

useGeneratedKeys="true" keyProperty="id"
//插入一名老师和2门课程
@Test
    public void testInsert() throws IOException {
        SqlSession session=MybatisUtils.openSession();
        TeacherMapper tMapper=session.getMapper(TeacherMapper.class);
        Teacher teacher=new Teacher();
        teacher.setName("谭浩强");
        teacher.setSex("男");
        teacher.setPhone("13876548861");
        tMapper.add(teacher);

        CourseMapper cMapper=session.getMapper(CourseMapper.class);
        Course course=new Course();
        course.setName("C语言入门与提高");
        course.setType("必修");
        course.setHours("60");
        course.setTeacher(teacher);
        cMapper.add(course);

        Course course2=new Course();
        course2.setName("精通Java基础");
        course2.setType("选修");
        course2.setHours("30");
        course2.setTeacher(teacher);
        cMapper.add(course2);
        session.commit();
        session.close();
    }

(2)查询数据
比较查询老师信息和课程信息的select语句
A如果查询老师信息,那么左连接时老师的表要放在左边,反之查询课程信息,课程表左连接时放在左边
B老师对应得课程是多个,所以在定义返回值resultMap的时候,课程要使用Collection标签,并且返回类型为javaType
C课程对应的老师只有一个,所以在定义返回值resultMap的时候,老师使用的是association标签,并且返回类型为ofType
//查询ID为15的老师信息和对应的课程信息,以及查询Id为12的课程信息及对应的老师信息

@Test
    public void testSelect() throws IOException
    {
        SqlSession session=MybatisUtils.openSession();
        TeacherMapper tMapper=session.getMapper(TeacherMapper.class);
        Teacher teacher=tMapper.select(15);
        System.out.println(teacher);

        CourseMapper cMapper=session.getMapper(CourseMapper.class);
        Course course=cMapper.select(12);
        System.out.println(course);
        session.close();
    }

六、多对多关系
学生 和 课程

一个学生可以选择多门课程:getCourses()
一门课程,也可以被多个学生选择:getStudents()

学生
Student(id,name,sex,pwd,phone,grade,photo)

课程
Course(id,name,type,hours)

数据库的设计:

中间表
student_course(sid,cid)

数据库表关系
sid cid
2 3
2 3(x)
2 4
13 4

sid和cid的组合不能重复

primary key , 复合主键,联合主键(composite key)

提取学生的时候,要把学生选择的所有课程也提取出来。(三个表的左连接查询,相对比较复杂)

left jion :学生即使没有选择课程,也能把学生的信息提取出来。

from student,course where (=内连接:inner join)
… 如果学生没有选择课程,学生的信息也提取不出来

1、新建student、course和Student_course数据表
Student_course表中的sid和cid要分别设置为student表和course表的外键
2、新建Student、Course和StudentCourse类

Student.java
package model;

import java.util.List;

public class Student {
    private int id;
    private String name;
    private String sex;
    private String pwd;
    private String phone;
    private String grade;
    private String photo;
//多对多的关系中一个学生对应多个课程
    private List<Course> courses;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    public String getGrade() {
        return grade;
    }
    public void setGrade(String grade) {
        this.grade = grade;
    }
    public String getPhoto() {
        return photo;
    }
    public void setPhoto(String photo) {
        this.photo = photo;
    }
    public List<Course> getCourses() {
        return courses;
    }
    public void setCourses(List<Course> courses) {
        this.courses = courses;
    }
    @Override
    public String toString() {
        return "Student [id=" + id + ", name=" + name + ", sex=" + sex + ", pwd=" + pwd + ", phone=" + phone
                + ", grade=" + grade + ", photo=" + photo + ", courses=" + courses + "]";
    }
}

Course.java
package model;

import java.util.List;

public class Course {
    private int id;
    private String name;
    private String type;
    private String hours;
//一个课程也对应多个
    private List<Student> students;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public String getHours() {
        return hours;
    }
    public void setHours(String hours) {
        this.hours = hours;
    }
    public List<Student> getStudents() {
        return students;
    }
    public void setStudents(List<Student> students) {
        this.students = students;
    }
    @Override
    public String toString() {
        return "Course [id=" + id + ", name=" + name + ", type=" + type + ", hours=" + hours + ", students=" + students
                + "]";
    }

}
//建立StudentCourse类用来和student_course表对应
StudentCourse.java
package model;

public class StudentCourse {
    private Student student;
    private Course course;
    public Student getStudent() {
        return student;
    }
    public void setStudent(Student student) {
        this.student = student;
    }
    public Course getCourse() {
        return course;
    }
    public void setCourse(Course course) {
        this.course = course;
    }
}

3、新建StudentMapper、CourseMapper和StudentCourseMapper接口

StudentMapper.java
package mapper;

import model.Student;

public interface StudentMapper {
    public void add(Student student);
    public Student get(int id);
    public Student select(int id);
}
CourseMapper.java
package mapper;

import model.Course;

public interface CourseMapper {
    public void add(Course course);
    public Course get(int id);
    public Course select(int id);
}

StudentCourseMapper.java
package mapper;

import model.StudentCourse;

public interface StudentCourseMapper {
    public void setMap(StudentCourse studentCourse);
}

4、新建StudentMapper.xml、CourseMapper.xml和StudentCourseMapper.xml
StudentMapper.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="mapper.StudentMapper">
    <insert id="add" parameterType="model.Student">
        insert into student 
                        (
                             name,
                              sex,
                              pwd,
                            phone,
                            grade,
                            photo
                        ) 
                values 
                        (
                            #{name},
                            #{sex},
                            #{pwd},
                            #{phone},
                            #{grade},
                            #{photo}
                        )
    </insert>
    <select id="get" parameterType="int" resultType="model.Student">
        select * from student where id=#{id} 
    </select>
    <select id="select" parameterType="int" resultMap="student">
        select
            sid,sname,ssex,spwd,sphone,sgrade,sphoto,
            c.id cid,
            c.name cname,
            c.type ctype,
            c.hours chours 
        from
            (
                select 
                    s.id sid,
                    s.name sname,
                    s.sex ssex,
                    s.pwd spwd,
                    s.phone sphone,
                    s.grade sgrade,
                    s.photo sphoto,
                    sc.cid sccid
                from 
                    student s
                left join 
                    student_course sc
                on 
                    s.id=sc.sid 
            )remp
    left join
            course c
        on
            sccid=c.id
        where
            sid=#{id}
    </select>
    <resultMap type="model.Student" id="student">
        <id property="id" column="sid"/>
        <result property="name" column="sname"/>
        <result property="sex" column="ssex"/>
        <result property="pwd" column="spwd"/>
        <result property="phone" column="sphone"/>
        <result property="grade" column="sgrade"/>
        <result property="photo" column="sphoto"/>
        <collection property="courses" ofType="model.Course">
            <id property="id" column="cid"/>
            <result property="name" column="cname"/>
            <result property="type" column="ctype"/>
            <result property="hours" column="chours"/>
        </collection>   
    </resultMap>
</mapper>

CourseMapper.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="mapper.CourseMapper">
    <insert id="add" parameterType="model.Course">
        insert into course 
                (
                     name,
                     type,
                     hours
                 ) 
            values 
                (
                    #{name},
                    #{type},
                    #{hours}
                )
    </insert>
    <select id="get" parameterType="int" resultType="model.Course">
        select * from course where id=#{id} 
    </select>
    <select id="select" parameterType="int" resultMap="course">
        select 
            c.id cid,
            c.name cname,
            c.type ctype,
            c.hours chours,
            sid,sname,ssex,spwd,sphone,sgrade,sphoto
         from
             course c
        left join
             (
                select
                    s.id sid,
                    s.name sname,
                    s.sex ssex,
                    s.pwd spwd,
                    s.phone sphone,
                    s.grade sgrade,
                    s.photo sphoto,
                    sc.cid sccid
                from
                    student_course sc
                left join
                    student s
                on
                    s.id=sc.sid
               )remp
          on
            c.id=sccid
        where
            c.id=#{id}
    </select>
    <resultMap type="model.Course" id="course">
        <id property="id" column="cid"/>
        <result property="name" column="cname"/>
        <result property="type" column="ctype"/>
        <result property="hours" column="chours"/>
        <collection property="students" ofType="model.Student">
            <id property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="sex" column="ssex"/>
            <result property="pwd" column="spwd"/>
            <result property="phone" column="sphone"/>
            <result property="grade" column="sgrade"/>
            <result property="photo" column="sphoto"/>
        </collection>
    </resultMap>
</mapper>

StudentCourseMapper.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="mapper.StudentCourseMapper">
<insert id="setMap" parameterType="model.StudentCourse">
    insert into student_course (sid,cid) values (#{student.id},#{course.id})
</insert>
</mapper>

5、在mybatis-config.xml文件中增加

<mapper class="mapper.StudentCourseMapper"/>
<mapper class="mapper.StudentMapper"/> 
<mapper class="mapper.CourseMapper"/>

(1)增加数据
//插入2个学生和2门课程

@Test
public void testInsert() throws IOException {
    SqlSession session=MybatisUtils.openSession();
    StudentMapper sMapper=session.getMapper(StudentMapper.class);
    Student student1=new Student();
    student1.setName("刘德华");
    student1.setSex("男");
    student1.setPwd("123456");
    student1.setPhone("15201916370");
    student1.setGrade("二年级");
    sMapper.add(student1);

    Student student2=new Student();
    student2.setName("朱丽倩");
    student2.setSex("女");
    student2.setPwd("123456");
    student2.setPhone("13636709659");
    student2.setGrade("一年级");
    sMapper.add(student2);

    CourseMapper cMapper=session.getMapper(CourseMapper.class);
    Course course1=new Course();
    course1.setName("C语言入门与提高");
    course1.setType("必修");
    course1.setHours("60");
    cMapper.add(course1);

    Course course2=new Course();
    course2.setName("精通Java基础");
    course2.setType("选修");
    course2.setHours("30");
    cMapper.add(course2);
    session.commit();
    session.close();
}

//插入中间表信息,把学生和课程对应起来

@Test
public void testSetMap() throws IOException {
    SqlSession session=MybatisUtils.openSession();
    StudentMapper sMapper=session.getMapper(StudentMapper.class);
    CourseMapper cMapper=session.getMapper(CourseMapper.class);
    StudentCourseMapper scMapper=session.getMapper(StudentCourseMapper.class);

    StudentCourse sc=new StudentCourse();
    sc.setStudent(sMapper.get(9));
    sc.setCourse(cMapper.get(16));
    scMapper.setMap(sc);;

    StudentCourse sc1=new StudentCourse();
    sc1.setStudent(sMapper.get(9));
    sc1.setCourse(cMapper.get(17));
    scMapper.setMap(sc1);;

    StudentCourse sc2=new StudentCourse();
    sc2.setStudent(sMapper.get(10));
    sc2.setCourse(cMapper.get(16));
    scMapper.setMap(sc2);;

    StudentCourse sc3=new StudentCourse();
    sc3.setStudent(sMapper.get(10));
    sc3.setCourse(cMapper.get(17));
    scMapper.setMap(sc3);;

    session.commit();
    session.close();
}

(2)查询数据
//查询学生信息及对应的课程信息

@Test
    public void testSelectStudent() throws IOException {
        SqlSession session=MybatisUtils.openSession();
        StudentMapper sMapper=session.getMapper(StudentMapper.class);
        //CourseMapper cMapper=session.getMapper(CourseMapper.class);
        //StudentCourseMapper scMapper=session.getMapper(StudentCourseMapper.class);
        Student student=sMapper.select(9);
        System.out.println(student);
    }
//查询课程信息及对应的学生信息
    @Test
    public void testSelectCourse() throws IOException {
        SqlSession session=MybatisUtils.openSession();
        //StudentMapper sMapper=session.getMapper(StudentMapper.class);
        CourseMapper cMapper=session.getMapper(CourseMapper.class);
        //StudentCourseMapper scMapper=session.getMapper(StudentCourseMapper.class);
        Course course=cMapper.select(16);
        System.out.println(course);
    }

七、三表左连接的思路

(一) 提取学生信息的时候,能够把学生的所选课程都提取出来

A表-学生表(id,...) B表-学生课程表(sid,cid),C表(id,...)-课程表

(1)前两个表进行左连接,将连接后的结果表,再与后面一个表左连接

 (A - B) - C

(2) 后两个表进行左连接,然后在让第一个表和前面连接后的结果表左连接

 A - (B - C)

A - B 连接的结果

select
            s.id    sid,
            s.name  sname,
            s.sex   ssex,
            s.pwd   spwd,
            s.phone sphone,
            s.grade sgrade,
            s.photo sphoto,
            sc.cid  sccid
        from
            student s left join student_course sc
        on
            s.id=sc.sid

(A - B) - C

select
        sid,sname,ssex,spwd,sphone,sgrade,sphoto,
        c.id    cid,
        c.name  cname,
        c.type  ctype,
        c.hours chours
    from
        (
        select
            s.id    sid,
            s.name  sname,
            s.sex   ssex,
            s.pwd   spwd,
            s.phone sphone,
            s.grade sgrade,
            s.photo sphoto,
            sc.cid  sccid
        from
            student s left join student_course sc
        on
            s.id=sc.sid
        ) temp
        left join 
course c
        on
temp.sccid=c.id 

<!—如果sccid在几个表中没有重复,那么可以把temp.省掉 -->
            where
 sid=#{id}   

(二) 在提取课程信息的时候,能够把选择该课程的学生的信息也提取出来

A - (B - C)

课程表course - (学生课程表 student_course - 学生表student)

B - C 左连接的结果

select
            s.id    sid,
            s.name  sname,
            s.sex   ssex,
            s.pwd   spwd,
            s.phone sphone,
            s.grade sgrade,
            s.photo sphoto,
            sc.cid  sccid           
    from 
        student_course sc
    left join
        student s
    on sc.sid=s.id

A - (B - C)

select
    sid,sname,ssex,spwd,sphone,sgrade,sphoto,
    c.id    cid,
    c.name  cname,
    c.type  ctype,
    c.hours chours
from 
    course c
left join
    (
    select
            s.id    sid,
            s.name  sname,
            s.sex   ssex,
            s.pwd   spwd,
            s.phone sphone,
            s.grade sgrade,
            s.photo sphoto,
            sc.cid  sccid           
    from 
        student_course sc
    left join
        student s
    on sc.sid=s.id
    ) temp
on c.id=temp.sccid
where c.id=#{id}

模型提升:
查询A对象的信息:A( AB B)
查询B对象的信息:B (BA A)
AB(BA)外(键)表可以抽象为各种表之间的链接点
四表左连:
课程 - 学生 - 老师 之间的关系(四表)

course student student_course teacher

从前面课程-学生关系查询的SQL开始

A - (B - C)

select
    sid,sname,ssex,spwd,sphone,sgrade,sphoto,
    c.id    cid,
    c.name  cname,
    c.type  ctype,
    c.hours chours
from 
    course c
left join
    (
    select
            s.id    sid,
            s.name  sname,
            s.sex   ssex,
            s.pwd   spwd,
            s.phone sphone,
            s.grade sgrade,
            s.photo sphoto,
            sc.cid  sccid           
    from 
        student_course sc
    left join
        student s
    on sc.sid=s.id
    ) temp
on c.id=temp.sccid
where c.id=#{id}

(A - B) - (C -D)

select
    cid,cname,ctype,chours,
    tid,tname,tsex,tphone,
    sid,sname,ssex,spwd,sphone,sgrade,sphoto
from 
    (
    select 
      c.id cid,
      c.name cname,
      c.type ctype,
      c.hours chours,
      t.id    tid,
      t.name  tname,
      t.sex   tsex,
      t.phone tphone
    from 
        course c
    left JOIN
      teacher t
    on c.id=t.id
    ) t1
left join
    (
    select
            s.id    sid,
            s.name  sname,
            s.sex   ssex,
            s.pwd   spwd,
            s.phone sphone,
            s.grade sgrade,
            s.photo sphoto,
            sc.cid  sccid           
    from 
        student_course sc
    left join
        student s
    on sc.sid=s.id
    ) t2
on t1.cid=t2.sccid
where t1.cid=3
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

行云的逆袭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值