【Mybatis】多表查询

来源:互联网 发布:跑包软件 编辑:程序博客网 时间:2024/06/04 00:59

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

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


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

SELECT title,content FROM user,blogwhere 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,blogwhere 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"));}}}

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