【Mybatis】多表查询

多表查询一直是数据库的关键部分。网上关于Mybatis的例子天华龙凤,又要自己新建实体类,又在一个实体类中将另一个实体类联系起来,在我看来大可不必,只要将sql查询结果的视图映射到Java里面即可。下面举一个例子来说明这个问题。

下面是两张表,一张user一张blog,blog的creator是参照user的id,用来记录谁发的blog。


那要找a的blog的title和content注定需要多表查询,查询语句相信只要稍微懂点数据库的人,估计是没什么疑问的,具体如下,一个很简单的多表查询:

SELECT title,content FROM user,blog
where user.username='a'
and user.id=blog.creator

现在主要问题是如何反映到mybatis上面,网上大部分教程写要在user.java中搞一个blog.java,然后又要在xml配一大堆,在我看来是不对的。

要是这是个涉及N个表的查询呢?要是user和blog表有交互之后,user又和x表有交互呢?这样在一个实体类的数据不就多如繁星?在xml配的association不就天花龙凤?

其实只要配一个sql视图的dao数据库接口就行,连sql的实体类都不用配,更何况数据库视图根本就没有实体。

具体实现如下:

1、先贴上我工程的目录结构


2、基本上和《【Mybatis】Helloworld》( 点击打开链接)的目录结构差不多。configuration.xml基本是一字没改,仅仅是声明有一个sql.xml的mapper
<?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>
	<!-- 写明关于mysql的连接信息 -->
	<environments default="development">
		<environment id="development">
			<transactionManager type="jdbc" />
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:mysql://localhost:3306/test" />
				<property name="username" value="root" />
				<property name="password" value="root" />
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<mapper resource="test/mapper/Sql.xml" />
	</mappers>
</configuration>     

3、在Sql.xml里面就不用写些association节点了,直接摆上我们在数据库查询多表的查询语句。parameterType接受参数#{username}是string没什么问题,如果你是int或者是其它就自己改好,关键是返回参数resultType声明是一个map。
<?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="test.dao.SqlDao">
	<select id="findBlogByUsername" parameterType="String"
		resultType="Map">
		SELECT title,content FROM user,blog
		where user.username=#{username}
		and user.id=blog.creator
	</select>
</mapper> 

之后在test.dao.SqlDao.java接着声明返回的东东是一个关于map的list,mybatis就会将这段sql所对应的视图转成一个map的list。这个map的list是这样,list存着sql对应视图的每一行,然后map的key就是每一行里面的每一个字段名,value就是这个key对应一个数据,恰好构成一个类二维数组对应一张二维表的视图。
package test.dao;

import java.util.*;

public interface SqlDao {
	public List<Map<String, Object>> findBlogByUsername(String username);
}

4、最后我们就可以直接在其它的java调用这个方法,在java中得到这个sql视图,也就是多表查询的结果,例如主测试类MybatisMultiTable.java调用sqlDao.findBlogByUsername("a");:
import java.io.IOException;
import java.util.*;

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 test.dao.SqlDao;

public class MybatisMultiTable {

	/* 纯java连接数据库的方法 */
	private static SqlSessionFactory getSessionFactory() {
		SqlSessionFactory sessionFactory = null;
		String resource = "configuration.xml";
		try {
			sessionFactory = new SqlSessionFactoryBuilder().build(Resources
					.getResourceAsReader(resource));
		} catch (IOException e) {
			e.printStackTrace();
		}
		return sessionFactory;
	}

	public static void main(String[] args) {
		SqlSession sqlSession = getSessionFactory().openSession();// 连接数据库
		SqlDao sqlDao = sqlSession.getMapper(SqlDao.class);
		List<Map<String, Object>> sqlresult = sqlDao.findBlogByUsername("a");
		System.out.println("title\tcontent");
		System.out.println("==============");
		for (Map<String, Object> one_sqlresult : sqlresult) {
			System.out.println(one_sqlresult.get("title") + "\t"
					+ one_sqlresult.get("content"));

		}
	}

}

将其返回值打印出来的运行结果如下图所示:

猜你喜欢

转载自blog.csdn.net/yongh701/article/details/78597268