下面就来说一下 mybatis 是通过什么来实现多表联合查询的。首先看一下表关系,如图:

里,我已经搭好了开发的环境,用到的是 SpringMVC + Spring +
MyBatis,当然,为了简单期间,你可以不用搭前端的框架,只使用 Spring + MyBatis 就可以,外加 junit
测试即可。环境我就不带大家搭了,这里只说涉及到联合查询的操作。
设计好表之后,我用到了 mybatis 的自动生成工具 mybatis generator 生成的实体类、mapper 接口、以及 mapper xml 文件。由于是测试多表联合查询,因此需要自己稍加改动。
下面是 User 和 Role 的实体类代码:
  1. <span style="font-family:Comic Sans MS;font-size:12px;">package com.sica.domain;
  2.  
  3. import java.io.Serializable;
  4. import java.util.List;
  5.  
  6. public class User implements Serializable {
  7. private String id;
  8.  
  9. private String username;
  10.  
  11. private String password;
  12.  
  13. private List<Role> roles;
  14.  
  15. private static final long serialVersionUID = 1L;
  16.  
  17. public String getId() {
  18. return id;
  19. }
  20.  
  21. public void setId(String id) {
  22. this.id = id == null ? null : id.trim();
  23. }
  24.  
  25. public String getUsername() {
  26. return username;
  27. }
  28.  
  29. public void setUsername(String username) {
  30. this.username = username == null ? null : username.trim();
  31. }
  32.  
  33. public String getPassword() {
  34. return password;
  35. }
  36.  
  37. public void setPassword(String password) {
  38. this.password = password == null ? null : password.trim();
  39. }
  40.  
  41. public List<Role> getRoles() {
  42. return roles;
  43. }
  44.  
  45. public void setRoles(List<Role> roles) {
  46. this.roles = roles;
  47. }
  48.  
  49. @Override
  50. public boolean equals(Object that) {
  51. if (this == that) {
  52. return true;
  53. }
  54. if (that == null) {
  55. return false;
  56. }
  57. if (getClass() != that.getClass()) {
  58. return false;
  59. }
  60. User other = (User) that;
  61. return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
  62. && (this.getUsername() == null ? other.getUsername() == null : this.getUsername().equals(other.getUsername()))
  63. && (this.getPassword() == null ? other.getPassword() == null : this.getPassword().equals(other.getPassword()));
  64. }
  65.  
  66. @Override
  67. public int hashCode() {
  68. final int prime = 31;
  69. int result = 1;
  70. result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
  71. result = prime * result + ((getUsername() == null) ? 0 : getUsername().hashCode());
  72. result = prime * result + ((getPassword() == null) ? 0 : getPassword().hashCode());
  73. return result;
  74. }
  75. }</span>

Role

  1. <span style="font-family:Comic Sans MS;font-size:12px;">package com.sica.domain;
  2.  
  3. import java.io.Serializable;
  4.  
  5. public class Role implements Serializable {
  6. private String id;
  7.  
  8. private String name;
  9.  
  10. private String jsms;
  11.  
  12. private String bz;
  13.  
  14. private Integer jlzt;
  15.  
  16. private String glbm;
  17.  
  18. private String userid;
  19.  
  20. private static final long serialVersionUID = 1L;
  21.  
  22. public String getId() {
  23. return id;
  24. }
  25.  
  26. public void setId(String id) {
  27. this.id = id == null ? null : id.trim();
  28. }
  29.  
  30. public String getName() {
  31. return name;
  32. }
  33.  
  34. public void setName(String name) {
  35. this.name = name == null ? null : name.trim();
  36. }
  37.  
  38. public String getJsms() {
  39. return jsms;
  40. }
  41.  
  42. public void setJsms(String jsms) {
  43. this.jsms = jsms == null ? null : jsms.trim();
  44. }
  45.  
  46. public String getBz() {
  47. return bz;
  48. }
  49.  
  50. public void setBz(String bz) {
  51. this.bz = bz == null ? null : bz.trim();
  52. }
  53.  
  54. public Integer getJlzt() {
  55. return jlzt;
  56. }
  57.  
  58. public void setJlzt(Integer jlzt) {
  59. this.jlzt = jlzt;
  60. }
  61.  
  62. public String getGlbm() {
  63. return glbm;
  64. }
  65.  
  66. public void setGlbm(String glbm) {
  67. this.glbm = glbm == null ? null : glbm.trim();
  68. }
  69.  
  70. public String getUserid() {
  71. return userid;
  72. }
  73.  
  74. public void setUserid(String userid) {
  75. this.userid = userid == null ? null : userid.trim();
  76. }
  77.  
  78. @Override
  79. public boolean equals(Object that) {
  80. if (this == that) {
  81. return true;
  82. }
  83. if (that == null) {
  84. return false;
  85. }
  86. if (getClass() != that.getClass()) {
  87. return false;
  88. }
  89. Role other = (Role) that;
  90. return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
  91. && (this.getName() == null ? other.getName() == null : this.getName().equals(other.getName()))
  92. && (this.getJsms() == null ? other.getJsms() == null : this.getJsms().equals(other.getJsms()))
  93. && (this.getBz() == null ? other.getBz() == null : this.getBz().equals(other.getBz()))
  94. && (this.getJlzt() == null ? other.getJlzt() == null : this.getJlzt().equals(other.getJlzt()))
  95. && (this.getGlbm() == null ? other.getGlbm() == null : this.getGlbm().equals(other.getGlbm()))
  96. && (this.getUserid() == null ? other.getUserid() == null : this.getUserid().equals(other.getUserid()));
  97. }
  98.  
  99. @Override
  100. public int hashCode() {
  101. final int prime = 31;
  102. int result = 1;
  103. result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
  104. result = prime * result + ((getName() == null) ? 0 : getName().hashCode());
  105. result = prime * result + ((getJsms() == null) ? 0 : getJsms().hashCode());
  106. result = prime * result + ((getBz() == null) ? 0 : getBz().hashCode());
  107. result = prime * result + ((getJlzt() == null) ? 0 : getJlzt().hashCode());
  108. result = prime * result + ((getGlbm() == null) ? 0 : getGlbm().hashCode());
  109. result = prime * result + ((getUserid() == null) ? 0 : getUserid().hashCode());
  110. return result;
  111. }
  112. }</span>
首先讲一下业务,这里用到的 User 、Role 的对应关系是,一个用户有多个角色,也就是 User : Role 是 1 : n 的关系。因此,在 User 的实体中加入一个 Role 的属性,对应一对多的关系。
然后就是 mapper 接口和 xml 文件了:
mapper接口
UserMapper
  1. <span style="font-family:Comic Sans MS;font-size:12px;">package com.sica.mapper;
  2.  
  3. import com.sica.domain.User;
  4.  
  5. import java.util.List;
  6.  
  7. public interface UserMapper {
  8. int deleteByPrimaryKey(String id);
  9.  
  10. int insert(User record);
  11.  
  12. int insertSelective(User record);
  13.  
  14. User selectByPrimaryKey(String id);
  15.  
  16. int updateByPrimaryKeySelective(User record);
  17.  
  18. int updateByPrimaryKey(User record);
  19.  
  20. List<User> queryForList();
  21. }</span>
mapper xml文件
UserMapper
  1. <span style="font-family:Comic Sans MS;font-size:12px;"><?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
  3. <mapper namespace="com.sica.mapper.UserMapper">
  4. <resultMap id="BaseResultMap" type="com.sica.domain.User">
  5. <id column="id" property="id" jdbcType="VARCHAR"/>
  6. <result column="username" property="username" jdbcType="VARCHAR"/>
  7. <result column="password" property="password" jdbcType="VARCHAR"/>
  8. </resultMap>
  9.  
  10. <resultMap id="queryForListMap" type="com.sica.domain.User">
  11. <id column="id" property="id" jdbcType="VARCHAR"/>
  12. <result column="username" property="username" jdbcType="VARCHAR"/>
  13. <result column="password" property="password" jdbcType="VARCHAR"/>
  14. <collection property="roles" javaType="java.util.List" ofType="com.sica.domain.Role">
  15. <id column="r_id" property="id" jdbcType="VARCHAR" />
  16. <result column="r_name" property="name" jdbcType="VARCHAR" />
  17. <result column="r_jsms" property="jsms" jdbcType="VARCHAR" />
  18. <result column="r_bz" property="bz" jdbcType="VARCHAR" />
  19. <result column="r_jlzt" property="jlzt" jdbcType="INTEGER" />
  20. <result column="r_glbm" property="glbm" jdbcType="VARCHAR" />
  21. </collection>
  22. </resultMap>
  23. <select id="queryForList" resultMap="queryForListMap">
  24. SELECT
  25. u.id,
  26. u.username,
  27. u.password,
  28. r.id r_id,
  29. r.name r_name,
  30. r.jsms r_jsms,
  31. r.bz r_bz,
  32. r.jlzt r_jlzt,
  33. r.glbm r_glbm
  34. FROM
  35. user u
  36. LEFT JOIN
  37. role r
  38. ON
  39. u.id = r.userid
  40. </select>
  41. <sql id="Base_Column_List">
  42. id, username, password
  43. </sql>
  44. <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.String">
  45. select
  46. <include refid="Base_Column_List"/>
  47. from user
  48. where id = #{id,jdbcType=VARCHAR}
  49. </select>
  50. <delete id="deleteByPrimaryKey" parameterType="java.lang.String">
  51. delete from user
  52. where id = #{id,jdbcType=VARCHAR}
  53. </delete>
  54. <insert id="insert" parameterType="com.sica.domain.User">
  55. insert into user (id, username, password
  56. )
  57. values (#{id,jdbcType=VARCHAR}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}
  58. )
  59. </insert>
  60. <insert id="insertSelective" parameterType="com.sica.domain.User">
  61. insert into user
  62. <trim prefix="(" suffix=")" suffixOverrides=",">
  63. <if test="id != null">
  64. id,
  65. </if>
  66. <if test="username != null">
  67. username,
  68. </if>
  69. <if test="password != null">
  70. password,
  71. </if>
  72. </trim>
  73. <trim prefix="values (" suffix=")" suffixOverrides=",">
  74. <if test="id != null">
  75. #{id,jdbcType=VARCHAR},
  76. </if>
  77. <if test="username != null">
  78. #{username,jdbcType=VARCHAR},
  79. </if>
  80. <if test="password != null">
  81. #{password,jdbcType=VARCHAR},
  82. </if>
  83. </trim>
  84. </insert>
  85. <update id="updateByPrimaryKeySelective" parameterType="com.sica.domain.User">
  86. update user
  87. <set>
  88. <if test="username != null">
  89. username = #{username,jdbcType=VARCHAR},
  90. </if>
  91. <if test="password != null">
  92. password = #{password,jdbcType=VARCHAR},
  93. </if>
  94. </set>
  95. where id = #{id,jdbcType=VARCHAR}
  96. </update>
  97. <update id="updateByPrimaryKey" parameterType="com.sica.domain.User">
  98. update user
  99. set username = #{username,jdbcType=VARCHAR},
  100. password = #{password,jdbcType=VARCHAR}
  101. where id = #{id,jdbcType=VARCHAR}
  102. </update>
  103. </mapper></span>
之后,我扩展了一个 Dao 接口,当然,你也可以直接使用 mapper 接口,都是一样的。
Dao 接口
IUserDao
  1. <span style="font-family:Comic Sans MS;font-size:12px;">package com.sica.dao;
  2.  
  3. import com.sica.mapper.UserMapper;
  4.  
  5. /**
  6. * Created by IntelliJ IDEA.
  7. * Package: com.sica.dao
  8. * Name: IUserDao
  9. * User: xiang.li
  10. * Date: 2015/5/22
  11. * Time: 15:25
  12. * Desc: To change this template use File | Settings | File Templates.
  13. */
  14. public interface IUserDao extends UserMapper {
  15.  
  16. }</span>
下面就是 service 和实现层的代码了。
IUserService
  1. <span style="font-family:Comic Sans MS;font-size:12px;">package com.sica.service;
  2.  
  3. import com.sica.domain.User;
  4.  
  5. import java.util.List;
  6.  
  7. /**
  8. * Created by xiang.li on 2015/1/31.
  9. */
  10. public interface IUserService {
  11.  
  12. /**
  13. * 根据Id查询用户对象
  14. * @param id 编号
  15. * @return 用户对象
  16. */
  17. User getUserById(String id);
  18.  
  19. /**
  20. * 根据用户名查询用户对象
  21. * @return List
  22. */
  23. List<User> queryUserList();
  24. }</span>

UserServiceImpl

  1. <span style="font-family:Comic Sans MS;font-size:12px;">package com.sica.service.impl;
  2.  
  3. import com.sica.dao.IUserDao;
  4. import com.sica.domain.User;
  5. import com.sica.service.IUserService;
  6. import org.springframework.stereotype.Service;
  7.  
  8. import javax.annotation.Resource;
  9. import java.util.List;
  10.  
  11. /**
  12. * Created by xiang.li on 2015/1/31.
  13. */
  14. @Service("userService")
  15. public class UserServiceImpl implements IUserService {
  16.  
  17. @Resource
  18. public IUserDao userDao;
  19.  
  20. @Override
  21. public User getUserById(String id) {
  22. return this.userDao.selectByPrimaryKey(id);
  23. }
  24.  
  25. @Override
  26. public List<User> queryUserList() {
  27. return userDao.queryForList();
  28. }
  29.  
  30. }</span>

当然,还有所谓的 applicationContext.xml 配置,不过,我这里叫 spring-mybatis.xml。

  1. <span style="font-family:Comic Sans MS;font-size:12px;"><?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:p="http://www.springframework.org/schema/p"
  5. xmlns:context="http://www.springframework.org/schema/context"
  6. xmlns:mvc="http://www.springframework.org/schema/mvc"
  7. xsi:schemaLocation="http://www.springframework.org/schema/beans
  8. http://www.springframework.org/schema/beans/spring-beans.xsd
  9. http://www.springframework.org/schema/context
  10. http://www.springframework.org/schema/context/spring-context.xsd
  11. http://www.springframework.org/schema/mvc
  12. http://www.springframework.org/schema/mvc/spring-mvc.xsd">
  13.  
  14. <!-- 自动扫描 -->
  15. <context:component-scan base-package="com.sica"/>
  16. <!-- 引入配置文件 -->
  17. <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
  18. p:location="classpath:jdbc.properties"
  19. />
  20.  
  21. <!-- 配置数据库连接池 -->
  22. <!-- 初始化连接大小 -->
  23. <!-- 连接池最大数量 -->
  24. <!-- 连接池最大空闲 -->
  25. <!-- 连接池最小空闲 -->
  26. <!-- 获取连接最大等待时间 -->
  27. <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
  28. p:driverClassName="${jdbc.driver}"
  29. p:url="${jdbc.url}"
  30. p:username="${jdbc.username}"
  31. p:password="${jdbc.password}"
  32. p:initialSize="${jdbc.initialSize}"
  33. p:maxActive="${jdbc.maxActive}"
  34. p:maxIdle="${jdbc.maxIdle}"
  35. p:minIdle="${jdbc.minIdle}"
  36. p:maxWait="${jdbc.maxWait}"
  37. />
  38.  
  39. <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
  40. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" lazy-init="default"
  41. p:dataSource-ref="dataSource"
  42. p:mapperLocations="classpath:com/sica/mapping/*.xml"
  43. />
  44.  
  45. <!-- DAO接口所在包名,Spring会自动查找其下的类 -->
  46. <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"
  47. p:basePackage="com.sica.dao"
  48. p:sqlSessionFactoryBeanName="sqlSessionFactory"
  49. />
  50.  
  51. <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
  52. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
  53. p:dataSource-ref="dataSource"
  54. />
  55. </beans></span>
最后,我用到的是 junit 进行的测试,测试代码如下。

GetUserTest

  1. <span style="font-family:Comic Sans MS;font-size:12px;">package com.sica.user;
  2.  
  3. import com.alibaba.fastjson.JSON;
  4. import com.sica.domain.User;
  5. import com.sica.service.IUserService;
  6. import org.junit.Test;
  7. import org.junit.runner.RunWith;
  8. import org.slf4j.Logger;
  9. import org.slf4j.LoggerFactory;
  10. import org.springframework.test.context.ContextConfiguration;
  11. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  12.  
  13. import javax.annotation.Resource;
  14. import java.util.List;
  15.  
  16. /**
  17. * Created by xiang.li on 2015/2/1.
  18. */
  19. @RunWith(SpringJUnit4ClassRunner.class)
  20. @ContextConfiguration(locations = "classpath:spring-mybatis.xml")
  21. public class GetUserTest {
  22.  
  23. private static String UUID = "3";
  24. @Resource
  25. private IUserService userService;
  26. private static Logger logger = LoggerFactory.getLogger(GetUserTest.class);
  27.  
  28. @Test
  29. public void test() {
  30. User user = userService.getUserById(UUID);
  31. logger.info(JSON.toJSONString(user));
  32. }
  33.  
  34. /**
  35. * 测试联合查询
  36. */
  37. @Test
  38. public void test2() {
  39. List<User> users = userService.queryUserList();
  40. logger.info(JSON.toJSONString(users));
  41. }
  42. }</span>

测试结果

出自:http://blog.csdn.net/happylee6688/article/details/45967763

MyBatis 多表联合查询及优化 以及自定义返回结果集的更多相关文章

  1. MyBatis 多表联合查询,字段重复的解决方法

    MyBatis 多表联合查询,两张表中字段重复时,在配置文件中,sql语句联合查询时使用字段别名,resultMap中对应的column属性使用相应的别名: <resultMap type=&q ...

  2. MyBatis之三:多表联合查询

    在这篇文章里面主要讲解如何在mybatis里面使用一对一.一对多.多表联合查询(类似视图)操作的例子. 注:阅读本文前请先大概看一下之前两篇文章. 一.表结构 班级表class,学生表student, ...

  3. Mybatis oracle多表联合查询分页数据重复的问题

    Mybatis oracle多表联合查询分页数据重复的问题 多表联合查询分页获取数据时出现一个诡异的现象:数据总条数正确,但有些记录多了,有些记录却又少了甚至没了.针对这个问题找了好久,最后发现是由于 ...

  4. mybatis:开发环境搭建--增删改查--多表联合查询(多对一)

    什么是mybatisMyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索.MyBatis使用简单的XML或 ...

  5. mybatis Plus 多表联合查询

    //实体类package com.sk.skkill.entity; import com.baomidou.mybatisplus.annotation.TableField;import com. ...

  6. 一步步学Mybatis-实现多表联合查询(4)

    上一章节中我们已经完成了对单表的CRUD操作,接下来今天这一讲讲述的是关于Mybatis在多表查询时候的应用,毕竟实际业务中也是多表的联合查询比较多嘛~ 还记得最一开始我们新建过一张Website表吗 ...

  7. 你了解MySQL中的多表联合查询吗?

    前言: 多表联合查询,其实就是我们MySQL中的join语句,经常会看到有人说join非常影响性能,不建议使用,你知道这是为什么呢?我们究竟可不可以用呢? 测试数据: CREATE TABLE `t2 ...

  8. yii 多表联合查询的几种方法

    yii多表联合查询, 第一种,用command,自己拼接sql语句执行查询 第二种,用AR,model需继承下面的ar,执行queryall或queryrow方法 <?php //applica ...

  9. MVC5+EF6简单实例---以原有SQLServer数据库两表联合查询为例

    有二三年没写代码了,**内的工作就是这样,容易废人!看到园子里这么多大侠朝气蓬勃的,我想也要学点东西并和大家分享,共同进步!快乐每一天,进步每一天!言归正传! 通过最近一段时间对MVC5.EF6的学习 ...

随机推荐

  1. 三层架构与MVC的区别

    我们平时总是将混为一谈,殊不知它俩并不是一个概念.下面我来为大家揭晓我所知道的一些真相. 首先,它俩根本不是一个概念. 三层架构是一个分层式的软件体系架构设计,它可适用于任何一个项目. MVC是一个设 ...

  2. Spark实战1:shell+独立App使用总结

    Spark改进了Hadoop执行非流式算法的需要多次IO的缺陷,Spark的所有操作都是基于RDD弹性分布式数据集这种数据结构的,对RDD的操作主要的操作包括transform和action两种操作. ...

  3. ctl 里面pdef解说

    WRF 模式MM5 模式都是目前从网上可以下载的气象软件,因此在国内经常可以见到.但这两种模式的数据特点数据的水平网格都不是标准的经纬度网格.需要在ctl 文件中加入PDEF 定义说明把这种非标准的数 ...

  4. C# csv 操作类

    using System.Data; using System.IO; using System.Text; namespace YanZhiwei.DotNet2.Utilities.Common ...

  5. n阶乘 尾数0的个数

    class Solution {public: int trailingZeroes(int n) {            if(n<=0) return 0; int i=0;        ...

  6. linux打开文件数量的查看方法

    linux打开文件数量的查看方法 linux打开文件数量的查看方法在网上查到两种查看linux打开文件数量的查看方法,但结果不相同,linux查看文件打开数量是以那个文件或命令为标准呢? 搜索过关于u ...

  7. weblogic .NoClassDefFoundError: Could not initialize class sun.awt.X11Graphi

    这个是常见问题,可以通过增加Weblogic的启动参数来解决: -Djava.awt.headless=true 你可以修改 startWebLogic.sh 文件. export JAVA_OPTI ...

  8. php socket通信(tcp/udp)

    注意 1.在socket_bind的时候ip地址不能真回环地址如127.0.0.1 2.server.php后台跑起来的时候 nohup php server.php > /var/tmp/a. ...

  9. 关于Oracle过程,函数的经典例子及解析

    一,Oracle中的过程,函数 对于oracle中的过程和函数,个人觉得可以化为一类,因为它们在写法上并没有什么的不同.公式无非就是 create or replace Package_name(pa ...

  10. Oracle绑定变量

    select * from table where id = ? 类似于上面这样的sql,如果不用绑定变量,每次执行时Oracle会认为是不同的sql,会在每次执行时生成一遍执行计划,而执行计划的生成 ...