MyBatis代码实例系列-04:MyBatis多表映射实例(一对多、多对一和多对多)

超级通道:MyBatis代码实例系列-绪论

本章主要记录MyBatis中的多表映射:一对多、多对一和多对多,涉及到的知识点有:
1. resultMap:当数据库方法返回的是复合数据类型(如list等),通常使用resultMap而非resultType
2. collection:在resultMap中用来配置集合类型的数据结构,用来实现表间一对多映射。
3. association:在resultMap中用来配置关联关系的数据结构,用来实现表间多对一以及一对一映射。

1.表间一对多关联映射

实例场景:person(人员表)experience(工作经历表)是一对多关系,即:一个人有多条工作经验,一条工作经验只能属于一个人。
实例目的:通过一个人员的id,查询出此人的人员信息及所有的工作经历信息。

1.1.SQL语句

drop table person;
create table `person`(
    `person_id` int(5) unsigned not null comment '人员id',
    `name` varchar(10) not null comment '姓名',
    `age` int(3) not null comment '年龄',
    primary key(person_id)
)engine=InnoDB comment='人员' auto_increment=1 default charset=utf8;
insert into person values(1,'张三',25);
insert into person values(2,'李四',16);
select * from person;

drop table experience;
create table `experience`(
    `experience_id` int(5) unsigned not null comment '工作经验id',
    `person_id` int(5)  unsigned not null comment '人员id',
    `company` varchar(32) not null comment '公司',
    `position` varchar(16) not null comment '职位',
    primary key(experience_id)
)engine=InnoDB comment='工作经验' auto_increment=1 default charset=utf8;
insert into experience values(1,1,'北京天大地大科技有限公司','开发工程师');
insert into experience values(2,1,'南通考古研究院','考古专家');
insert into experience values(3,1,'海南旅游集团','CEO');
select * from experience;

1.2.目录结构

src
\---main
    \---java
    |   \---pers
    |       \---hanchao
    |           \---himybatis
    |               \---one2many
    |                   \---Person.java
    |                   \---Experience.java
    |                   \---IPersonDAO.java
    |                   \---PersonApp.java
    \---webapp
        \---mybatis-mappers
            \---Person.xml
        \---log4j.properties
        \---mybatis-config.xml

1.3.MyBatis配置mybatis-config.xml

关于mybatis-config.xml的完整配置,可以参考:
MyBatis代码实例系列-04:MyBatis单张表简单实现增删改查 + log4j + 手动事务控制

        <!--一对多实例,通过collection标签进行关联-->
        <typeAlias type="pers.hanchao.himybatis.one2many.Person" alias="Person"/>
        <typeAlias type="pers.hanchao.himybatis.one2many.Experience" alias="Experience"/>

        <!--一对多实例-->
        <mapper resource="mybatis-mappers/Person.xml"/>

1.4.实体类+IDAO+XML

1.4.1.实体类

Person.java

package pers.hanchao.himybatis.one2many;

import java.util.List;

/**
 * <p>人员信息</p>
 * @author hanchao 2018/1/27 14:55
 **/
public class Person {
    /** 人员id */
    private Integer id;
    /** 姓名 */
    private String name;
    /** 年龄 */
    private Integer age;
    /** 教育背景 */
    private List<Experience> experienceList;
    //constructor,toString,setter,getter
}

Experience.java

package pers.hanchao.himybatis.one2many;

/**
 * <p>工作经验</p>
 * @author hanchao 2018/1/27 14:58
 **/
public class Experience {
    /** 工作经验id */
    private Integer id;
    /** 公司名称 */
    private String company;
    /** 职位 */
    private String position;
    //constructor,toString,setter,getter
}

说明:

  1. 一对多实现的关键之一:通过将对象列表作为属性,如private List experienceList;
1.4.2.IDAO

在当前场景中,人员是业务处理的对象,所以Person为操作对象,建立IDAO,即IPersonDAO

package pers.hanchao.himybatis.one2many;

/**
 * <p>人员-工作经历操作DAO层接口</p>
 * @author hanchao 2018/1/27 15:50
 **/
public interface IPersonDAO {
    /** 根据id查询人员信息及工作经验信息 */
    Person queryPersonById(Integer id);
}
1.4.3.XML:Problem.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">
<!--MyBatis的分配置文件,分别对应每个实体,用来配置SQL操作及SQL语句-->
<!--namespace,定义这个映射的命名域,这里指向Dao层接口-->
<mapper namespace="pers.hanchao.himybatis.one2many.IPersonDAO">
    <!--注意这里是resultMap-->
    <select id="queryPersonById" parameterType="Integer" resultMap="personExperienceMap">
        SELECT psn.*,exp.* FROM `person` psn LEFT JOIN `experience` exp ON psn.person_id = exp.person_id WHERE psn.person_id = #{id}
    </select>
    <!--注意上面的返回对象resultMap指向这个id;Person是数据模型,用全路径名是为了防止冲突    -->
    <resultMap id="personExperienceMap" type="pers.hanchao.himybatis.one2many.Person">
        <!--property是对象里的字段名,column是数据库中的字段名-->
        <result property="id" column="person_id"/>
        <result property="name" column="name"/>
        <result property="age" column="age"/>
        <!--ofType是集合元素的类型,column是指外键字段-->
        <collection property="experienceList" ofType="pers.hanchao.himybatis.one2many.Experience" column="person_id">
            <!--id表示主键-->
            <result property="id" column="experience_id"/>
            <result property="company" column="company"/>
            <result property="position" column="position"/>
        </collection>
    </resultMap>
</mapper>

注意:

  1. queryPersonById查询的返回值不是简单的Person类型,而是组合类型personExperienceMap
  2. personExperienceMap类型中由collection属性配置集合类型的元素,以实现1对多的目的。
  3. result标签的property表示的是Java实体中的字段,column表示的是数据库表中的字段。
  4. collection标签的column字段表示外键字段。

1.5.result

2018-01-28 15:52:48 INFO  PersonApp:48 - Person{id=1, name='张三', age=25}
2018-01-28 15:52:48 INFO  PersonApp:76 - Experience{id=1, company='北京天大地大科技有限公司', position='开发工程师'}
2018-01-28 15:52:48 INFO  PersonApp:76 - Experience{id=2, company='南通考古研究院', position='考古专家'}
2018-01-28 15:52:48 INFO  PersonApp:76 - Experience{id=3, company='海南旅游集团', position='CEO'}

2018-01-28 15:52:48 INFO  PersonApp:54 - Person{id=2, name='李四', age=16}
2018-01-28 15:52:48 INFO  PersonApp:73 - 此人无工作经验

2.表间多对一关联映射

实例场景:experience(工作经历表)person(人员表)与是多对一关系,即:一条工作经验只能属于一个人,一个人有多条工作经验。
实例目的:通过一个工作经验的id,查询出此工作经历信息及所属的人员信息。

2.1.SQL语句

drop table person;
create table `person`(
    `person_id` int(5) unsigned not null comment '人员id',
    `name` varchar(10) not null comment '姓名',
    `age` int(3) not null comment '年龄',
    primary key(person_id)
)engine=InnoDB comment='人员' auto_increment=1 default charset=utf8;
insert into person values(1,'张三',25);
insert into person values(2,'李四',16);
select * from person;

drop table experience;
create table `experience`(
    `experience_id` int(5) unsigned not null comment '工作经验id',
    `person_id` int(5)  unsigned not null comment '人员id',
    `company` varchar(32) not null comment '公司',
    `position` varchar(16) not null comment '职位',
    primary key(experience_id)
)engine=InnoDB comment='工作经验' auto_increment=1 default charset=utf8;
insert into experience values(1,1,'北京天大地大科技有限公司','开发工程师');
insert into experience values(2,1,'南通考古研究院','考古专家');
insert into experience values(3,1,'海南旅游集团','CEO');
select * from experience;

2.2.目录结构

src
\---main
    \---java
    |   \---pers
    |       \---hanchao
    |           \---himybatis
    |               \---many2one
    |                   \---Experience.java
    |                   \---Person.java
    |                   \---IExperienceDAO.java
    |                   \---ExperienceApp.java
    \---webapp
        \---mybatis-mappers
            \---Experience.xml
        \---log4j.properties
        \---mybatis-config.xml

2.3.MyBatis配置mybatis-config.xml

关于mybatis-config.xml的完整配置,可以参考:
MyBatis代码实例系列-04:MyBatis单张表简单实现增删改查 + log4j + 手动事务控制

<!--多对一实例-->
<!--many2one包里的Person和Experience没有在这里配置,应为在Experience.xml里直接通过全类名进行的调用,而非别名-->

<!--多对一实例-->
<mapper resource="mybatis-mappers/Experience.xml"/>

2.4.实体类+IDAO+XML

2.4.1.实体类

Experience.java

package pers.hanchao.himybatis.many2one;
/**
 * <p>工作经验</p>
 * @author hanchao 2018/1/27 16:07
 **/
public class Experience {
    /** 工作经验id */
    private Integer id;
    /** 公司名称 */
    private String company;
    /** 职位 */
    private String position;
    /** 所属人员 */
    private Person person;
    //constructor,toString,setter,getter
}

Person.java

package pers.hanchao.himybatis.many2one;

/**
 * <p>人员信息</p>
 * @author hanchao 2018/1/27 16:06
 **/
public class Person {
    /** 人员id */
    private Integer id;
    /** 姓名 */
    private String name;
    /** 年龄 */
    private Integer age;
    //constructor,toString,setter,getter
}

说明:

1. 多对一实现的关键之一:通过将对象作为属性,如private Person person;

2.4.2.IDAO

在当前场景中,工作经历是业务处理的对象,所以Experience为操作对象,建立IDAO,即IExperienceDAO

package pers.hanchao.himybatis.many2one;

/**
 * <p>工作经历-人员DAO层接口</p>
 * @author hanchao 2018/1/27 16:02
 **/
public interface IExperienceDAO {
    /** 根据id查询工作经验及所属人员信息 */
    Experience queryExperienceById(Integer id);
}
2.4.3.XML:Experience.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">
<!--MyBatis的分配置文件,分别对应每个实体,用来配置SQL操作及SQL语句-->
<!--namespace,定义这个映射的命名域,这里指向Dao层接口-->
<mapper namespace="pers.hanchao.himybatis.many2one.IExperienceDAO">

    <select id="queryExperienceById" parameterType="Integer" resultMap="experiencePersonMap">
        SELECT exp.*,psn.* FROM experience exp LEFT JOIN person psn ON exp.person_id = psn.person_id WHERE exp.experience_id = #{id}
    </select>

    <resultMap id="experiencePersonMap" type="pers.hanchao.himybatis.many2one.Experience">
        <result property="id" column="experience_id"/>
        <result property="company" column="company"/>
        <result property="position" column="position"/>
        <association property="person" column="user_id" javaType="pers.hanchao.himybatis.many2one.Person">
            <result property="id" column="person_id"/>
            <!--字段的property和column一致,可以不配置-->
            <!--<result property="name" column="name"/>-->
            <!--<result property="age" column="age"/>-->
        </association>
    </resultMap>
</mapper>

注意:

  1. queryExperienceById查询的返回值不是简单的Experience类型,而是组合类型experiencePersonMap
  2. experiencePersonMap类型中由association属性配置关联关系的实体,以实现多对一的目的。
  3. result标签的property表示的是Java实体中的字段,column表示的是数据库表中的字段。
  4. 字段的property和column一致,可以不配置。
  5. association标签的column字段表示外键字段。

2.5.result

2018-01-28 15:53:47 INFO  ExperienceApp:38 - Experience{id=2, company='南通考古研究院', position='考古专家'}
2018-01-28 15:53:47 INFO  ExperienceApp:39 - Person{id=1, name='张三', age=25}

3.表间多对多关联映射

实例场景:student(学生表)course(选修)与是多对多关系他们通过中间表student_course相关联,即:一个学生可以选修多门选修课,每门选修课可以被多个学生选修。
实例目的:

  1. 通过一个学生的id,查询出此学生的学生信息及所选选修课信息。
  2. 通过一个选修课的id,查询出此选修课的信息及所有选修本课的学生信息。
  3. 添加一个新的学生信息。
  4. 添加一门新的选修课。
  5. 新来的学生选修了新开设的选修课。

3.1.SQL语句

drop table student;
create table `student`(
    `student_id` int(4) unsigned not null comment '学生id',
    `name` varchar(10) not null comment '姓名',
    `number` varchar(3) not null comment '学号',
    primary key(student_id)
)engine=InnoDB comment='学生' auto_increment=1 default charset=utf8;
insert into student values(1,'张三','003');
insert into student values(2,'李四','004');
insert into student values(3,'王五','005');
select * from student;

drop table course;
create table `course`(
    `course_id` int(5) unsigned not null comment '选修课id',
    `name` varchar(10)  not null comment '课程名',
    `score` int(1) unsigned not null comment '学分',
    primary key(course_id)
)engine=InnoDB comment='选修课' default charset=utf8;
insert into course values(1,'Java开发',2);
insert into course values(2,'国家地理',1);
insert into course values(3,'十级英语',2);
insert into course values(4,'高等数学',3);
insert into course values(5,'国语',1);
select * from course;

drop table student_course;
create table `student_course`(
    `student_id` int(4) unsigned not null comment '学生id',
    `course_id` int(4) unsigned not null comment '选修课id',
    primary key(student_id,course_id)
)engine = InnoDB comment='学生选修课中间表' charset=utf8;
insert into student_course values(1,1);
insert into student_course values(1,3);
insert into student_course values(1,5);

insert into student_course values(2,2);
insert into student_course values(2,4);

insert into student_course values(3,1);
insert into student_course values(3,2);
insert into student_course values(3,3);
insert into student_course values(3,4);
insert into student_course values(3,5);
select * from student_course;

注意:多对多最好是使用这种单表+中间表+单表的数据结构

3.2.目录结构

src
\---main
    \---java
    |   \---pers
    |       \---hanchao
    |           \---himybatis
    |               \---many2many
    |                   \---Student.java
    |                   \---Course.java
    |                   \---StudentCourse.java
    |                   \---IStudentDAO.java
    |                   \---ICourseDAO.java
    |                   \---IStudentCourseDAO.java
    |                   \---Many2manyApp.java
    \---webapp
        \---mybatis-mappers
            \---Student.xml
            \---Course.xml
            \---StudentCourse.xml
        \---log4j.properties
        \---mybatis-config.xml

3.3.MyBatis配置mybatis-config.xml

关于mybatis-config.xml的完整配置,可以参考:
MyBatis代码实例系列-04:MyBatis单张表简单实现增删改查 + log4j + 手动事务控制

<!--多对多实例-->
<typeAlias type="pers.hanchao.himybatis.many2many.Student" alias="Student"/>
<typeAlias type="pers.hanchao.himybatis.many2many.Course" alias="Course"/>
<typeAlias type="pers.hanchao.himybatis.many2many.StudentCourse" alias="StudentCourse"/>

<!--多对多实例-->
<mapper resource="mybatis-mappers/Student.xml"/>
<mapper resource="mybatis-mappers/Course.xml"/>
<mapper resource="mybatis-mappers/StudentCourse.xml"/>

3.4.实体类+IDAO+XML

3.4.1.实体类

单表Student.java

package pers.hanchao.himybatis.many2many;

import java.util.List;

/**
 * <p>学生信息表</p>
 * @author hanchao 2018/1/27 16:54
 **/
public class Student {
    /** 学生id */
    private Integer id;
    /** 姓名 */
    private String name;
    /** 学号 */
    private String number;
    /** 所有选修课 */
    private List<Course> courseList;
    //constructor,toString,setter,getter
}

单表Course.java

package pers.hanchao.himybatis.many2many;

import java.util.List;

/**
 * <p>选课表</p>
 * @author hanchao 2018/1/27 16:55
 **/
public class Course {
    /** 选课id */
    private Integer id;
    /** 课程名称 */
    private String name;
    /** 学分 */
    private Integer score;
    /** 选择本课程的学生 */
    private List<Student> studentList;
    //constructor,toString,setter,getter
}

中间表StudentCourse.java

package pers.hanchao.himybatis.many2many;

/**
 * <p>学生选修课中间表</p>
 * @author hanchao 2018/1/27 16:59
 **/
public class StudentCourse {
    private Integer studentId;
    private Integer courseId;
    //constructor,toString,setter,getter
}

注意:

  1. 对单表Student和Course,都需要以对方的对象列表作为属性如private List courseList;和private List studentList;
3.4.2.IDAO

在当前场景中,学生和课程可以作为业务对象。所以分别以StudentCourse为操作对象,建立IDAO,即IStudentDAOICourseDAO

IStudentDAO.java

package pers.hanchao.himybatis.many2many;

/**
 * <p>学生DAO</p>
 * @author hanchao 2018/1/27 17:06
 **/
public interface IStudentDAO {
    /** 新增一个学生 */
    void insertStudent(Student student);
    /** 根据id查询一个学生的信息 */
    Student queryStudentById(Integer id);
}

ICourseDAO.java

package pers.hanchao.himybatis.many2many;

/**
 * <p>选修课DAO</p>
 * @author hanchao 2018/1/27 17:03
 **/
public interface ICourseDAO {
    /** 新增一门课程 */
    void insertCourse(Course course);
    /** 根据id查询一门课程 */
    Course queryCourseById(Integer id);
}

IStudentCourseDAO.java

package pers.hanchao.himybatis.many2many;

/**
 * <p>学生选课DAO</p>
 * @author hanchao 2018/1/27 17:08
 **/
public interface IStudentCourseDAO {
    /** 插入一条学生选课信息 */
    void insertStudentCourse(StudentCourse studentCourse);
    /**  */
    Student queryStudentByCourseId(Integer id);
    /**  */
    Course queryCourseByStudentId(Integer id);
}
3.4.3.XML

Student.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">
<!--MyBatis的分配置文件,分别对应每个实体,用来配置SQL操作及SQL语句-->
<!--namespace,定义这个映射的命名域,这里指向Dao层接口-->
<mapper namespace="pers.hanchao.himybatis.many2many.IStudentDAO">
    <!--新增学生信息-->
    <insert id="insertStudent" parameterType="Student">
        INSERT INTO `student`(student_id,name,number) VALUES (#{id},#{name},#{number})
    </insert>
    <!--查询学生信息-->
    <select id="queryStudentById" parameterType="Integer" resultMap="studentCourseMap">
        SELECT * FROM `student` WHERE student_id = #{id}
    </select>
    <resultMap id="studentCourseMap" type="Student">
        <result property="id" column="student_id"/>
        <!--property与column相同的没必要配置-->
        <!--<result property="name" column="name"/>-->
        <!--<result property="number" column="number"/>-->
        <!--这里是1对多关系,这里的Column是在queryCourseByStudentId里的查询列-->
        <collection property="courseList" column="student_id"
                    select="pers.hanchao.himybatis.many2many.IStudentCourseDAO.queryCourseByStudentId"/>
    </resultMap>
</mapper>

Course.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">
<!--MyBatis的分配置文件,分别对应每个实体,用来配置SQL操作及SQL语句-->
<!--namespace,定义这个映射的命名域,这里指向Dao层接口-->
<mapper namespace="pers.hanchao.himybatis.many2many.ICourseDAO">
    <!--插入新的选修课-->
    <insert id="insertCourse" parameterType="Course">
        INSERT INTO `course`(course_id,name,score) VALUES (#{id},#{name},#{score})
    </insert>
    <!--根据id查询选修课新-->
    <select id="queryCourseById" parameterType="Integer" resultMap="courseStudentMap">
        SELECT * FROM `course` WHERE course_id = #{id}
    </select>
    <resultMap id="courseStudentMap" type="Course">
        <!--property:Java中的字段,column:表中的字段-->
        <result property="id" column="course_id"/>
        <!--property与column相同的没必要配置-->
        <!--<result property="name" column="name"/>-->
        <!--<result property="score" column="score"/>-->
        <!--这里是1对多关系,这里的Column是在queryStudentByCourseId里的查询列-->
        <collection property="studentList" column="course_id"
                    select="pers.hanchao.himybatis.many2many.IStudentCourseDAO.queryStudentByCourseId"/>
    </resultMap>
</mapper>

StudentCourse.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">
<!--MyBatis的分配置文件,分别对应每个实体,用来配置SQL操作及SQL语句-->
<!--namespace,定义这个映射的命名域,这里指向Dao层接口-->
<mapper namespace="pers.hanchao.himybatis.many2many.IStudentCourseDAO">
    <!--新增一条选修记录-->
    <insert id="insertStudentCourse" parameterType="StudentCourse">
        INSERT INTO `student_course`(student_id,course_id) VALUES (#{studentId},#{courseId})
    </insert>

    <!--根据学生id,查询这个学生所有的选修课信息-->
    <select id="queryCourseByStudentId" resultMap="courseByStudentIdMap" parameterType="Integer">
        SELECT cos.*,sc.course_id
        FROM `course` cos,`student_course` sc
        WHERE cos.course_id = sc.course_id
        AND sc.student_id = #{student_id}
    </select>
    <resultMap id="courseByStudentIdMap" type="Course">
        <result property="id" column="course_id"/>
        <!--property与column相同的没必要配置-->
        <!--<result property="name" column="name"/>-->
        <!--<result property="score" column="score"/>-->
    </resultMap>

    <!--根据选修课id,查询选修此选修课的所有学生信息-->
    <select id="queryStudentByCourseId" resultMap="studentByCourseMap" parameterType="Integer">
        SELECT std.*,sc.student_id
        FROM `student` std,`student_course` sc
        WHERE std.student_id = sc.student_id
        AND sc.course_id = #{course_id}
    </select>
    <resultMap id="studentByCourseMap" type="Student">
        <result property="id" column="student_id"/>
        <!--property与column相同的没必要配置-->
        <!--<result property="name" column="name"/>-->
        <!--<result property="number" column="number"/>-->
    </resultMap>
</mapper>

说明:

  1. StudentCourse的一对多关系,实际上是通过中间表student_course转化成了两个1对多关系,即一个student对应多个student_course以及一个Course对应多个student_course。所以,多对多映射实际上是两个一对多映射的组合。
  2. 一对多查询的返回值不是简单的实体类型,而是组合类型,如studentCourseMapcourseStudentMap等。
  3. resultMap类型中由collection属性配置集合类型的元素,以实现1对多的目的。
  4. result标签的property表示的是Java实体中的字段,column表示的是数据库表中的字段。
  5. 字段的propertycolumn一致,可以不配置。
  6. collection标签的column字段表示外键字段。
  7. collection标签的select字段表示的是映射到中间表中的方法。

3.5.result

2018-01-28 15:54:11 INFO  Many2manyApp:40 - =========查询学生id=1的所有选修课
2018-01-28 15:54:11 INFO  Many2manyApp:43 - Student{id=1, name='张三', number='003'}
2018-01-28 15:54:11 INFO  Many2manyApp:109 - Course{id=1, name='Java开发', score=2}
2018-01-28 15:54:11 INFO  Many2manyApp:109 - Course{id=3, name='十级英语', score=2}
2018-01-28 15:54:11 INFO  Many2manyApp:109 - Course{id=5, name='国语', score=1}

2018-01-28 15:54:11 INFO  Many2manyApp:48 - =========查询选修课id=1的所有学生
2018-01-28 15:54:11 INFO  Many2manyApp:51 - Course{id=1, name='Java开发', score=2}
2018-01-28 15:54:11 INFO  Many2manyApp:109 - Student{id=1, name='张三', number='003'}
2018-01-28 15:54:11 INFO  Many2manyApp:109 - Student{id=3, name='王五', number='005'}

2018-01-28 15:54:11 INFO  Many2manyApp:56 - =========新增一个学生:陈六
2018-01-28 15:54:11 INFO  Many2manyApp:59 - Student{id=4, name='陈六', number='006'}

2018-01-28 15:54:11 INFO  Many2manyApp:63 - =========新增一门课程:玄学
2018-01-28 15:54:11 INFO  Many2manyApp:66 - Course{id=6, name='玄学', score=3}

2018-01-28 15:54:11 INFO  Many2manyApp:70 - =========新学生 陈六 选修了新选修课 玄学
2018-01-28 15:54:11 INFO  Many2manyApp:74 - StudentCourse{studentId=4, courseId=6}

2018-01-28 15:54:11 INFO  Many2manyApp:78 - =========查询陈六选修的课程
2018-01-28 15:54:11 INFO  Many2manyApp:80 - Student{id=4, name='陈六', number='006'}
2018-01-28 15:54:11 INFO  Many2manyApp:109 - Course{id=6, name='玄学', score=3}

2018-01-28 15:54:11 INFO  Many2manyApp:85 - =========查询选修玄学的所有学生
2018-01-28 15:54:11 INFO  Many2manyApp:87 - Course{id=6, name='玄学', score=3}
2018-01-28 15:54:11 INFO  Many2manyApp:109 - Student{id=4, name='陈六', number='006'}
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值