温馨提示:对mapper.xml映射文件和mapper接口类之间的详细对应关系不清的可以查看上上一篇一对一操作的内容进行了解
1.第一步:编写数据库的配置文件,日志的配置文件,文件的具体编写请查看上上一篇一对一操作的内容进行了解
准备:
package com.itheima.bean;
public class Course {
private Integer id; //主键id
private String name; //课程名称
//省略构造和set\get
}
package com.ithmy.bean;
import java.util.List;
public class Student {
private Integer id; //主键id
private String name; //学生姓名
private Integer age; //学生年龄
private List<Course> courses; // 学生所选择的课程集合
//省略构造和set\get
}
2.第二步:MyBatisConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!--MyBatis的DTD约束-->
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--configuration 核心根标签-->
<configuration>
<!--引入数据库连接的配置文件-->
<properties resource="jdbc.properties"/>
<!--配置LOG4J-->
<settings>
<setting name="logImpl" value="log4j"/>
</settings>
<!--起别名-->
<typeAliases>
<package name="com.ithmy.bean"/>
</typeAliases>
<!--environments配置数据库环境,环境可以有多个。default属性指定使用的是哪个-->
<environments default="mysql">
<!--environment配置数据库环境 id属性唯一标识-->
<environment id="mysql">
<!-- transactionManager事务管理。 type属性,采用JDBC默认的事务-->
<transactionManager type="JDBC"></transactionManager>
<!-- dataSource数据源信息 type属性 连接池-->
<dataSource type="POOLED">
<!-- property获取数据库连接的配置信息 -->
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<!-- mappers引入映射配置文件 -->
<mappers>
<mappers>
<mapper resource="com/ithmy/many_to_many/ManyToManyMapper.xml"/>
</mappers>
</mappers>
</configuration>
3.第三步:配置文件:com.ithmy.many_to_many.ManyToManyMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ithmy.table03.ManyToManyMapper">
<resultMap id="manyToMany" type="student">
<id column="sid" property="id"/>
<result column="sname" property="name"/>
<result column="sage" property="age"/>
<collection property="courses" ofType="course">
<id column="cid" property="id"/>
<result column="cname" property="name"/>
</collection>
</resultMap>
<select id="selectAll" resultMap="manyToMany">
SELECT sc.sid,s.name sname,s.age sage,sc.cid,c.name cname FROM student s,course c,stu_cr sc WHERE sc.sid=s.id AND sc.cid=c.id
</select>
<!--注意这里查询的是sc.cid,将这个cid给course的id了,这也是可以的,因为都是课程id
但其实sql语句中的sc.cid,可以换成c.id,这样的话给course的id更合适
-->
</mapper>
4.第四步:接口
package com.ithmy.table03;
import com.ithmy.bean.Student;
import java.util.List;
public interface ManyToManyMapper {
//查询全部
public abstract List<Student> selectAll();
}
5.第五步:测试
package com.ithmy.table03;
import com.ithmy.bean.Course;
import com.ithmy.bean.Student;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.InputStream;
import java.util.List;
public class Test01 {
@Test
public void selectAll() throws Exception{
//1.加载核心配置文件
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
//2.获取SqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//4.获取ManyToManyMapper接口的实现类对象
ManyToManyMapper mapper = sqlSession.getMapper(ManyToManyMapper.class);
//5.调用实现类的方法,接收结果
List<Student> students = mapper.selectAll();
//6.处理结果
for (Student student : students) {
System.out.println(student.getId() + "," + student.getName() + "," + student.getAge());
List<Course> courses = student.getCourses();
for (Course cours : courses) {
System.out.println("\t" + cours);
}
}
//7.释放资源
sqlSession.close();
is.close();
}
}
6.总结:
<resultMap>:配置字段和对象属性的映射关系标签。
id 属性:唯一标识
type 属性:实体对象类型
<id>:配置主键映射关系标签。
<result>:配置非主键映射关系标签。
column 属性:表中字段名称
property 属性: 实体对象变量名称
<collection>:配置被包含集合对象的映射关系标签。
property 属性:被包含集合对象的变量名
ofType 属性:集合中保存的对象数据类型
7.拓展:
当我们开发中遇到多对多的表关系的时候,往往可能不止两个实体间的包含,很可能是多个,这个时候要找到最顶层的那个包含实体类,向上面的例子一样就是Student,
这是很捋清楚它的下层下下层下下下层等关系,按照这个例子一样的写法把包含转成<collection></collection>就行了,最后写一下sql语句就完美解决了!
注意!注意!注意!
在实际开发中,多对多这样的关联查询直接使用sql很少用,因为关联查询需要查询的次数会大幅增加,导致的就是数据库的响应很慢,
一般开发中会使用单表查询,查询出包含表的关键字,然后通过Java进行关键字再单表查的方式实现多对多关系,最终查询出想要的结果