一、多对一

多对一,顾名思义就在一张数据表里有多个记录,他们有个字段对应对是另一个数据的数据,比如多个学生对应一个老师,直接使用select是不能够把另一个数据表的数据查询出来,这时就要用到多对一的查询方法。
在Mybatis里面,结果映射(resultMap)里的一个子元素association就可以实现多对一

association – 一个复杂类型的关联;许多结果将包装成这种类型 嵌套结果映射 – 关联本身可以是一个 resultMap元素,或者从别处引用一个

相关属性:

property:映射到列结果的字段或属性。如果用来匹配的 JavaBean 存在给定名字的属性,那么它将会被使用。否则 MyBatis 将会寻找给定名称的字段。 无论是哪一种情形,你都可以使用通常的点式分隔形式进行复杂属性导航。 比如,你可以这样映射一些简单的东西:“username”,或者映射到一些复杂的东西上:“address.street.number”。

javaType :一个 Java 类的完全限定名,或一个类型别名(关于内置的类型别名,可以参考上面的表格)。 如果你映射到一个 JavaBean,MyBatis 通常可以推断类型。然而,如果你映射到的是 HashMap,那么你应该明确地指定 javaType 来保证行为与期望的相一致。

column :数据库中的列名,或者是列的别名。一般情况下,这和传递给 resultSet.getString(columnName) 方法的参数一样。 注意:在使用复合主键的时候,你可以使用 column=”{prop1=col1,prop2=col2}” 这样的语法来指定多个传递给嵌套 Select 查询语句的列名。这会使得 prop1 和 prop2 作为参数对象,被设置为对应嵌套 Select 语句的参数。

select :用于加载复杂类型属性的映射语句的 ID,它会从 column 属性指定的列中检索数据,作为参数传递给目标 select 语句。 具体请参考下面的例子。注意:在使用复合主键的时候,你可以使用 column=”{prop1=col1,prop2=col2}” 这样的语法来指定多个传递给嵌套 Select 查询语句的列名。这会使得 prop1 和 prop2 作为参数对象,被设置为对应嵌套 Select 语句的参数。

1.建立数据表

在这里插入图片描述
在这里插入图片描述
这里我就建立了一个peo和teacher两个数据表,peo对应的是学生,teacher对应了教师,其中peo中的tid字段对应的就是teacher的id字段,查询时主要就是用到tid来查询teacher数据表的数据

2.编写实体类

在工程里创建一个Peo类和Teacher类,分别对应peo和teacher数据表,注意要在Peo类里创建一个Teacher类来存放查询到的teacher信息

3.编写XML映射文件

我这里是分开了两个xml文件,分别对应的是peo和teacher

peo.mapper.xml

<select id="getPeoTeacher" resultMap="PeoTeacher">
		select * from peo
</select>
<resultMap id="PeoTeacher" type="Peo">
		<association property="teacher" column="tid" javaType="Teacher" select="entity.TeacherMapper.getTeacher">
		</association>
</resultMap>

teacher.mapper.xml

<select id="getTeacher" resultType="Teacher" >
        select * from teacher where id = #{id}
</select>

在peo.mapper.xml里的<association>里的property是映射到列结果的字段或属性,就是你在实体类里的变量名,column就是要根据什么字段来查询,这里的tid就是peo里的tid,对应着teacher的id,javaType就是返回的类型,这里为teacher,select里就是要执行的查询teacher数据的方法,我这里是存放在了另一个xml文件里。
resultMap<association>来实现多对一,相当于执行了两次select查询,第一次就是查询peo,然后使用查询到的tid字段来查询teacher。

dao层的编写:

public List<Peo> getPeoTeacher() throws IOException {
        SqlSession session = MybatisUtil.getSession();
        List<Peo> list = session.selectList("entity.PeoMapper.getPeoTeacher");
        session.close();
        return list;
    }

4.测试

public class Test {
    public static void main(String[] args) throws IOException {
        PeoDao peoDao = new PeoDao();
        List<Peo> l = peoDao.getPeoTeacher();
        for (Peo p : l){
            System.out.println(p+" "+p.getTeacher());
        }
    }
}

在这里插入图片描述
我这里就将每一个peo和对应的teacher给查询出来了

二、一对多

当知道如何实现多对一之后,一对多就很容易写了
多对一是根据peo的tid来查询teacher的id,一对多就是反过来的,根据teacher的id来查询peo的tid
这里是使用resultMapcollection来实现

1.编写实体类

这里就只用在Teacher类里多添加一个子元素peo来存放查询到到peo数据,因为peo数据会不止一个,所以要用list来存放

private List<Peo> peo;

2.编写XML映射文件

teacher.mapper.xml

<select id="getTeacherPeo" resultMap="TeacherPeo">
        select * from teacher where id = #{id}
</select>
<resultMap id="TeacherPeo" type="Teacher" >
        <collection property="peo" javaType="ArrayList" ofType="Peo" column="id" select="entity.PeoMapper.getByTid">
        </collection>
</resultMap>

peo.mapper.xml

<select id="getByTid" resultType="Peo">
		select * from peo where tid=#{id}
</select>

注意这里的javaType="ArrayList" ofType="Peo"

dao层:

public  Teacher getTeacher(int id) throws IOException {
        Teacher teacher = new Teacher();
        SqlSession session = MybatisUtil.getSession();
        teacher = session.selectOne("entity.TeacherMapper.getTeacherPeo",id);
        session.close();
        return teacher;
    }

3.测试

public class Test {
    public static void main(String[] args) throws IOException {
        TeacherDao teacherDao = new TeacherDao();
        Teacher tea = teacherDao.getTeacher(1);
        System.out.println(tea);
        for (Peo p : tea.getPeo()) {
            System.out.println(p);
        }
    }
}

在这里插入图片描述

三、动态sql

平时编写sql语句,一般都是写死的,比如要写一个根据性别来查询,我们要将全部男性查询出来

select * from peo where sex=#{sex}

这时我们就必须传入一个参数给到sex,若没有传入则不会查询出任何数据
动态sql就可以解决参数为空时查询不到数据到问题,当你传入参数时就会根据参数来参数,若不传入则是查询全部数据

在mybatis里if+where语句就可以很方便的实现动态sql

<select id="selectAll" resultType="Peo" parameterType="Peo">
		select * from peo
		<where>
			<if test="name!=null">
				name = #{name}
			</if>
			<if test="sex!=null">
				and sex = #{sex}
			</if>
		</where>
	</select>

当有多个条件时,若第一个条件不成立,<where>会自动将后面的满足条件的sql语句中的and去掉

还有使用set+if就可以实现update的动态sql

<update id="updatePeo" parameterType="Peo">
		update peo p
		<set>
			<if test="name != null and name != ''">
				p.name = #{name},
			</if>
			<if test="sex != null and sex != ''">
				p.sex = #{sex}
			</if>
		</set>
		where id = #{id}
	</update>

动态sql一般就是运用在搜索时的条件筛选


版权声明:本文为weixin_44069664原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_44069664/article/details/102693083