MyBatis多表联查

这篇文章写了以下几个简单的例子,用来说明MyBatis多标联查基本语法

1.sql片段的用法

2.一对多查询

3.多条sql的一对多查询

4.多对一查询

5.多条sql一对多查询

6、多对多查询

这里沿着接口→小配置的路线写了,测试类就是遍历输出结果:

一、接口:

 1 package cn.sohappy.acourses.course0921;
 2
 3 import cn.sohappy.acourses.bean.BillManyToOne;
 4 import cn.sohappy.acourses.bean.UserOneToMany;
 5 import cn.sohappy.bean.Smbms_user;
 6
 7 import java.util.List;
 8
 9 public interface IUserDAO {
10     //01.sql片段,查询所有user
11     List<Smbms_user> findAll();
12     //02.oneToMany,传入user,返回包含账单信息的user
13     UserOneToMany getUserOneToManyBills(UserOneToMany user);
14     //03.oneToMany,多条sql查询,传入user,返回包含账单信息的user
15     UserOneToMany getUserOneToManyBillsMultiSQL(UserOneToMany user);
16     //04.manyToOne,传入bill,返回包含用户信息的bill
17     BillManyToOne getBillManyToOneUser(BillManyToOne bill);
18     //05.manyToOne,多条sql查询,传入bill,返回包含用户信息的bill
19     BillManyToOne getBillManyToOneUserMultiSQL(BillManyToOne bill);
20 }

二、小配置

先实现第一个方法

1、List<Smbms_user> findAll();查询所有user的编号,名字,密码

小配置的配置头

<?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="cn.sohappy.acourses.course0921.IUserDAO">
    <!--此处是代码-->
</mapper>

以下省略配置头

  <sql id="columns">
        userCode,userName,userPassword
    </sql>
    <resultMap id="mUser" type="cn.sohappy.bean.Smbms_user" autoMapping="false">
        <id property="username" column="userName"/>
        <result property="userpassword" column="userPassword"/>
        <result property="usercode" column="userCode"/>
    </resultMap>
    <!--用<include refid="columns"/>代替*-->
    <select id="findAll" resultMap="mUser">
        select <include refid="columns"/> from smbms_user
    </select>

2、UserOneToMany getUserOneToManyBills(UserOneToMany user);

查询某个用户的账单信息,首先将账单List植入用户类中(第11行)

 1 package cn.sohappy.acourses.bean;
 2
 3 import java.util.List;
 4
 5 public class UserOneToMany {
 6     private Long id;
 7     private String usercode;
 8     private String username;
 9
10     //a user has lots of bills
11     private List<BillManyToOne> bills;
12
13     //getter and setter
14 }

小配置代码:

resultMap中property是对象的属性名,column是数据表中的字段名。collection是UserOneToMany对象中植入的泛型集合属性List<BillManyToOne> bills

语法是:<collection property="bills" ofType="cn.sohappy.acourses.bean.BillManyToOne">...code...</collection>

 1 <!--02.oneToMany-->
 2     <resultMap id="UserOneToManyBills" type="cn.sohappy.acourses.bean.UserOneToMany" autoMapping="false">
 3         <id property="id" column="u_id"/>
 4         <result property="username" column="userName"/>
 5         <collection property="bills" ofType="cn.sohappy.acourses.bean.BillManyToOne">
 6             <id property="id" column="b_id"/>
 7             <result property="productname" column="productName"/>
 8             <result property="billcode" column="billCode"/>
 9         </collection>
10     </resultMap>
11     <select id="getUserOneToManyBills" resultMap="UserOneToManyBills">
12         <!--不好,id重名了,起个别名吧-->
13         select smbms_user.id as u_id,userName,smbms_bill.id as b_id,productName,billCode from smbms_user,smbms_bill
14         where smbms_user.id=smbms_bill.createdBy and userCode=#{usercode}
15     </select>

3、UserOneToMany getUserOneToManyBillsMultiSQL(UserOneToMany user);

该方法通过多条sql查询user和其账单

小配置代码:其中#{**}是占位符

 1 <!--03.oneToMany多条sql-->
 2     <resultMap id="UserOneToManyBillsMultiSQL" type="cn.sohappy.acourses.bean.UserOneToMany" autoMapping="false">
 3         <id property="id" column="id"/>
 4         <result property="username" column="userName"/>
 5         <!--下行的select为第二条sql名,column为第一条sql的字段名,其唯一值作为第二条sql的条件-->
 6         <collection property="bills" ofType="cn.sohappy.acourses.bean.BillManyToOne" select="selectBillsByUser" column="id"/>
 7     </resultMap>
 8     <select id="selectBillsByUser" resultType="cn.sohappy.acourses.bean.BillManyToOne">
 9         select * from smbms_bill where createdBy=#{**}
10     </select>
11     <select id="getUserOneToManyBillsMultiSQL" resultMap="UserOneToManyBillsMultiSQL">
12         select * from smbms_user where userCode=#{usercode}
13     </select>

4、BillManyToOne getBillManyToOneUser(BillManyToOne bill);

传入bill,返回包含用户信息的bill,这里需要在bill类中植入user属性及相应getter and setter:private UserOneToMany user;

小配置代码:这里使用的语法是:<association property="user" javaType="cn.sohappy.acourses.bean.UserOneToMany">...code...</association>

 1 <!--04.manyToOne-->
 2     <resultMap id="BillManyToOneUser" type="cn.sohappy.acourses.bean.BillManyToOne" autoMapping="false">
 3         <id property="id" column="b_id"/>
 4         <result property="billcode" column="billCode"/>
 5         <association property="user" javaType="cn.sohappy.acourses.bean.UserOneToMany">
 6             <id property="id" column="u_id"/>
 7             <result property="usercode" column="userCode"/>
 8             <result property="username" column="userName"/>
 9         </association>
10     </resultMap>
11     <select id="getBillManyToOneUser" resultMap="BillManyToOneUser">
12         select smbms_user.id as u_id,userCode,userName,smbms_bill.id as b_id,billCode from smbms_user,smbms_bill
13         where smbms_user.id=smbms_bill.createdBy and billCode=#{billcode}
14     </select>

5.BillManyToOne getBillManyToOneUserMultiSQL(BillManyToOne bill);多条sql多对一查询

小配置代码:

 1 <!--05.manyToOne多条sql-->
 2     <resultMap id="BillManyToOneUserMultiSQL" type="cn.sohappy.acourses.bean.BillManyToOne" autoMapping="false">
 3         <id property="id" column="id"/>
 4         <result property="billcode" column="billCode"/>
 5         <association property="user" javaType="cn.sohappy.acourses.bean.UserOneToMany" autoMapping="false" select="selectUserByCreatedBy" column="CreatedBy">
 6             <id property="id" column="id"/>
 7             <result property="usercode" column="userCode"/>
 8             <result property="username" column="userName"/>
 9         </association>
10     </resultMap>
11     <select id="selectUserByCreatedBy" resultType="cn.sohappy.acourses.bean.UserOneToMany">
12         select * from smbms_user where id=#{**}
13     </select>
14     <!--这里需要查找公共字段createdBy作为association中的column参数-->
15     <select id="getBillManyToOneUserMultiSQL" resultMap="BillManyToOneUserMultiSQL">
16         select id,billCode,createdBy from smbms_bill where billCode=#{billcode}
17     </select>

最后写下多对多查询

其实多对多查询和一对多查询是一样的,只不过表中可能没有公共字段,要借助第三张表。

举个例子:根据老师id查询他所教授学生的id

下面建立三张表:

这是student表

这是老师表

这是第三张表

步骤和一对多是一样的,先生成实体类,然后在老师中植入学生List

创建接口,写个方法:

1 package cn.sohappy.acourses.course0923;
2
3 import cn.sohappy.acourses.bean.Teachert14;
4
5 public interface ITeacherDAO {
6     Teachert14 findStudentsByTeacher(Teachert14 teacher);
7 }

下面直接写小配置了:

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE mapper
 3         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 4         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5 <mapper namespace="cn.sohappy.acourses.course0923.ITeacherDAO">
 6     <resultMap id="mTeacher" type="cn.sohappy.acourses.bean.Teachert14">
 7         <id property="tid" column="tid"/>
 8         <result property="tname" column="tname"/>
 9         <collection property="studentt14s" ofType="cn.sohappy.acourses.bean.Studentt14">
10             <id property="sid" column="sid"/>
11             <result property="sname" column="sname"/>
12         </collection>
13     </resultMap>
14     <select id="findStudentsByTeacher" resultMap="mTeacher">
15         select studentt14.sid,sname,teachert14.tid,tname from studentt14,teachert14,teacher_studentt14
16         where studentt14.sid=teacher_studentt14.sid and teachert14.tid=teacher_studentt14.tid
17         and teachert14.tid=#{tid}
18     </select>
19 </mapper>

最后附上测试类和MyBatis工具类:

测试类:

 1 package cn.test;
 2
 3 import cn.sohappy.acourses.bean.Studentt14;
 4 import cn.sohappy.acourses.bean.Teachert14;
 5 import cn.sohappy.acourses.course0923.ITeacherDAO;
 6 import cn.sohappy.util.MyBatisUtil;
 7 import org.apache.ibatis.session.SqlSession;
 8 import org.junit.Test;
 9
10 public class test20170923 {
11     //多对多,借助第三张表
12     @Test
13     public void findStudentsByTeacher(){
14         SqlSession session = MyBatisUtil.getSession();
15         ITeacherDAO mapper = session.getMapper(ITeacherDAO.class);
16         Teachert14 teachert14 = new Teachert14();
17         teachert14.setTid(1L);
18         Teachert14 teacher = mapper.findStudentsByTeacher(teachert14);
19         for (Studentt14 item:teacher.getStudentt14s()) {
20             System.out.println(item.getSname());
21         }
22     }
23 }

MyBatis工具类:

 1 package cn.sohappy.util;
 2
 3 import org.apache.ibatis.io.Resources;
 4 import org.apache.ibatis.session.SqlSession;
 5 import org.apache.ibatis.session.SqlSessionFactory;
 6 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 7
 8 import java.io.IOException;
 9 import java.io.InputStream;
10
11 public class MyBatisUtil {
12     private static InputStream is;
13     private static SqlSessionFactory sqlSessionFactory;
14     static {
15         try {
16             is=Resources.getResourceAsStream("mybatis-config.xml");
17         } catch (IOException e) {
18             e.printStackTrace();
19         }
20         sqlSessionFactory= new SqlSessionFactoryBuilder().build(is);
21     }
22     private MyBatisUtil(){}
23     public static SqlSession getSession(){
24         return sqlSessionFactory.openSession();
25     }
26 }
时间: 2024-10-06 05:26:49

MyBatis多表联查的相关文章

使用mybatis多表联查的时候结果异常及springmvc的理解

今天使用mybatis多表联查的时候,在dos窗口查询时可以出结果集,但是使用mybatis查询的时候最后返回的结果只有最后一个结果 然后研究了半天没弄出来,后来无意中发现添加了最外层从表的ID字段后结果就查出来了,由此可见,数据是由主键来区分的,当主键不在查询范围时,数据默认调用最后一条语句 另外使用springmvc时无法使用实例化service对象,会报空指针异常

SpringBoot整合mybatis多表联查之数据库建表

1.各关联表尽量不要使用相同的字段.因为在多表联查时,如果出现相同的字段,数据库自动使这些相同字段的值相等. 比如说,订单表有一个表示订单状态的status字段,而它的外键关联的表car有一个表示车状态的status字段,这两个status表示的含义完全不一样,但因为两个status字段一样,数据库默认将他们的值相等,导致数据失真. 2.在mapper.xml文件中使用的sql语句,应先在数据库测试成功后才使用. 3.在运行整个项目之前,应先对各个mapper,service,controlle

mybatis.net 多表联查

mybatis.net针对多表联查,其实不用讲联查出的所有的列全部做一个新的resultMap,我们完全可以通过集成关系来实现,真是上一次说的懒加载,在一定程度上可以提高其性能,但这并不是说懒加载性能一定就差,他有其自己的用途,比如我们只需要查询主表的一条记录,但是在从表中却有1000条记录,就比较适合用懒加载. 参见http://www.cnblogs.com/zuolijun/p/5443823.html <resultMap id="teamMemberPermissionDocto

MyBatis(四)关于多表联查 关联关系之一--------一对多(单条sql语句查询)

在MyBatis中,进行多表联查时关联关系主要有这几种:一对多,多对一,多对多,还有一种自关联 1.一对多:有两种方式 (1)用一条sql语句进行查询    (以查询部门和员工为案例) 首先创建实体类 package entity; import java.util.List; /** * Created by mycom on 2018/2/26. */ public class Dept {//部门 private Integer deptNo; private String deptNam

使用mybatis进行多表联查

一.使用mybatis的基本步骤 1.导入jar包 2.配置文件 3.使用配置文件完成操作 二.实战演习 需求:教师表里有教师id和教师姓名 学生表里有学生id,姓名,年龄,教师id 一个教师有多个学生,一个学生只有一个教师,现在需要显示学生表的学生信息和教师姓名 1.导入jar包 2.导入配置文件,mybatis和log4j都是写了一次以后随便用 这些都是写死了的,直接配好即可 三.开始多表联查 1.业务装配方式,分为两步, 1.1查询所有的学生, 1.2根据学生的tid得到教师的信息存入学生

五表联查sql和复选框 增删改查

这是五表联查的效果图,如果这个不明显,那么用添加说话 这样就明显了把 这个送餐时间和地点,都是一对多的,那么这个菜单就是多对多,其实对于老鸟来说没有什么大不了,但是对于新手,我希望还是可以有点帮助的,这个是用Mybatis写的 首先我们先把sql给贡献出来,或许有些丑,不过,这反正也是给自己写的随笔无所谓了 select a.*,b.fname from    (select a.*,c.aname from (select a.*,b.name tname from    t_order a,

Mybatis多表查询之一对一查询的多种实现-XML配置

Mybatis 中对于多表查询提供了非常强大的实现方式,主要是通过resultMap的结果映射对于多表查询后的返回值进行封装,让我们来看一下官网上对于resultMap的解释:resultMap 元素是 MyBatis 中最重要最强大的元素.它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来,并在一些情形下允许你进行一些 JDBC 不支持的操作.实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份 resultMap 能够代替实现同等功能的长达数千行的代码.R

mybatis(单表增删改查)

(mybatis注意各个文件的映射问题) 用到的t_user数据库脚本: -- 导出 mybatis 的数据库结构 CREATE DATABASE IF NOT EXISTS `mybatis` /*!40100 DEFAULT CHARACTER SET utf8 */; USE `mybatis`; -- 导出 表 mybatis.t_user 结构 CREATE TABLE IF NOT EXISTS `t_user` ( `id` int(10) NOT NULL AUTO_INCREM

mybatis(单表增删改查useMapper版)

数据库脚本(注意测试时先add-->load-->update-->delete-->list)UserMapper版 -- -------------------------------------------------------- -- 主机: 127.0.0.1 -- 服务器版本: 5.5.36-MariaDB - mariadb.org binary distribution -- 服务器操作系统: Win32 -- HeidiSQL 版本: 8.0.0.4396 --