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

定义账户信息的实体类Account 

public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money; /*get set toString*/
}

User

public class User implements Serializable {

    private Integer id;
private String username;
private String address;
private String sex;
private Date birthday;
  /*get  set toString*/
}

用户的持久层接口IuserDao:

public interface IUserDao {
List<User> findAll();
User findUserById (Integer userId);
}

IAccountDao:

public interface IAccountDao {
/**
* 查询所有账户
* @return
*/
List<Account> findAll();
}

映射配置文件IUserDao.xml:

<?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="com.mkl.dao.IUserDao"> <!-- 查询所有 -->
<select id="findAll" resultType="user">
select * from user;
</select> <!-- 根据id查询用户 -->
<select id="findUserById" parameterType="int" resultType="user">
select * from user where id = #{uid}
</select> </mapper>

IAccountDao.xml:

<?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="com.mkl.dao.IAccountDao">
<!-- 查询所有账户信息-->
<select id="findAll" resultType="Account">
select * from account;
</select>
</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>
<!-- 配置properties-->
<properties resource="jdbcConfig.properties"></properties> <!--使用typeAliases配置别名,它只能配置domain中类的别名 -->
<typeAliases>
<package name="com.mkl.domain"></package>
</typeAliases> <!--配置环境-->
<environments default="mysql">
<!-- 配置mysql的环境-->
<environment id="mysql">
<!-- 配置事务 -->
<transactionManager type="JDBC"></transactionManager> <!--配置连接池-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</dataSource>
</environment>
</environments>
<!-- 配置映射文件的位置 -->
<mappers>
<package name="com.mkl.dao"></package>
</mappers>
</configuration>

一对一查询(多对一)

需求 :

查询所有账户信息,关联查询对应用户信息。

注意: 

因为一个账户信息只能供某个用户使用,所以从查询账户信息出发关联查询用户信息为一对一查询。

如果从用户信息出发查询用户下的账户信息则为一对多查询,因为一个用户可以有多个账户。

方式一 :

编写 Sql 语句

实现查询账户信息时,也要查询账户所对应的用户信息。

SELECT    account.*,   user.username,   user.address

FROM   account,   user

WHERE  account.uid = user.id ;

查询结果

定义 AccountUser 类

为了能够封装上面 SQL 语句的查询结果,定义 AccountCustomer 类中要包含账户信息同时还要包含用户信息

所以我们要在定义 AccountUser 类时可以继承Account 类。

public class AccountUser extends Account implements Serializable {
/*继承了Account中的信息*/
private String username;
private String address; /*get set super.toString+toString*/
}

账户的持久层接口 IAccountDao中添加方法

    /**
* 查询所有账户 同时获取到当前账户的所属用户信息: 用户名称 地址
* @return
*/
List<AccountUser> findAllEnhance();

在 IAccountDao.xml 文件中添加相应的的查询配置信息

 <!--增强的查询所有账户信息, 包含账户信息, 用户名称 地址-->
<select id="findAllEnhance" resultType="AccountUser">
select account.*, user.username as username,user.address as address
   from account,user
   where user.id=account.uid;
</select>

添加测试方法

   /**
* 测试增强的查询所有账户信息, 包含账户信息, 用户名称 地址
*/
@Test
public void testFindAllAccountEnhance(){
List<AccountUser> accountUsers=accountDao.findAllEnhance ();
System.out.println (accountUsers);
}

方式二(常用):

让用户和账户的实体类能体现出来一对多的关系

使用 resultMap,定义专门的 resultMap 用于映射一对一查询结果

一对一的关系映射 使用association标签

在从表实体类Account中添加主表实体的对象引用

从表实体应该包含一个主表实体的对象引用

        //从表实体应该包含一个主表实体的对象引用
private User user; /*get set*/

IAccountDao 接口中的方法

   /**
* 查询所有账户 同时获取账户的所属用户信息
* @return
*/
List<Account> findAll();

修改IAccountDao.xml 文件

<!--定义封装account和user的resultMap-->
<resultMap id="accountUserMap" type="account">
<id column="aid" property="id"></id>
<result column="uid" property="uid"></result>
<result column="money" property="money"></result>
<!--一对一的关系映射, 配置封装User的内容-->
<association property="user" javaType="user">
<id column="id" property="id"></id>
<result column="username" property="username"></result>
<result column="sex" property="sex"></result>
<result column="birthday" property="birthday"></result>
<result column="address" property="address"></result>
</association>
</resultMap> <!-- 查询所有账户信息-->
<select id="findAll" resultMap="accountUserMap">
select user.*,account.id as aid, account.uid ,account.money
from account,user
where user.id=account.uid;
</select>

一对多查询

需求:

查询所有用户信息及用户关联的账户信息。

分析: 

用户信息和他的账户信息为一对多关系

并且查询过程中如果用户没有账户信息,此时也要将用户信息查询出来,我们想到了 左外连接查询 比较合适。

编写 SQL 语句 :

SELECT user.*, account.id AS aid,account.uid,account.money
FROM USER
LEFT JOIN account
ON user.id = account.uid ;

User 类加入 List<Account>

一对多关系映射, 主表实体应该包含从表实体的集合引用

private List<Account> accounts;

/*get set*/

持久层接口IUserDao中的查询方法

/**
* 查询所有用户,同时获取出每个用户下的所有账户信息
* @return */
List<User> findAll();

修改持久层接口的映射配置文件IUserDao.xml

  <resultMap id="userMap" type="user">
    <id column="id" property="id"></id>
    <result column="username" property="username"/>
    <result column="address" property="address"/>
    <result column="sex" property="sex"/>
    <result column="birthday" property="birthday"/>
    <!--封装该用户下的账户信息到List-->
    <!--collection是用于建立一对多中集合属性的对应关系, ofType用于指定集合元素的数据类型-->
    <collection property="accounts" ofType="account">
      <id column="aid" property="id"/>
      <result column="uid" property="uid"/>
      <result column="money" property="money"/>
    </collection>
  </resultMap> <!-- 查询所有 -->
<!--<select id="findAll" resultType="user">-->
<select id="findAll" resultMap="userMap">
SELECT user.*, account.id AS aid,account.uid,account.money
FROM USER
LEFT JOIN account
ON user.id = account.uid ;
</select>

collection   用于建立一对多中集合属性的对应关系  表示关联查询结果集 

  property="accounts"  关联查询的结果集存储在 User 对象的上哪个属性。

  ofType="account"   指定关联查询的结果集中的对象类型即List中的对象类型。此处可以使用别名,也可以使用全限定名。

Mybatis中的多表查询 多对一,一对多的更多相关文章

  1. Mybatis中的多表查询 多对多

    示例:用户和角色 一个用户可以有多个角色 一个角色可以赋予多个用户 步骤: 1.建立两张表:用户表,角色表 让用户表和角色表具有多对多的关系. 需要使用中间表,中间表中包含各自的主键,在中间表中是外键 ...

  2. MyBatis中实现多表查询

    如果查询的数据量大,推荐使用N+1次查询.数据量少使用联合查询... 一. 1.Mybatis是实现多表查询方式 1.1  业务装配:对两个表编写单表查询语句,在业务(Service)把查询的两表结果 ...

  3. 在Mybatis中使用连表查询的一次实际应用

    以前在工作中很少使用多表关联查询,对连表查询的具体作用和使用场景也没有很直观的认识,通过这次在项目中的实际应用,对此有了一定的认识,特记录如下. 关联表介绍: 分别是属性表attr_info.属性值表 ...

  4. Hibernate中的多表查询及抓取策略

    1.Hibernate中的多表查询 1.1SQL中的多表查询 [交叉连接] select * from A,B; [内连接] 显示内连接:inner join(inner 可以省略) Select * ...

  5. mysql中的回表查询与索引覆盖

    了解一下MySQL中的回表查询与索引覆盖. 回表查询 要说回表查询,先要从InnoDB的索引实现说起.InnoDB有两大类索引,一类是聚集索引(Clustered Index),一类是普通索引(Sec ...

  6. Mybatis多表查询(一对一、一对多、多对多)

    Mybatis的多表级联查询 . 一对一可以通过<association>实现,一对多和多对多通过<collection>实现. <discriminator> 元 ...

  7. MyBatis学习之多表查询

    一对多需求:即一张表class中又含有多张表(teacher,student)内容.现根据class_id 来获取对应的班级信息(包括学生和老师信息) 方式一:嵌套结果 使用嵌套结果映射来处理重复的联 ...

  8. Mybatis学习——一对一关联表查询

    1.SQL语句建表 CREATE TABLE teacher( t_id ) ); CREATE TABLE class( c_id ), teacher_id INT ); ALTER TABLE ...

  9. MyBatis总结-实现关联表查询

    一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) 1.2.创建表和数据 创建一张教师表和班级表,这里我们假设一个老师只负责教一个班,那么老师和班级之间的关系就是一种一对一的关 ...

随机推荐

  1. C#泛型参数多线程与复杂参数多线程

    背景:最近用多线程用的比较多自己走了一些弯路,分享出来希望大家少走弯路,C#中的多线程有两个重载,一个是不带参数的,一个是带参数的,但是即便是带参数的多线程也不支持泛型,这使得使用泛型参数多线程的时候 ...

  2. Handler消息传送机制

    一.什么是UI线程 当程序第一次启动的时候,Android会同时启动一条主线程( Main Thread). 主要负责处理与UI相关的事件. 二.UI线程存在的问题 出于性能优化考虑,Android的 ...

  3. 小程序二维码生成接口API

    获取小程序码 我们推荐生成并使用小程序码,它具有更好的辨识度.目前有两个接口可以生成小程序码,开发者可以根据自己的需要选择合适的接口. 接口A: 适用于需要的码数量较少的业务场景 接口地址: http ...

  4. python学习——练习题(5)

    """ 题目:输入三个整数x,y,z,请把这三个数由小到大输出. """ def inputInt(i): ""&quo ...

  5. leetcode806

    vector<int> numberOfLines(vector<int>& widths, string S) { map<char, int> MAP; ...

  6. struts2中s:iterator的使用(2个list嵌套循环)

    <s:iterator value="packagePlateTbls" id="plateTbls"> <tr> <td cla ...

  7. 【原创】9. MYSQL++中的Field、FieldNames以及FieldTypes类型

    mysqlpp::Field其实使用的并不多,主要在于Result.h中ResultBase以及他的派生类型(UseQueryResult和StoreQueryResult)的几个获取下一个field ...

  8. IDEA MAVEN 1.8无效的源发行版

    最近想将自己在IDEA上开发的MAVEN项目切换到JDK1.8版本上,结果IDEA报1.8无效的源发行版.下面说一下自己的解决方案: 1.pom文件 <build> <plugins ...

  9. 使用Java创建XML数据

    ------------siwuxie095                         工程名:TestCreateXML 包名:com.siwuxie095.xml 类名:CreateXML. ...

  10. mysql 主键

    什么是主键 表中的每一行都应该具有可以唯一标识自己的一列(或一组列).而这个承担标识作用的列称为主键. 任何列都可以作为主键,只要它满足以下条件: • 任何两行都不具有相同的主键值.就是说这列的值都是 ...