Mybatis学习(8)多表之一对多关联查询

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SDDDLLL/article/details/84999924

在之前的博客当中都是单表的增删改查操作,现在考虑一个稍微复杂一点也更贴近真实情况的问题。关联查询。关联查询分为四种情况:

  1. 一对一关联查询
  2. 一对多关联查询
  3. 多对一关联查询
  4. 多对多关联查询

本篇博客先考虑一种情况,一对多关联查询。以国家和部长之间的一对多关系进行演示。先看整个项目的目录结构:

1、定义实体

在定义实体的时候,若定义的是双向关联,也就是说双方的属性中都有对象的属性作为域属性出现,那么在定义各自的toString()方法时候需要注意,只让一方可以输出为另外一方即可,否则的话会形成递归调用。这种情况可以参考博客:

https://blog.csdn.net/SDDDLLL/article/details/83268054

我们知道一个国家当中会有很多个部长,所以国家和部长之间的关系是一对多关系。

首先是国家类:

public class Country {
	private Integer cid;
	private String cname;
	//关联属性
	private Set<Minister> ministers;
	
	//getter和serter方法
    //toString方法
	
}

然后是部长类:

public class Minister {
	private Integer mid;
	private String mname;
	
	//getter和seter
    //toString方法
}

2、定义数据库表

首先是国家表:country

其次是部长表:minister

3、定义ICountryDao接口

我们通过国家的id选出这个国家,以及这个国家的部长。

import com.test.beans.Country;

public interface ICountryDao {
	Country selectCountryById(int cid);
}

4、定义测试类

public class MyTest {
	//由于增删改查都需要ICountryDao ,所以将其设置2全局变量。	
	private ICountryDao dao ;
	private SqlSession sqlSession;
	
	@Before
	public void testBefore(){
		sqlSession = MybatisUtil.getSqlSession();
		dao = sqlSession.getMapper(ICountryDao.class);
	}
	
	@After
	public void after(){
		if(sqlSession!=null){
			sqlSession.close();
		}
	}

    @Test
	public void testSelectStuByCondition() {
		Integer a=new Integer(2);
		Country country=dao.selectCountryById(a);
		System.out.println(country);
	}
	
}

5、定义映射文件

A:多表链接查询方式

<?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.test.dao.ICountryDao">
	<resultMap type="Country" id="countryMapper">
		<id column="cid" property="cid"/>
		<result column="cname" property="cname"/>
		<collection property="ministers" ofType="Minister">
			<id column="mid" property="mid"/>
			<result column="mname" property="mname"/>
		</collection>
	</resultMap>

	<select id="selectCountryById" resultMap="countryMapper">
		select cid,cname,mid,mname 
		from country,minister
		where 
		countryid = cid  and cid = #{xxx}
	</select>
</mapper>

注意:1、由于此时返回的结果是部长集合,resultMap要单独处理

2、此时即使字段名与属性名字相同,在<resultMap/>也要写出他们的映射关系。因为框架是根据这个<resultMap/>封装对象的。

3、在映射文件中使用<collection/>标签体现出两个实体对象间的关联关系。这两个属性的意义是:

  • property:指定关联属性,也就是country类中的集合属性,类中的字段名
  • ofType:集合属性的泛型类型(也就是minister类)

B:多表单独查询方式

多表连接查询方式是将多张表进行连接,链接为一张表后进行查询。其查询的本质是一张表。多表单独查询方式是多张表各自查询各自的相关内容,需要多张表的联合数据了,则将主表的查询结果联合其他表的查询结果,封装为一个对象。

当然,这多个查询是可以跨越多个映射文件的,也就是跨越多个namespace的。在使用其他namespace的查询时,添加上其所在的namespace即可。

<?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.test.dao.ICountryDao">
	<select id="selectMinisterById" resultType="Minister">
		select mid,mname 
		from minister
		where 
		countryid=#{ooo}
	</select>
	
	<resultMap type="Country" id="countryMapper">
		<id column="cid" property="cid"/>
		<result column="cname" property="cname"/>
		<collection 
			property="ministers" 
			ofType="Minister"
			select="selectMinisterById"
			column="cid"/>

	</resultMap>

	<select id="selectCountryById" resultMap="countryMapper">
		select cid,cname
		from country
		where 
		cid = #{xxx}
	</select>
</mapper>

我们可以看到我们在<collection/>中又进行了一次查询,其属性的数据来自于另一个查询<selectMinisterById>(不是根据图,根据代码)。而该查询的动态参数country=#{ooo}的值来自于查询<selectCountryById/>的查询结果cid

6、其他类中的代码

1、MybatisUtil

public class MybatisUtil {
	
	//单例模式创建sqlSession.要设置成静态的
	
	public static SqlSession getSqlSession(){
		SqlSessionFactory factory = null;
		try {
			InputStream is = Resources.getResourceAsStream("mybatis.xml");	
			if(factory==null){
				factory=new SqlSessionFactoryBuilder().build(is);
			}			
			SqlSession sqlSession = factory.openSession();
			return sqlSession;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
}

2、mybatis.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<!-- 数据库的配置文件 -->
	<properties resource="jdbc.properties"/>
	
	<!-- 别名的定义 -->
	<typeAliases>
		<!-- 将保内的所有类的名字作为别名 -->
		<package name="com.test.beans"/>
	</typeAliases>
	<!-- 配置运行环境 -->
	<environments default="testEM">
		<environment id="testEM">
			<transactionManager type="JDBC"/>
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}"/>
				<property name="url" value="${jdbc.url}"/>
				<property name="username" value="${jdbc.user}"/>
				<property name="password" value="${jdbc.password}"/>
			</dataSource>
		</environment>
	</environments>
	
	<!-- 注册映射文件 -->
	<mappers>
		<mapper resource="com/test/dao/mapper.xml"/>
	</mappers>
	
</configuration>

3、jdbc.properties

jdbc.driver= com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/test1
jdbc.user=root
jdbc.password=root

4、log4j.properties

##define an appender named console
log4j.appender.console=org.apache.log4j.ConsoleAppender
#The Target value is System.out or System.err
log4j.appender.console.Target=System.out
#set the layout type of the apperder
log4j.appender.console.layout=org.apache.log4j.PatternLayout
#set the layout format pattern
log4j.appender.console.layout.ConversionPattern=[%-5p] %m%n

##define a logger
##.test is mybatis.xml namespace 
log4j.logger.com.test.dao.ICountryDao=debug,console

附上源码地址:https://download.csdn.net/download/sdddlll/10859884

猜你喜欢

转载自blog.csdn.net/SDDDLLL/article/details/84999924