步骤

  1. 建立两张表:用户表。账户表

    1. 让用户表和账户表之间具备一对多的关系:需要使用外键在账户表中添加
  2. 建立两个实体类:用户实体类和账户实体类
    1. 让用户和账户的实体类能体现出一对多的关系
  3. 建立两个配置文件
    1. 用户配置文件
    2. 账户配置文件
  4. 实现配置
    1. 当我们查询用户时,可以同时得到用户下所包含的账户信息
    2. 当我们查询账户时,可以同时得到账户的所属用户信息。

建立用户表和账户表

  1. 建立用户表
create table mybatisuser(id int(11) not null auto_increment,username varchar(32) not null comment '用户名称',birthday datetime default null comment '生日',sex char(1) default null comment '性别',address varchar(256) default null comment '地址',primary key (id)
)engine=innoDB default charset=utf8;
  1. 建立账户表
DROP TABLE IF EXISTS ACCOUNT;
CREATE TABLE ACCOUNT(id INT(11) NOT NULL COMMENT '编号',uid INT(11) DEFAULT NULL COMMENT '用户编号',money DOUBLE DEFAULT NULL COMMENT '金额',PRIMARY KEY (id),KEY FK_Reference_8 (uid),CONSTRAINT FK_Reference_8 FOREIGN KEY (uid) REFERENCES mybatisuser (id)
)ENGINE=INNODB DEFAULT CHARSET=utf8;
  1. 查询所有账户同时包含用户名和地址

    1. 创建实体类
    public class AccountUser extends Account {private String username;private String address;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic String toString() {return super.toString() + "AccountUser{" +"username='" + username + '\'' +", address='" + address + '\'' +'}';}
    }
    
    1. sql语句
       <select id="findAllAccount" resultType="domain.AccountUser">SELECT a.*,u.username,u.address FROM ACCOUNT a, mybatisuser u WHERE a.uid=u.id;</select>
    

一对一查询

  1. 从表实体类应该包含一个主表实体类的对象引用
public class Account implements Serializable {private int id;private int uid;private double money;//从表实体类应该包含一个主表实体类的对象引用private MybatisUser mybatisUser;public MybatisUser getMybatisUser() {return mybatisUser;}public void setMybatisUser(MybatisUser mybatisUser) {this.mybatisUser = mybatisUser;}public int getId() {return id;}public void setId(int id) {this.id = id;}public int getUid() {return uid;}public void setUid(int uid) {this.uid = uid;}public double getMoney() {return money;}public void setMoney(double money) {this.money = money;}@Overridepublic String toString() {return "Account{" +"id=" + id +", uid=" + uid +", money=" + money +'}';}
}
  1. 定义封装account和user的resultMap
<resultMap id="accountUserMap" type="domain.Account"><id property="id" column="aid"></id><result property="uid" column="uid"></result><result property="money" column="money"></result><!--一对一的关系映射,配置封装user的内容--><association property="mybatisUser" column="uid"><id property="id" column="id"></id><result property="username" column="username"></result><result property="birthday" column="birthday"></result><result property="sex" column="sex"></result><result property="address" column="address"></result></association>
</resultMap>
  1. sql语句
<select id="findAll" resultMap="accountUserMap">SELECT u.*,a.id as aid,a.uid,a.money FROM ACCOUNT a, mybatisuser u WHERE a.uid=u.id;
</select>
  1. 编写方法
public void testFindAll(){//5. 使用代理对象执行方法List<Account> accounts = accountDao.findAll();for (Account account : accounts){System.out.println("账户"+account.getId()+"----------------------------");System.out.println(account);System.out.println(account.getMybatisUser());}
}
  1. 查询结果

一对多查询

  1. 一对多映射,主表实体类应包含从表实体类的集合引用
public class UserAccount implements Serializable {private Integer id;private String username;private Date birthday;private String sex;private String address;//一对多映射,主表实体类应包含从表实体类的集合引用private List<Account> accounts;public List<Account> getAccounts() {return accounts;}public void setAccounts(List<Account> accounts) {this.accounts = accounts;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUserName() {return username;}public void setName(String name) {this.username = name;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic String toString() {return "MybatisUser{" +"id=" + id +", name='" + username + '\'' +", birthday=" + birthday +", sex='" + sex + '\'' +", address='" + address + '\'' +'}';}
}
  1. 定义UserAccount的resultMap
<!-- 定义UserAccount的resultMap-->
<resultMap id="userAccountMap" type="domain.UserAccount"><id property="id" column="id"></id><result property="username" column="username"></result><result property="birthday" column="birthday"></result><result property="sex" column="sex"></result><result property="address" column="address"></result><!--一对多的关系映射,配置UserAccount对象中accounts集合的内容--><collection property="accounts" ofType="domain.Account"><id property="id" column="aid"></id><result property="uid" column="uid"></result><result property="money" column="money"></result></collection>
</resultMap>
  1. sql语句
<select id="findAll" resultMap="userAccountMap">SELECT u.*,a.id as aid,a.uid,a.money FROM mybatisuser u left outer join account a on u.id=a.uid;
</select>
  1. 编写查询方法
public void testFindAll(){//5. 使用代理对象执行方法List<UserAccount> users = userDao.findAll();for (UserAccount user : users){System.out.println("用户"+user.getId()+"--------------------");System.out.println(user);System.out.println(user.getAccounts());}
}
  1. 查询结果

多对多查询

  1. 步骤

    1. 建立两张表:用户表,角色表

      1. 让用户表和账户表之间具备多对多的关系:需要使用中间表,中间表包含各自的主键,在中间表中是外键。
    2. 建立两个实体类:用户实体类和角色实体类
      1. 让用户和角色的实体类能体现出多对多的关系
      2. 各自包含对方一个集合引用
    3. 建立两个配置文件
      1. 用户配置文件
      2. 角色配置文件
    4. 实现配置
      1. 当我们查询用户时,可以同时得到用户所包含的角色信息
      2. 当我们查询账户时,可以同时得到角色所赋予的用户信息
  2. 建表

    1. 建立角色表
    DROP TABLE IF EXISTS `role`;CREATE TABLE `role` (
    `ID` INT(11) NOT NULL COMMENT '编号',
    `ROLE_NAME` VARCHAR(30) DEFAULT NULL COMMENT '角色名称',
    `ROLE_DESC` VARCHAR(60) DEFAULT NULL COMMENT '角色描述',
    PRIMARY KEY  (`ID`)
    ) ENGINE=INNODB DEFAULT CHARSET=utf8;INSERT  INTO `role`(`ID`,`ROLE_NAME`,`ROLE_DESC`) VALUES (1,'系主任','管理整个系'),(2,'院长','管理整个学院'),(3,'校长','管理整个学校');
    
    1. 建立中间表
    DROP TABLE IF EXISTS `user_role`;CREATE TABLE `user_role` (
    `UID` INT(11) NOT NULL COMMENT '用户编号',
    `RID` INT(11) NOT NULL COMMENT '角色编号',
    PRIMARY KEY  (`UID`,`RID`),
    KEY `FK_Reference_10` (`RID`),
    CONSTRAINT `FK_Reference_10` FOREIGN KEY (`RID`) REFERENCES `role` (`ID`),
    CONSTRAINT `FK_Reference_9` FOREIGN KEY (`UID`) REFERENCES `mybatisuser` (`id`)
    ) ENGINE=INNODB DEFAULT CHARSET=utf8;INSERT  INTO `user_role`(`UID`,`RID`) VALUES (2,1),(4,1),(2,2),(5,3),(6,1),(1,2),(4,2);
    
  3. 查询角色,同时得到该角色下的所有用户

    1. 创建角色实体类,同时包含用户的集合
    public class RoleUser implements Serializable {private Integer roleId;private String roleName;private String roleDesc;//生成多对多关系private List<UserRole> userRoles;public List<UserRole> getUserRoles() {return userRoles;}public void setUserRoles(List<UserRole> userRoles) {this.userRoles = userRoles;}public Integer getRoleId() {return roleId;}public void setRoleId(Integer roleId) {this.roleId = roleId;}public String getRoleName() {return roleName;}public void setRoleName(String roleName) {this.roleName = roleName;}public String getRoleDesc() {return roleDesc;}public void setRoleDesc(String roleDesc) {this.roleDesc = roleDesc;}@Overridepublic String toString() {return "RoleUser{" +"roleId=" + roleId +", roleName='" + roleName + '\'' +", roleDesc='" + roleDesc + '\'' +'}';}
    }
    
    1. 创建RoleUserDao接口
    public interface RoleUserDao {List<RoleUser> findAll();}
    
    1. 定义resultMap
    <resultMap id="roleUserMap" type="domain.RoleUser"><id property="roleId" column="rid"></id><result property="roleName" column="role_name"></result><result property="roleDesc" column="role_desc"></result><!--多对多的关系映射,配置封装user的内容--><collection property="userRoles" ofType="domain.UserRole"><id property="id" column="id"></id><result property="username" column="username"></result><result property="birthday" column="birthday"></result><result property="sex" column="sex"></result><result property="address" column="address"></result></collection>
    </resultMap>
    
    1. sql语句
    <select id="findAll" resultMap="roleUserMap">SELECT u.*,r.id as rid,r.role_name,r.role_desc FROM role rleft outer join user_role ur on r.id=ur.ridleft outer join mybatisuser u on u.id=ur.uid;
    </select>
    
    1. 编写方法
    public class RoleUserTest {public static void main(String[] args) throws IOException {}private InputStream in;private SqlSession sqlSession;private RoleUserDao roleUserDao;@Beforepublic void init() throws IOException {//1. 读取配置文件in = Resources.getResourceAsStream("SqlMapConfig.xml");//2. 使用ServletContext对象的getRealPath()//2. 创建SqlSessionFactory工厂SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();SqlSessionFactory factory = sqlSessionFactoryBuilder.build(in);//3. 使用工厂生产SqlSession对象sqlSession = factory.openSession();//4. 使用SqlSession创建Dao接口的代理对象roleUserDao = sqlSession.getMapper(RoleUserDao.class);}@Afterpublic void destory() throws IOException {//6.事务的提交sqlSession.commit();//7. 释放资源sqlSession.close();in.close();}@Testpublic void testFindAll(){//5. 使用代理对象执行方法List<RoleUser> roleUsers = roleUserDao.findAll();for (RoleUser roleUser : roleUsers){System.out.println("角色"+roleUser.getRoleId()+"--------------------");System.out.println(roleUser);System.out.println(roleUser.getUserRoles());}}
    }
    
    1. 输出结果
  4. 查询所有用户,同时得到该用户的所有角色信息

    1. 创建user实体类,同时包含角色集合
    public class UserRole implements Serializable {private Integer id;private String username;private Date birthday;private String sex;private String address;//生成多对多映射关系private List<RoleUser> roleUsers;public List<RoleUser> getRoleUsers() {return roleUsers;}public void setRoleUsers(List<RoleUser> roleUsers) {this.roleUsers = roleUsers;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic String toString() {return "UserRole{" +"id=" + id +", username='" + username + '\'' +", birthday=" + birthday +", sex='" + sex + '\'' +", address='" + address + '\'' +'}';}
    }
    
    1. 创建UserRoleDao接口
    public interface UserRoleDao {List<UserRole> findAll();}
    
    1. 定义resultMap
    <resultMap id="userRoleMap" type="domain.UserRole"><id property="id" column="id"></id><result property="username" column="username"></result><result property="birthday" column="birthday"></result><result property="sex" column="sex"></result><result property="address" column="address"></result><!--一对一的关系映射,配置封装user的内容--><collection property="roleUsers" ofType="domain.RoleUser"><id property="roleId" column="rid"></id><result property="roleName" column="role_name"></result><result property="roleDesc" column="role_desc"></result></collection>
    </resultMap>
    
    1. 定义sql语句
    <select id="findAll" resultMap="userRoleMap">SELECT r.id as rid,r.role_name,r.role_desc,u.* FROM mybatisuser uleft outer join user_role ur on u.id=ur.uidleft outer join role r on r.id=ur.rid;
    </select>
    
    1. 编写测试方法
    public class UserRoleTest {public static void main(String[] args) throws IOException {}private InputStream in;private SqlSession sqlSession;private UserRoleDao userRoleDao;@Beforepublic void init() throws IOException {//1. 读取配置文件in = Resources.getResourceAsStream("SqlMapConfig.xml");//2. 使用ServletContext对象的getRealPath()//2. 创建SqlSessionFactory工厂SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();SqlSessionFactory factory = sqlSessionFactoryBuilder.build(in);//3. 使用工厂生产SqlSession对象sqlSession = factory.openSession();//4. 使用SqlSession创建Dao接口的代理对象userRoleDao = sqlSession.getMapper(UserRoleDao.class);}@Afterpublic void destory() throws IOException {//6.事务的提交sqlSession.commit();//7. 释放资源sqlSession.close();in.close();}@Testpublic void testFindAll(){//5. 使用代理对象执行方法List<UserRole> userRoles = userRoleDao.findAll();for (UserRole userRole : userRoles){System.out.println("用户"+userRole.getId()+"--------------------");System.out.println(userRole);System.out.println(userRole.getRoleUsers());}}
    }
    
    1. 输出结果

JNDI

  1. 基本概念

    1. JNDI(Java Naming and Directory Interface,Java命名和目录接口)是SUN公司提供的一种标准的Java命名系统接口
    2. JNDI仿windows的注册表,通过key:value实现
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TBAg2OHA-1610768096586)(JNDI.png)]
  2. 新建MAVEN-webapp工程,配置目录
  3. 导入依赖
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.5</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.21</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.5</version></dependency><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.2</version></dependency>
  1. 配置Mybatis主配置文件SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><typeAliases><package name="domain"/></typeAliases><environments default="mysql"><environment id="mysql"><transactionManager type="JDBC"/><dataSource type="JNDI"><property name="data_source" value="java:comp/env/jdbc/my_jndi_test"/></dataSource></environment></environments><mappers><mapper resource="dao/MybatisUserDao.xml"/></mappers>
</configuration>
  1. 在webapp目录下新建目录MATE-INF,在MATE-INF下创建context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<!--
<Resource
name="jdbc/my_jndi_test"                                    数据源的名称
type="javax.sql.DataSource"                                 数据源类型
auth="Container"                                            数据源提供者
maxActive="20"                                              最大活动数
maxWait="10000"                                             最大等待时间
maxIdle="5"                                                 最大空闲数
username="root"                                             用户名
password="fy123"                                            密码
driverClassName="com.mysql.cj.jdbc.Driver"                  驱动类
url="jdbc:mysql://localhost:3306/my_db?serverTimezone=UTC"  连接url字符串
/>-->
<Resource
name="jdbc/my_jndi_test"
type="javax.sql.DataSource"
auth="Container"
maxActive="20"
maxWait="10000"
maxIdle="5"
username="root"
password="fy123"
driverClassName="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://localhost:3306/my_db?serverTimezone=UTC"
/>
</Context>
  1. 编写index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ page import="org.apache.ibatis.io.Resources" %>
<%@ page import="org.apache.ibatis.session.SqlSessionFactoryBuilder" %>
<%@ page import="org.apache.ibatis.session.SqlSessionFactory" %>
<%@ page import="dao.MybatisUserDao" %>
<%@ page import="domain.MybatisUser" %>
<%@ page import="java.util.List" %>
<%@ page import="java.io.InputStream" %>
<%@ page import="org.apache.ibatis.session.SqlSession" %>
<html>
<body>
<h2>Hello World!</h2>
<%InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();SqlSessionFactory factory = sqlSessionFactoryBuilder.build(in);SqlSession sqlSession = factory.openSession();MybatisUserDao userDao = sqlSession.getMapper(MybatisUserDao.class);List<MybatisUser> users = userDao.findAll();for (MybatisUser user : users){System.out.println(user);}sqlSession.close();in.close();
%>
</body>
</html>

Mybatis多表查询相关推荐

  1. MyBatis多表查询之XML和注解实现(resultMap结果集映射配置数据库字段与实体类属性一一映射)

    MyBatis多表查询 多表模型分类 一对一:在任意一方建立外键,关联对方的主键. 一对多:在多的一方建立外键,关联一的一方的主键. 多对多:借助中间表,中间表至少两个字段,分别关联两张表的主键. 数 ...

  2. Mybatis—多表查询

    Mybatis多表查询 一对一查询 一对一查询的模型MapperScannerConfigurer 用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户 创建Order和User实体 ...

  3. java day55【 Mybatis 连接池与事务深入 、 Mybatis 的动态 SQL 语句、 Mybatis 多表查询之一对多 、 Mybatis 多表查询之多对多】...

    第1章 Mybatis 连接池与事务深入 1.1 Mybatis 的连接池技术 1.1.1 Mybatis 连接池的分类 1.1.2 Mybatis 中数据源的配置 1.1.3 Mybatis 中 D ...

  4. mybatis多表查询(一对多,多对一,多对多)

    mybatis多表查询.多对一,一对多,多对多 多对一.一对多 准备阶段 建立dept实体类和emp实体类 建立Dao接口 写Dao的Mapper映射 多对多 多对一.一对多 准备阶段 建立一个部门表 ...

  5. 7. MyBatis多表查询 - 一对一 - 一对多 - 多对多

    7. MyBatis多表查询 - 一对一 - 一对多 - 多对多 前言 在前面的篇章,我们已经熟悉了单表查询,下面我们来看看如何进行 多表查询. 数据准备 create database if not ...

  6. Mybatis多表查询之一对多、多对一

    目录 前言 一.建立数据库 二.多对一查询 2.1 编写实体类 2.2 编写接口 2.3 编写Mapper配置文件 (StudentMapper.xml) 2.4 多对一查询结果 三.一对多查询 3. ...

  7. mybatis联表查询且统计数据

    mybatis联表查询且统计数据 表1的数据+表2的数据的统计==>vo接收 前端原型图如下: 涉及到两张表 t_record t_user_record 详情A/B A:未签收人数 B:全部人 ...

  8. 7.Mybatis关联表查询(这里主要讲的是一对一和一对多的关联查询)

    视频地址:http://edu.51cto.com/sd/be679 在Mybatis中的管理表查询这里主要介绍的是一对一和一对多的关联查询的resultMap的管理配置查询,当然你也可以用包装类来实 ...

  9. Mybatis学习笔记 4:Mybatis 连表查询(一)——一对多关系

    完整代码在这 在查询数据库时,我们经常会遇到多张表联合查询的情况,而Mybatis使连表查询更加简便了,查询出的数据格式非常易于使用,省去了一大部分复杂的代码编写工作,对于关系型数据库来说,数据模型之 ...

  10. mybatis多表查询出来的实体如何映射_mybatis进阶案例之多表查询

    mybatis进阶案例之多表查询 一.mybatis中表之间的关系 在数据库中,实体型之间的关系主要有如下几种: 1.一对一 如果对于实体集A中的每一个实体,实体集B中至多有一个(也可以没有)实体与之 ...

最新文章

  1. Ubuntu 14.04安装搜狗拼音linux版应该注意的问题
  2. vista——最恰当的中文译名应该是“喂死它”
  3. R语言rpartb包树回归模型构建:基于乳腺癌(breast cancer)数据集
  4. Android 如何判断CPU是32位还是64位
  5. 一招解决迅雷5不更新无法继续使用原创
  6. 电商购物网站开发需要注意这些问题
  7. opencv cv::mat::data是什么数据类型?
  8. python学习笔记:第19天 类的约束、异常、MD5和logging
  9. java线程的创建与执行_Java多线程的创建和运行
  10. 网络中的计算机之间的关系,有关服务器与主机之间的关系
  11. 保障实时音视频服务体验,华为云原生媒体网络有7大秘籍
  12. #华为云·寻找黑马程序员#【代码重构之路】如何“消除”if/else
  13. oracle连接工具类,c# .net oracle连接工具类
  14. C#的排序算法以及随机产生不重复数字的几个Demo
  15. 因为某种原因阻止文本引擎初始化_文成县搜索引擎优化如何,神马SEO优化_万推霸屏...
  16. 【Shell脚本学习7】Shell脚本学习指南分享
  17. AMD IOMMU与Linux (2) -- IVRS及AMD IOMMU硬件初始化
  18. 测量脉冲调制信号的绝对和加性相位噪声
  19. 彻底搞懂内存屏障(上)
  20. lisp不是函授型语言_lisp语言的定义

热门文章

  1. kivy打包问题汇总
  2. Git安装步骤嗷,详细到每一步
  3. 棒棒糖c语言编译器,用C语言画个棒棒糖-一言不合就分享!代!码
  4. feng 的模块(框架)以及运作过程
  5. FPGA图像处理学习——基于肤色的人脸识别
  6. 修改simple_peripheral_oad_offchip的 Bootloader
  7. matlab中ss函数_matlab ss函数 tf函数
  8. 一篇对大数据深度思考的文章,让你认识并读懂大数据
  9. Kubernetes 网络训练营第2期 | 明晚开课
  10. 这6个自学网站在知乎得到40万的热推!凭什么?看了就知道!