• 今日学习 Mybatis 的关联映射


    关联映射的三种关系:

    我们首先绘制一个简化的 E-R 图来表示三种关联关系。

    上图表示的三种关系:

    • 一对一:一个班主任只属于一个班级,一个班级也只能有一个班主任
    • 一对多:一个班级有多个学生,一个学生只属于一个班级
    • 多对多:一个学生可以选多门课,一门课可以有多个学生选

    一对一关联映射

    新建一个数据库并取名 mybatis,在数据库里创建班主任表 tb_head_teacher 并插入一条数据,创建班级表 tb_class 并插入一条数据。

    创建项目OneToOne。

    项目文件结构如图

    具体步骤如下:

    src/main/java 的包 shiyanlou.mybatis.onetoone.model 下新建类 HeadTeacher.java,一个班主任具有 id、name、age 属性。HeadTeacher.java 的代码如下:

    1. package shiyanlou.mybatis.onetoone.model;
    2. public class HeadTeacher {
    3. private Integer id;
    4. private String name;
    5. private Integer age;
    6. public HeadTeacher() {
    7. }
    8. public HeadTeacher(Integer id, String name, Integer age) {
    9. this.id = id;
    10. this.name = name;
    11. this.age = age;
    12. }
    13. public Integer getId() {
    14. return id;
    15. }
    16. public void setId(Integer id) {
    17. this.id = id;
    18. }
    19. public String getName() {
    20. return name;
    21. }
    22. public void setName(String name) {
    23. this.name = name;
    24. }
    25. public Integer getAge() {
    26. return age;
    27. }
    28. public void setAge(Integer age) {
    29. this.age = age;
    30. }
    31. }

    再在包 shiyanlou.mybatis.onetoone.model 下新建类 Classes.java,一个班级有 id,name,teacher(HeadTeacher teacher)属性。teacher 属性用来映射一对一的关联关系,表示这个班级的班主任。Classes.java 的代码如下:

    1. package shiyanlou.mybatis.onetoone.model;
    2. public class Classes {
    3. private Integer id;
    4. private String name;
    5. private HeadTeacher teacher;
    6. public Classes() {
    7. }
    8. public Classes(Integer id, String name, HeadTeacher teacher) {
    9. this.id = id;
    10. this.name = name;
    11. this.teacher = teacher;
    12. }
    13. public Integer getId() {
    14. return id;
    15. }
    16. public void setId(Integer id) {
    17. this.id = id;
    18. }
    19. public String getName() {
    20. return name;
    21. }
    22. public void setName(String name) {
    23. this.name = name;
    24. }
    25. public HeadTeacher getTeacher() {
    26. return teacher;
    27. }
    28. public void setTeacher(HeadTeacher teacher) {
    29. this.teacher = teacher;
    30. }
    31. }

    新建包 shiyanlou.mybatis.onetoone.mapper ,并在包下新建方法接口 ClassesMapper.java。

    ClassesMapper 接口的代码如下:

    1. package shiyanlou.mybatis.onetoone.mapper;
    2. import shiyanlou.mybatis.onetoone.model.Classes;
    3. public interface ClassesMapper {
    4. /*
    5. * 根据 id 查询班级 Classes
    6. * @param id
    7. * @return
    8. * @throws Exception
    9. */
    10. public Classes selectClassById(Integer id) throws Exception;
    11. }

    在包 shiyanlou.mybatis.onetoone.mapper 下新建映射文件 ClassesMapper.xml ,映射文件与接口名相同。

    ClassesMapper.xml 的配置如下:

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    3. <mapper namespace="shiyanlou.mybatis.onetoone.mapper.ClassesMapper">
    4. <select id="selectClassById" parameterType="int" resultMap="classmap">
    5. select * from tb_class c, tb_head_teacher t where c.c_ht_id = t.ht_id and c.c_id=#{id}
    6. </select>
    7. <!-- resultMap: 映射实体类和字段之间的一一对应的关系 -->
    8. <resultMap id="classmap" type="Classes">
    9. <id property="id" column="c_id" />
    10. <result property="name" column="c_name" />
    11. <!-- 一对一关联映射:association -->
    12. <association property="teacher" javaType="HeadTeacher">
    13. <id property="id" column="ht_id" />
    14. <result property="name" column="ht_name" />
    15. <result property="age" column="ht_age" />
    16. </association>
    17. </resultMap>
    18. </mapper>

    在这里,采用的是关联的嵌套结果映射的方式,使用了  元素映射一对一的关联关系。

    如果想要 HeadTeacher 的结果映射可以重用,我们可以采用下面的方式,先定义 HeadTeacher 的 resultMap:

    1. <resultMap id="teachermap" type="HeadTeacher">
    2. <id property="id" column="ht_id"/>
    3. <result property="name" column="ht_name" />
    4. <result property="age" column="ht_age" />
    5. </resultMap>
    6. <resultMap id="classmap" type="Classes">
    7. <id property="id" column="c_id" />
    8. <result property="name" column="c_name" />
    9. <!-- 一对一关联映射:association -->
    10. <association property="teacher" column="c_ht_id" javaType="HeadTeacher" resultMap="teachermap" />
    11. </resultMap>

    在项目目录 src/main/resources 下新建 MyBatis 配置文件 mybatis.cfg.xml ,用来配置 Mybatis 的运行环境、数据源、事务等。

    mybatis.cfg.xml 的配置如下,具体解释注释已经给出:

    1. "1.0" encoding="UTF-8"?>
    2. configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
    3. <configuration>
    4. <typeAliases>
    5. <package name="shiyanlou.mybatis.onetoone.model" />
    6. typeAliases>
    7. <environments default="development">
    8. <environment id="development">
    9. <transactionManager type="JDBC" />
    10. <dataSource type="POOLED">
    11. <property name="driver" value="com.mysql.jdbc.Driver" />
    12. <property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
    13. <property name="username" value="root" />
    14. <property name="password" value="" />
    15. dataSource>
    16. environment>
    17. environments>
    18. <mappers>
    19. <package name="shiyanlou.mybatis.onetoone.mapper" />
    20. mappers>
    21. configuration>

    使用日志文件是为了查看控制台输出的 SQL 语句。

    在项目目录 src/main/resources 下新建 MyBatis 日志记录文件 log4j.properties ,在里面添加如下内容:

    1. # Global logging configuration
    2. log4j.rootLogger=DEBUG, stdout
    3. # Console output...
    4. log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    5. log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    6. log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

    在包 shiyanlou.mybatis.onetoone.test 下新建测试类 Test.java ,代码如下:

    1. package shiyanlou.mybatis.onetoone.test;
    2. import java.io.IOException;
    3. import java.io.InputStream;
    4. import org.apache.ibatis.io.Resources;
    5. import org.apache.ibatis.session.SqlSession;
    6. import org.apache.ibatis.session.SqlSessionFactory;
    7. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    8. import shiyanlou.mybatis.onetoone.mapper.ClassesMapper;
    9. import shiyanlou.mybatis.onetoone.model.Classes;
    10. public class Test {
    11. private static SqlSessionFactory sqlSessionFactory;
    12. public static void main(String[] args) {
    13. // Mybatis 配置文件
    14. String resource = "mybatis.cfg.xml";
    15. // 得到配置文件流
    16. InputStream inputStream = null;
    17. try {
    18. inputStream = Resources.getResourceAsStream(resource);
    19. } catch (IOException e) {
    20. e.printStackTrace();
    21. }
    22. // 创建会话工厂,传入 MyBatis 的配置文件信息
    23. sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    24. // 通过工厂得到 SqlSession
    25. SqlSession session = sqlSessionFactory.openSession();
    26. ClassesMapper mapper = session.getMapper(ClassesMapper.class);
    27. try {
    28. Classes classes = mapper.selectClassById(1);
    29. session.commit();
    30. System.out.println(classes.getId() + "," + classes.getName() + ",["
    31. + classes.getTeacher().getId() + ","
    32. + classes.getTeacher().getName() + ","
    33. + classes.getTeacher().getAge()+"]");
    34. } catch (Exception e) {
    35. e.printStackTrace();
    36. session.rollback();
    37. }
    38. // 释放资源
    39. session.close();
    40. }
    41. }

    运行测试类 Test.java, 查询 对应班级的所有信息及其班主任的信息,得到的输出信息与数据库中的数据一致。

    一对多关联映射

    项目文件结构

    打开数据库,新建一个数据库并取名 mybatis,创建班级表 tb_class 并插入数据,创建学生表 tb_student 并插入数据。

    新建项目 OneToMany。

    src/main/java 的包 shiyanlou.mybatis.onetomany.model 下新建类 Student.java,一个学生具有 id、name、sex、age 属性。Student.java 的代码如下:

    1. package shiyanlou.mybatis.onetomany.model;
    2. public class Student {
    3. private Integer id;
    4. private String name;
    5. private String sex;
    6. private Integer age;
    7. public Student() {
    8. }
    9. public Student(Integer id, String name, String sex, Integer age) {
    10. this.id = id;
    11. this.name = name;
    12. this.sex = sex;
    13. this.age = age;
    14. }
    15. public Integer getId() {
    16. return id;
    17. }
    18. public void setId(Integer id) {
    19. this.id = id;
    20. }
    21. public String getName() {
    22. return name;
    23. }
    24. public void setName(String name) {
    25. this.name = name;
    26. }
    27. public String getSex() {
    28. return sex;
    29. }
    30. public void setSex(String sex) {
    31. this.sex = sex;
    32. }
    33. public Integer getAge() {
    34. return age;
    35. }
    36. public void setAge(Integer age) {
    37. this.age = age;
    38. }
    39. }

    再在包 shiyanlou.mybatis.onetomany.model 下新建类 Classes.java,一个班级有 id,name,students 属性。List students 用来表示一对多的关系,一个班级可以有多个学生。students 是一个 List 集合。Classes.java 的代码如下:

    1. package shiyanlou.mybatis.onetomany.model;
    2. import java.util.List;
    3. public class Classes {
    4. private Integer id;
    5. private String name;
    6. // 班级和学生是一对多的关系,即一个班级可以有多个学生
    7. private List<Student> students;
    8. public Classes() {
    9. }
    10. public Classes(Integer id, String name, List<Student> students) {
    11. this.id = id;
    12. this.name = name;
    13. this.students = students;
    14. }
    15. public Integer getId() {
    16. return id;
    17. }
    18. public void setId(Integer id) {
    19. this.id = id;
    20. }
    21. public String getName() {
    22. return name;
    23. }
    24. public void setName(String name) {
    25. this.name = name;
    26. }
    27. public List<Student> getStudents() {
    28. return students;
    29. }
    30. public void setStudents(List students) {
    31. this.students = students;
    32. }
    33. }

    新建包 shiyanlou.mybatis.onetomany.mapper ,并在包下新建方法接口 ClassesMapper.java。

    ClassesMapper 接口的代码如下:

    1. package shiyanlou.mybatis.onetomany.mapper;
    2. import shiyanlou.mybatis.onetomany.model.Classes;
    3. public interface ClassesMapper {
    4. /*
    5. * 根据 id 查询班级 Classes 和它的学生
    6. * @param id
    7. * @return
    8. * @throws Exception
    9. */
    10. public Classes selectClassAndStudentsById(Integer id) throws Exception;
    11. }

    在包 shiyanlou.mybatis.onetomany.mapper 下新建映射文件 ClassesMapper.xml ,映射文件与接口名相同。

    ClassesMapper.xml 的配置如下:

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    3. <mapper namespace="shiyanlou.mybatis.onetomany.mapper.ClassesMapper">
    4. <select id="selectClassAndStudentsById" parameterType="int" resultMap="classmap">
    5. select c.c_id,c.c_name,s.s_id,s.s_name,s.s_sex,s.s_age from tb_class c left outer join tb_student s on c.c_id = s.s_c_id where c.c_id=#{id}
    6. </select>
    7. <!-- resultMap: 映射实体类和字段之间的一一对应的关系 -->
    8. <resultMap id="classmap" type="Classes">
    9. <id property="id" column="c_id" />
    10. <result property="name" column="c_name" />
    11. <!-- 一对多关联映射:collection -->
    12. <collection property="students" ofType="Student">
    13. <id property="id" column="s_id" />
    14. <result property="name" column="s_name" />
    15. <result property="sex" column="s_sex" />
    16. <result property="age" column="s_age" />
    17. </collection>
    18. </resultMap>
    19. </mapper>

    在这里,采用的是集合的嵌套结果映射的方式,使用了  元素映射一对多的关联关系。

    如果想要 Student 的结果映射可以重用,我们可以定义一个 Student 类型的 resultMap,再在  中用 resultMap= 引用,同一对一关联映射的 

    在项目目录 src/main/resources 下新建 MyBatis 配置文件 mybatis.cfg.xml ,用来配置 Mybatis 的运行环境、数据源、事务等。

    mybatis.cfg.xml 的配置如下,具体解释注释已经给出:

    1. "1.0" encoding="UTF-8"?>
    2. configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
    3. <configuration>
    4. <typeAliases>
    5. <package name="shiyanlou.mybatis.onetomany.model" />
    6. typeAliases>
    7. <environments default="development">
    8. <environment id="development">
    9. <transactionManager type="JDBC" />
    10. <dataSource type="POOLED">
    11. <property name="driver" value="com.mysql.jdbc.Driver" />
    12. <property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
    13. <property name="username" value="root" />
    14. <property name="password" value="" />
    15. dataSource>
    16. environment>
    17. environments>
    18. <mappers>
    19. <package name="shiyanlou.mybatis.onetomany.mapper" />
    20. mappers>
    21. configuration>

    使用日志文件是为了查看控制台输出的 SQL 语句。

    在项目目录 src/main/resources 下新建 MyBatis 日志记录文件 log4j.properties ,在里面添加如下内容:

    1. # Global logging configuration
    2. log4j.rootLogger=DEBUG, stdout
    3. # Console output...
    4. log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    5. log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    6. log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

    在包 shiyanlou.mybatis.onetomany.test 下新建测试类 Test.java ,代码如下:

    1. package shiyanlou.mybatis.onetomany.test;
    2. import java.io.IOException;
    3. import java.io.InputStream;
    4. import org.apache.ibatis.io.Resources;
    5. import org.apache.ibatis.session.SqlSession;
    6. import org.apache.ibatis.session.SqlSessionFactory;
    7. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    8. import java.util.List;
    9. import shiyanlou.mybatis.onetomany.mapper.ClassesMapper;
    10. import shiyanlou.mybatis.onetomany.model.Classes;
    11. import shiyanlou.mybatis.onetomany.model.Student;
    12. public class Test {
    13. private static SqlSessionFactory sqlSessionFactory;
    14. public static void main(String[] args) {
    15. // Mybatis 配置文件
    16. String resource = "mybatis.cfg.xml";
    17. // 得到配置文件流
    18. InputStream inputStream = null;
    19. try {
    20. inputStream = Resources.getResourceAsStream(resource);
    21. } catch (IOException e) {
    22. e.printStackTrace();
    23. }
    24. // 创建会话工厂,传入 MyBatis 的配置文件信息
    25. sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    26. // 通过工厂得到 SqlSession
    27. SqlSession session = sqlSessionFactory.openSession();
    28. ClassesMapper mapper = session.getMapper(ClassesMapper.class);
    29. try {
    30. Classes classes = mapper.selectClassAndStudentsById(1);
    31. session.commit();
    32. System.out.println("班级信息:"+classes.getId()+","+classes.getName());
    33. List<Student> students = classes.getStudents();
    34. System.out.println("班级的所有学生信息:");
    35. for(Student stu:students){
    36. System.out.println(stu.getId()+","+stu.getName()+","+stu.getSex()+","+stu.getAge());
    37. }
    38. } catch (Exception e) {
    39. e.printStackTrace();
    40. session.rollback();
    41. }
    42. // 释放资源
    43. session.close();
    44. }
    45. }

    运行测试类 Test.java,查询 对应id 的班级的所有信息及其班主任的信息。

    多对一的实现和一对一的方式一样。

    多对多关联映射

    项目文件结构

    新建一个数据库并取名 mybatis,创建学生表 tb_student 并插入数据

    1. create table tb_student(
    2. s_id int primary key auto_increment,
    3. s_name varchar(20),
    4. s_sex varchar(10),
    5. s_age int);
    6. insert into tb_student(s_name,s_sex,s_age) values('Tom','male',18);
    7. insert into tb_student(s_name,s_sex,s_age) values('Jack','male',19);

    创建课程表 tb_course 并插入数据

    1. create table tb_course(
    2. c_id int primary key auto_increment,
    3. c_name varchar(20),
    4. c_credit int);
    5. insert into tb_course(c_name,c_credit) values('Math',5);
    6. insert into tb_course(c_name,c_credit) values('Computer',4);

    由于学生和课程是多对多的关联关系,因此创建中间表:选课表 tb_select_course 并插入数据

    1. create table tb_select_course(
    2. sc_s_id int,
    3. sc_c_id int,
    4. sc_date date,
    5. primary key(sc_s_id,sc_c_id),
    6. foreign key(sc_s_id) references tb_student(s_id),
    7. foreign key(sc_c_id) references tb_course(c_id));
    8. insert into tb_select_course(sc_s_id,sc_c_id,sc_date) values(1,1,'2017-03-01');
    9. insert into tb_select_course(sc_s_id,sc_c_id,sc_date) values(1,2,'2017-03-01');
    10. insert into tb_select_course(sc_s_id,sc_c_id,sc_date) values(2,1,'2017-03-02');
    11. insert into tb_select_course(sc_s_id,sc_c_id,sc_date) values(2,2,'2017-03-02');

    新建项目 ManyToMany。

    导入所需 jar 包,打开 pom.xml,修改为以下内容(前两个没加,感觉没必要,如果需要,就看这样照着改一下)

    1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    3. <modelVersion>4.0.0</modelVersion>
    4. <groupId>shiyanlou.mybatis.manytomany</groupId>
    5. <artifactId>ManyToMany</artifactId>
    6. <packaging>jar</packaging>
    7. <version>1.0-SNAPSHOT</version>
    8. <name>ManyToMany</name>
    9. <url>http://maven.apache.org</url>
    10. <dependencies>
    11. <dependency>
    12. <groupId>org.mybatis</groupId>
    13. <artifactId>mybatis</artifactId>
    14. <version>3.4.6</version>
    15. </dependency>
    16. <dependency>
    17. <groupId>mysql</groupId>
    18. <artifactId>mysql-connector-java</artifactId>
    19. <version>6.0.6</version>
    20. </dependency>
    21. <dependency>
    22. <groupId>log4j</groupId>
    23. <artifactId>log4j</artifactId>
    24. <version>1.2.17</version>
    25. </dependency>
    26. </dependencies>
    27. <build>
    28. <resources>
    29. <resource>
    30. <directory>src/main/java</directory>
    31. <includes>
    32. <include>**/*.xml</include>
    33. </includes>
    34. </resource>
    35. <resource>
    36. <directory>src/main/resources</directory>
    37. <includes>
    38. <include>**/*.*</include>
    39. </includes>
    40. </resource>
    41. </resources>
    42. </build>
    43. </project>

    实体类

    src/main/java 的包 shiyanlou.mybatis.manytomany.model 下新建类 Student.java,一个学生具有 id、name、sex、age、courses(List属性。学生和课程之间是多对多关系,一个学生可以选多门课。

    Student.java 的代码如下:

    1. package shiyanlou.mybatis.manytomany.model;
    2. import java.util.List;
    3. public class Student {
    4. private Integer id;
    5. private String name;
    6. private String sex;
    7. private Integer age;
    8. private List<Course> courses;
    9. public Student() {
    10. }
    11. public Student(Integer id, String name, String sex, Integer age,List<Course> courses) {
    12. this.id = id;
    13. this.name = name;
    14. this.sex = sex;
    15. this.age = age;
    16. this.courses = courses;
    17. }
    18. public Integer getId() {
    19. return id;
    20. }
    21. public void setId(Integer id) {
    22. this.id = id;
    23. }
    24. public String getName() {
    25. return name;
    26. }
    27. public void setName(String name) {
    28. this.name = name;
    29. }
    30. public String getSex() {
    31. return sex;
    32. }
    33. public void setSex(String sex) {
    34. this.sex = sex;
    35. }
    36. public Integer getAge() {
    37. return age;
    38. }
    39. public void setAge(Integer age) {
    40. this.age = age;
    41. }
    42. public List<Course> getCourses() {
    43. return courses;
    44. }
    45. public void setCourses(List courses) {
    46. this.courses = courses;
    47. }
    48. }

    再在包 shiyanlou.mybatis.manytomany.model 下新建类 Course.java,一个班级有 id,name,credit、students(List 属性。课程和学生之间是多对多关系,一个课程可以由多个学生选。

    Course.java 的代码如下:

    1. package shiyanlou.mybatis.manytomany.model;
    2. import java.util.List;
    3. public class Course {
    4. private Integer id;
    5. private String name;
    6. private Integer credit;
    7. private List<Student> students;
    8. public Course() {
    9. }
    10. public Course(Integer id, String name, Integer credit,
    11. List<Student> students) {
    12. this.id = id;
    13. this.name = name;
    14. this.credit = credit;
    15. this.students = students;
    16. }
    17. public Integer getId() {
    18. return id;
    19. }
    20. public void setId(Integer id) {
    21. this.id = id;
    22. }
    23. public String getName() {
    24. return name;
    25. }
    26. public void setName(String name) {
    27. this.name = name;
    28. }
    29. public Integer getCredit() {
    30. return credit;
    31. }
    32. public void setCredit(Integer credit) {
    33. this.credit = credit;
    34. }
    35. public List<Student> getStudents() {
    36. return students;
    37. }
    38. public void setStudents(List students) {
    39. this.students = students;
    40. }
    41. }

    最后在包 shiyanlou.mybatis.manytomany.model 下新建类 StudentCourseLink.java,用来描述学生和课程之间的关系,其包含 student(Student)、course(Course)、date 属性。

    1. package shiyanlou.mybatis.manytomany.model;
    2. import java.util.Date;
    3. public class StudentCourseLink {
    4. private Student student;
    5. private Course course;
    6. private Date date;
    7. public StudentCourseLink() {
    8. }
    9. public StudentCourseLink(Student student, Course course, Date date) {
    10. this.student = student;
    11. this.course = course;
    12. this.date = date;
    13. }
    14. public Student getStudent() {
    15. return student;
    16. }
    17. public void setStudent(Student student) {
    18. this.student = student;
    19. }
    20. public Course getCourse() {
    21. return course;
    22. }
    23. public void setCourse(Course course) {
    24. this.course = course;
    25. }
    26. public Date getDate() {
    27. return date;
    28. }
    29. public void setDate(Date date) {
    30. this.date = date;
    31. }
    32. }

    创建方法接口和定义映射文件

    新建包 shiyanlou.mybatis.manytomany.mapper ,并在包下新建方法接口 StudentMapper.java。

    StudentMapper 接口的代码如下:

    1. package shiyanlou.mybatis.manytomany.mapper;
    2. import shiyanlou.mybatis.manytomany.model.Student;
    3. import shiyanlou.mybatis.manytomany.model.StudentCourseLink;
    4. import java.util.List;
    5. public interface StudentMapper {
    6. /*
    7. * 查询所有学生及他们的选择课程的信息
    8. * @return
    9. * @throws Exception
    10. */
    11. public List selectStudentCourse() throws Exception;
    12. /*
    13. * 删除指定 id 用户的某门课(根据课程 id)的选课情况
    14. * @param StudentCourseLink
    15. * @throws Exception
    16. */
    17. public void deleteStudentCourseById(StudentCourseLink scLink) throws Exception;
    18. }

    在包 shiyanlou.mybatis.onetomany.mapper 下新建映射文件 StudentMapper.xml ,映射文件与接口名相同。

    StudentMapper.xml 的配置如下:

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    3. <mapper namespace="shiyanlou.mybatis.manytomany.mapper.StudentMapper">
    4. <!-- 查询所有学生及他们的选择课程的信息 -->
    5. <select id="selectStudentCourse" resultMap="studentCourseMap">
    6. select
    7. s.*,c.* from
    8. tb_student s,tb_course c,tb_select_course sc
    9. where s.s_id=sc.sc_s_id
    10. and c.c_id=sc.sc_c_id
    11. </select>
    12. <!-- 根据学生 id 和课程 id 删除该学生该门课的选课情况 -->
    13. <delete id="deleteStudentCourseById" parameterType="StudentCourseLink">
    14. delete from tb_select_course where sc_s_id=#{student.id} and sc_c_id=#{course.id}
    15. </delete>
    16. <!-- resultMap: 映射实体类和字段之间的一一对应的关系 -->
    17. <resultMap id="studentCourseMap" type="Student">
    18. <id property="id" column="s_id" />
    19. <result property="name" column="s_name" />
    20. <result property="sex" column="s_sex" />
    21. <result property="age" column="s_age" />
    22. <!-- 多对多关联映射:collection -->
    23. <collection property="courses" ofType="Course">
    24. <id property="id" column="c_id" />
    25. <result property="name" column="c_name" />
    26. <result property="credit" column="c_credit" />
    27. </collection>
    28. </resultMap>
    29. </mapper>

    在这里,采用的是集合的嵌套结果映射的方式,使用了  元素映射多对多的关联关系。

    配置文件 mybatis.cfg.xml

    在项目目录 src/main/resources 下新建 MyBatis 配置文件 mybatis.cfg.xml ,用来配置 Mybatis 的运行环境、数据源、事务等。

    mybatis.cfg.xml 的配置如下,具体解释注释已经给出:

    1. "1.0" encoding="UTF-8"?>
    2. configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
    3. <configuration>
    4. <typeAliases>
    5. <package name="shiyanlou.mybatis.manytomany.model" />
    6. typeAliases>
    7. <environments default="development">
    8. <environment id="development">
    9. <transactionManager type="JDBC" />
    10. <dataSource type="POOLED">
    11. <property name="driver" value="com.mysql.jdbc.Driver" />
    12. <property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
    13. <property name="username" value="root" />
    14. <property name="password" value="" />
    15. dataSource>
    16. environment>
    17. environments>
    18. <mappers>
    19. <package name="shiyanlou.mybatis.manytomany.mapper" />
    20. mappers>
    21. configuration>

    日志记录 log4j.properties

    感觉也不必要

    使用日志文件是为了查看控制台输出的 SQL 语句。

    在项目目录 src/main/resources 下新建 MyBatis 日志记录文件 log4j.properties ,在里面添加如下内容:

    1. # Global logging configuration
    2. log4j.rootLogger=DEBUG, stdout
    3. # Console output...
    4. log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    5. log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    6. log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

    测试类 Test

    在包 shiyanlou.mybatis.manytomany.test 下新建测试类 Test.java ,代码如下:

    1. package shiyanlou.mybatis.manytomany.test;
    2. import shiyanlou.mybatis.manytomany.mapper.StudentMapper;
    3. import shiyanlou.mybatis.manytomany.model.Course;
    4. import shiyanlou.mybatis.manytomany.model.Student;
    5. import shiyanlou.mybatis.manytomany.model.StudentCourseLink;
    6. import java.io.IOException;
    7. import java.io.InputStream;
    8. import java.util.List;
    9. import org.apache.ibatis.io.Resources;
    10. import org.apache.ibatis.session.SqlSession;
    11. import org.apache.ibatis.session.SqlSessionFactory;
    12. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    13. public class Test {
    14. private static SqlSessionFactory sqlSessionFactory;
    15. public static void main(String[] args) {
    16. // Mybatis 配置文件
    17. String resource = "mybatis.cfg.xml";
    18. // 得到配置文件流
    19. InputStream inputStream = null;
    20. try {
    21. inputStream = Resources.getResourceAsStream(resource);
    22. } catch (IOException e) {
    23. e.printStackTrace();
    24. }
    25. // 创建会话工厂,传入 MyBatis 的配置文件信息
    26. sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    27. selectStudentCourse();
    28. //deleteStudentCourseById();
    29. }
    30. // 查询所有学生及他们的选择课程的信息
    31. private static void selectStudentCourse(){
    32. // 通过工厂得到 SqlSession
    33. SqlSession session = sqlSessionFactory.openSession();
    34. StudentMapper mapper = session.getMapper(StudentMapper.class);
    35. try {
    36. List<Student> students = mapper.selectStudentCourse();
    37. session.commit();
    38. for(Student stu:students){
    39. System.out.println(stu.getId()+","+stu.getName()+","+stu.getSex()+","+stu.getAge()+":");
    40. List<Course> courses = stu.getCourses();
    41. for(Course cou:courses){
    42. System.out.println(cou.getId()+","+cou.getName()+","+cou.getCredit());
    43. }
    44. }
    45. } catch (Exception e) {
    46. e.printStackTrace();
    47. session.rollback();
    48. }
    49. // 释放资源
    50. session.close();
    51. }
    52. // 根据学生 id 和课程 id 删除该学生该门课的选课情况
    53. private static void deleteStudentCourseById(){
    54. SqlSession session = sqlSessionFactory.openSession();
    55. StudentMapper mapper = session.getMapper(StudentMapper.class);
    56. try {
    57. Student student = new Student();
    58. student.setId(1);
    59. Course course = new Course();
    60. course.setId(2);
    61. StudentCourseLink scLink = new StudentCourseLink();
    62. scLink.setStudent(student);
    63. scLink.setCourse(course);
    64. mapper.deleteStudentCourseById(scLink);
    65. session.commit();
    66. } catch (Exception e) {
    67. e.printStackTrace();
    68. session.rollback();
    69. }
    70. session.close();
    71. }
    72. }

    运行测试类 Test.java。

  • 相关阅读:
    cglib FastClass机制
    用Python采集世界杯球队热搜数据 并发送邮箱通知
    密码技术 (3) - 单向散列函数
    华为云2023年双十一服务器优惠价格表及活动大全
    ai绘画部署教程
    jQuery的使用
    【博学谷学习记录】超强总结,用心分享丨大数据超神之路(五):Hadooop基础篇
    服了,头条4面:因为一个问题问题砍了我10万薪水
    Composite Patterns :如果想用表达 部分-整体的继承关系,组合模式一定是不二之选了
    C#中的delegate和event,及他们的区别
  • 原文地址:https://blog.csdn.net/m0_63297917/article/details/133251671