当前位置:Gxlcms > 数据库问题 > SQL映射文件-----MySQL关系映射【1对1,1对多,多对多】

SQL映射文件-----MySQL关系映射【1对1,1对多,多对多】

时间:2021-07-01 10:21:17 帮助过:18人阅读

当数据库中表与表之间有关联时,在对数据库进行操作时,就不只是针对某一张表了,需要联表查询

MyBatis中如何实现联表查询

1、首先新建两张表

学生表(student

  • ID:stu_id
  • 姓名:stu_name
  • 年龄:stu_age
  • 性别:stu_gender
  • 所在班级:g_id

班级表(grade

  • ID:g_id
  • 班级名称:g_name

学生表和班级表通过 g_id 进行关联,一个班级对应多个学生

技术分享

2、创建相应的实体类和mapper接口

(1)创建 Student 类和 Grade 类(包名:com.bwlu.bean

技术分享技术分享

(2)创建 StudentMapper 接口和 GradeMapper 接口和相应的 XML 文件(使用逆向生成可直接生成)

 StudentMapper.java 接口

Student selectByPrimaryKey(Integer stuId);//按主键查询一条记录

 StudentMapper.xml

<mapper namespace="com.bwlu.mapper.StudentMapper" >
  <resultMap id="BaseResultMap" type="com.bwlu.bean.Student" >
    <id column="stu_id" property="stuId" jdbcType="INTEGER" />
    <result column="stu_name" property="stuName" jdbcType="VARCHAR" />
    <result column="stu_age" property="stuAge" jdbcType="INTEGER" />
    <result column="stu_gender" property="stuGender" jdbcType="INTEGER" />
    <result column="g_id" property="gId" jdbcType="INTEGER" />
  </resultMap>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
    select stu_id, stu_name, stu_age, stu_gender, g_id from student 
    where stu_id = #{stuId,jdbcType=INTEGER}
  </select>
</mapper>

 GradeMapper.java

Grade selectByPrimaryKey(Integer gId);//按主键查询一条记录

 GradeMapper.xml

<mapper namespace="com.bwlu.mapper.GradeMapper" >
  <resultMap id="BaseResultMap" type="com.bwlu.bean.Grade" >
    <id column="g_id" property="gId" jdbcType="INTEGER" />
    <result column="g_name" property="gName" jdbcType="VARCHAR" />
  </resultMap>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
    select g_id, g_name from grade
    where g_id = #{gId,jdbcType=INTEGER}
  </select>
</mapper>

3、在sql映射文件中写映射sql语句【联合查询:级联属性封装结果集】

3.1第一种 

(1)在 Student.java 中将 g_id 属性换成班级类型(Grade),并添加相应的getter和setter方法

//private Integer g_id;
private Grade grade;
public Grade getGrade() {
    return grade;
}
public void setGrade(Grade grade) {
    this.grade = grade;
}

(2)在 xml 中封装结果集,并编写相应的 sql 语句

<resultMap id="BaseResultMap" type="com.bwlu.bean.Student" >
  <id column="stu_id" property="stuId" jdbcType="INTEGER" />
  <result column="stu_name" property="stuName" jdbcType="VARCHAR" />
  <result column="stu_age" property="stuAge" jdbcType="INTEGER" />
  <result column="stu_gender" property="stuGender" jdbcType="INTEGER" />
  <result column="g_id" property="grade.gId" jdbcType="INTEGER" />
  <result column="g_name" property="grade.gName" jdbcType="VARCHAR" />
</resultMap>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
  select stu_id, stu_name, stu_age, stu_gender, g.g_id, g_name
  from student s,grade g
  where s.g_id = g.g_id AND stu_id = #{stuId,jdbcType=INTEGER}
</select>

(3)测试

@Autowired
private StudentMapper studentMapper;
@Test
public void testAssociation() {
    Student student = studentMapper.selectByPrimaryKey(6);
    System.out.println(student);//Student [stuId=6, stuName=lixiang, stuAge=22, stuGender=1, grade=Grade [gId=3, gName=软件(3)班]]
}

3.2第二种

(1)在 Student.java 中将 g_id 属性换成班级类型(Grade),并添加相应的getter和setter方法,同 3.1 的(1)

(2)使用association来定义关联对象的规则【比较正规的,推荐的方式】

<resultMap id="BaseResultMap" type="com.bwlu.bean.Student" >
  <id column="stu_id" property="stuId" jdbcType="INTEGER" />
  <result column="stu_name" property="stuName" jdbcType="VARCHAR" />
  <result column="stu_age" property="stuAge" jdbcType="INTEGER" />
  <result column="stu_gender" property="stuGender" jdbcType="INTEGER" />
  <!-- association可以指定联合的javaBean对象
    property="grade":指定哪个属性是联合的对象
    javaType:指定这个属性对象的类型【不能省略】-->
  <association property="grade" javaType="com.bwlu.bean.Grade">
      <id column="g_id" property="gId" jdbcType="INTEGER"/>
      <result column="g_name" property="gName" jdbcType="VARCHAR"/>
  </association>
</resultMap>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
  select stu_id, stu_name, stu_age, stu_gender, g.g_id, g_name
  from student s,grade g
  where s.g_id = g.g_id AND stu_id = #{stuId,jdbcType=INTEGER}
</select>

(3)测试(同 3.1 的(3),结果也一样)

 3.3第三种

(1)在 Student.java 中将 g_id 属性换成班级类型(Grade),并添加相应的getter和setter方法,同 3.1 的(1)

(2)使用Association进行分步查询【上述结果相当于使用嵌套结果集的形式】

<resultMap id="BaseResultMap" type="com.bwlu.bean.Student" >
  <id column="stu_id" property="stuId" jdbcType="INTEGER" />
  <result column="stu_name" property="stuName" jdbcType="VARCHAR" />
  <result column="stu_age" property="stuAge" jdbcType="INTEGER" />
  <result column="stu_gender" property="stuGender" jdbcType="INTEGER" />
  <!-- 使用association进行分步查询 
     1.先按照学生id查询学生信息
     2.根据查询学生信息中g_id值去班级表查出班级信息
     3.将班级信息设置到学生中:
    association定义关联对象的封装规则
    select:表明当前属性是调用指定的方法查出的结果
    column:指定将哪一列的值传给这个方法
    流程:使用select指定的方法(传入column指定的这列参数的值)查出对象,并封装给property指定的属性。-->
  <association property="grade" select="getGradeById" column="g_id"></association>
</resultMap>
<select id="getGradeById"resultType="com.bwlu.bean.Grade" parameterType="java.lang.Integer" >
  select g_id, g_name from grade 
  where g_id = #{gId,jdbcType=INTEGER}
</select>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
  select stu_id, stu_name, stu_age, stu_gender, g_id
  from student
  where stu_id = #{stuId,jdbcType=INTEGER}
</select>

 注:使用 resultType 返回值类型进行接收,必须使用驼峰式命名,使数据库中的字段和实体类中的字段对应。

 (3)测试(同 3.1 的(3),结果也一样)

 (2)中也可以指定为 GradeMapper 下的方法。

<association property="grade" select="com.bwlu.mapper.GradeMapper.selectByPrimaryKey" column="g_id"></association>

懒加载机制【按需加载,也叫懒加载】
3.3 分步查询中,每次查询 Student 对象的时候,都将关联 Grade 的对象查询出来了。

使用延迟加载,可以在需要 班级 信息的时候,再去查询,不需要的时候就不用查询。

在 MyBatis 的全局配置文件中,加入两个配置

<settings>
    <!-- 驼峰式命名 -->
    <setting name="mapUnderscoreToCamelCase" value="true"/>
    <!-- 开启懒加载机制 ,默认值为true-->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 开启的话,每个属性都会直接全部加载出来;禁用的话,只会按需加载出来 -->
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>

这样,当我们查询 Student 对象的时候,如果只输出学生姓名,就不会执行查询班级信息的 sql 语句,当需要班级信息的时候才会执行。

 

上述是在多端(学生)查询一端(班级)的信息,用 association,当我们在一端查询多端信息的时候,需要使用 collection,查出的是一个集合

 

未完

 

SQL映射文件-----MySQL关系映射【1对1,1对多,多对多】

标签:color   name   arch   val   tun   返回值   ssm   针对   arc   

人气教程排行