14、MyBatis的多表操作

1.MyBatis的多表操作

1.1 一对一查询
  1. 一对一查询的模型

    用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户

    一对一查询的需求:查询一个订单,与此同时查询出该订单所属的用户

  2. 一对一查询的语句

    对应的sql语句:select * from orders o,user u where o.uid=u.id;

    查询的结果如下:

  3. 创建Order和User实体

    public class Order {
    private int id;
    private Date ordertime;
    private double total;
    //代表当前订单从属于哪一个客户
    private User user;
    }
    public class User {
    private int id;
    private String username;
    private String password;
    private Date birthday;
    }
  4. 创建OrderMapper接口

    public interface OrderMapper {
    List<Order> findAll();
    }
  5. 配置OrderMapper.xml

    <mapper namespace="com.itheima.mapper.OrderMapper">
    <resultMap id="orderMap" type="com.itheima.domain.Order">
    <!--
    property: 当前实体(order)中的属性名称(private User user)
    javaType: 当前实体(order)中的属性的类型(User)
    -->
    <result column="oid" property="id"></id>
    <result column="ordertime" property="ordertime"></result>
    <result column="total" property="total"></result> <result column="uid" property="user.id"></result>
    <result column="username" property="user.username"></result>
    <result column="password" property="user.password"></result>
    <result column="birthday" property="user.birthday"></result>
    </resultMap>
    <select id="findAll" resultMap="orderMap">
    select * from orders o,user u where o.uid=u.id
    </select>
    </mapper>

    其中<resultMap>还可以配置如下:

    <resultMap id="orderMap" type="com.itheima.domain.Order">
    <result property="id" column="id"></result>
    <result property="ordertime" column="ordertime"></result>
    <result property="total" column="total"></result>
    <!--
    property: 当前实体(order)中的属性名称(private User user)
    javaType: 当前实体(order)中的属性的类型(User)
    -->
    <association property="user" javaType="com.itheima.domain.User">
    <result column="uid" property="id"></result>
    <result column="username" property="username"></result>
    <result column="password" property="password"></result>
    <result column="birthday" property="birthday"></result>
    </association>
    </resultMap>
  6. 测试结果

    OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
    List<Order> all = mapper.findAll();
    for(Order order : all){
    System.out.println(order);
    }

1.2 一对多查询
  1. 一对多查询的模型

    用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户

    一对多查询的需求:查询一个用户,与此同时查询出该用户具有的订单

  2. 一对多查询的语句

    对应的sql语句:select *,o.id oid from user u left join orders o on u.id=o.uid;

    查询的结果如下:

  3. 修改User实体

    public class Order {
    private int id;
    private Date ordertime;
    private double total;
    //代表当前订单从属于哪一个客户
    private User user;
    }
    public class User {
    private int id;
    private String username;
    private String password;
    private Date birthday;
    //代表当前用户具备哪些订单
    private List<Order> orderList;
    }
  4. 创建UserMapper接口

    public interface UserMapper {
    List<User> findAll();
    }
  5. 配置UserMapper.xml

    <mapper namespace="com.itheima.mapper.UserMapper">
    <resultMap id="userMap" type="com.itheima.domain.User">
    <!—手动指定字段与实体属性的映射关系-->
    <result column="id" property="id"></result>
    <result column="username" property="username"></result>
    <result column="password" property="password"></result>
    <result column="birthday" property="birthday"></result>
    <collection property="orderList" ofType="com.itheima.domain.Order">
    <result column="oid" property="id"></result>
    <result column="ordertime" property="ordertime"></result>
    <result column="total" property="total"></result>
    </collection>
    </resultMap>
    <select id="findAll" resultMap="userMap">
    select *,o.id oid from user u left join orders o on u.id=o.uid
    </select>
    </mapper>
  6. 测试结果

    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    List<User> all = mapper.findAll();
    for(User user : all){
    System.out.println(user.getUsername());
    List<Order> orderList = user.getOrderList();
    for(Order order : orderList){
    System.out.println(order);
    }
    System.out.println("----------------------------------");
    }

1.3 多对多查询
  1. 多对多查询的模型

    用户表和角色表的关系为,一个用户有多个角色,一个角色被多个用户使用

    多对多查询的需求:查询用户同时查询出该用户的所有角色

  2. 多对多查询的语句

    对应的sql语句:select u.*,r.*,r.id rid from user u left join user_role ur on u.id=ur.user_id

    inner join role r on ur.role_id=r.id;

    查询的结果如下:

  3. 创建Role实体,修改User实体

    public class User {
    private int id;
    private String username;
    private String password;
    private Date birthday;
    //代表当前用户具备哪些订单
    private List<Order> orderList;
    //代表当前用户具备哪些角色
    private List<Role> roleList;
    }
    public class Role {
    private int id;
    private String rolename;
    }
  4. 添加UserMapper接口方法

    List<User> findAllUserAndRole();
  5. 配置UserMapper.xml

    <resultMap id="userRoleMap" type="com.itheima.domain.User">
    <result column="id" property="id"></result>
    <result column="username" property="username"></result>
    <result column="password" property="password"></result>
    <result column="birthday" property="birthday"></result>
    <collection property="roleList" ofType="com.itheima.domain.Role">
    <result column="rid" property="id"></result>
    <result column="rolename" property="rolename"></result>
    </collection>
    </resultMap>
    <select id="findAllUserAndRole" resultMap="userRoleMap">
    select u.*,r.*,r.id rid from user u left join user_role ur on u.id=ur.user_id
    inner join role r on ur.role_id=r.id
    </select>
  6. 测试结果

    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    List<User> all = mapper.findAllUserAndRole();
    for(User user : all){
    System.out.println(user.getUsername());
    List<Role> roleList = user.getRoleList();
    for(Role role : roleList){
    System.out.println(role);
    }
    System.out.println("----------------------------------");
    }

1.4 小结

MyBatis多表配置方式:

  • 一对一配置:使用<resultMap>做配置

  • 一对多配置:使用<resultMap>+<collection>做配置

  • 多对多配置:使用<resultMap>+<collection>做配置


15、MyBatis注解开发

1.MyBatis的注解开发

1.1 MyBatis的常用注解

这几年来注解开发越来越流行,Mybatis也可以使用注解开发方式,这样我们就可以减少编写Mapper

映射文件了。

我们先围绕一些基本的CRUD来学习,再学习复杂映射多表操作。

  • @Insert:实现新增

  • @Update:实现更新

  • @Delete:实现删除

  • @Select:实现查询

  • @Result:实现结果集封装

  • @Results:可以与@Result 一起使用,封装多个结果集

  • @One:实现一对一结果集封装

  • @Many:实现一对多结果集封装

1.2 MyBatis的增删改查

简单的对user表的增删改查工作:

private UserMapper userMapper;
@Before
public void before() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
userMapper = sqlSession.getMapper(UserMapper.class);
}
@Test
public void testAdd() {
User user = new User();
user.setUsername("测试数据");
user.setPassword("123");
user.setBirthday(new Date());
userMapper.add(user);
}
@Test
public void testUpdate() throws IOException {
User user = new User();
user.setId(16);
user.setUsername("测试数据修改");
user.setPassword("abc");
user.setBirthday(new Date());
userMapper.update(user);
}
@Test
public void testDelete() throws IOException {
userMapper.delete(16);
}
@Test
public void testFindById() throws IOException {
User user = userMapper.findById(1);
System.out.println(user);
}
@Test
public void testFindAll() throws IOException {
List<User> all = userMapper.findAll();
for(User user : all){
System.out.println(user);
}
}

修改MyBatis的核心配置文件,我们使用了注解替代的映射文件,所以我们只需要加载使用了注解的Mapper接口即可

<mappers>
<!--扫描使用注解的类-->
<mapper class="com.itheima.mapper.UserMapper"></mapper>
</mappers>

或者指定扫描包含映射关系的接口所在的包也可以

<mappers>
<!--扫描使用注解的类所在的包-->
<package name="com.itheima.mapper"></package>
</mappers>
1.3 MyBatis的注解实现复杂映射开发

实现复杂关系映射之前我们可以在映射文件中通过配置<resultMap>来实现,使用注解开发后,我们可以使用@Results注解,@Result注解,@One注解,@Many注解组合完成复杂关系的配置


1.4 一对一查询
  1. 一对一查询的模型

    用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户

    一对一查询的需求:查询一个订单,与此同时查询出该订单所属的用户

  2. 一对一查询的语句

    对应的sql语句:

    select * from orders;

    select * from user where id=查询出订单的uid;

    查询的结果如下:

  3. 创建Order和User实体

    public class Order {
    private int id;
    private Date ordertime;
    private double total;
    //代表当前订单从属于哪一个客户
    private User user;
    }
    public class User {
    private int id;
    private String username;
    private String password;
    private Date birthday;
    }
  4. 创建OrderMapper接口

    public interface OrderMapper {
    List<Order> findAll();
    }
  5. 使用注解配置Mapper

  6. 测试结果

    @Test
    public void testSelectOrderAndUser() {
    List<Order> all = orderMapper.findAll();
    for(Order order : all){
    System.out.println(order);
    }
    }

1.5 一对多查询
  1. 一对多查询的模型

    用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户

    一对多查询的需求:查询一个用户,与此同时查询出该用户具有的订单

  2. 一对多查询的语句

    对应的sql语句:

    select * from user;

    select * from orders where uid=查询出用户的id;

    查询的结果如下:

  3. 修改User实体

    public class Order {
    private int id;
    private Date ordertime;
    private double total;
    //代表当前订单从属于哪一个客户
    private User user;
    }
    public class User {
    private int id;
    private String username;
    private String password;
    private Date birthday;
    //代表当前用户具备哪些订单
    private List<Order> orderList;
    }
  4. 创建UserMapper接口

    List<User> findAllUserAndOrder();
  5. 使用注解配置Mapper

  6. 测试结果

    List<User> all = userMapper.findAllUserAndOrder();
    for(User user : all){
    System.out.println(user.getUsername());
    List<Order> orderList = user.getOrderList();
    for(Order order : orderList){
    System.out.println(order);
    }
    System.out.println("-----------------------------");
    }
  7. 测试结果

1.6 多对多查询
  1. 多对多查询的模型

    用户表和角色表的关系为,一个用户有多个角色,一个角色被多个用户使用

    多对多查询的需求:查询用户同时查询出该用户的所有角色

  2. 多对多查询的语句

    对应的sql语句:

    select * from user;

    select * from role r,user_role ur where r.id=ur.role_id and ur.user_id=用户的id

    查询的结果如下:

  3. 创建Role实体,修改User实体

    public class User {
    private int id;
    private String username;
    private String password;
    private Date birthday;
    //代表当前用户具备哪些订单
    private List<Order> orderList;
    //代表当前用户具备哪些角色
    private List<Role> roleList;
    }
    public class Role {
    private int id;
    private String rolename;
    }
  4. 添加UserMapper接口方法

    List<User> findAllUserAndRole();
  5. 使用注解配置Mapper

  6. 测试结果

    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    List<User> all = mapper.findAllUserAndRole();
    for(User user : all){
    System.out.println(user.getUsername());
    List<Role> roleList = user.getRoleList();
    for(Role role : roleList){
    System.out.println(role);
    }
    System.out.println("----------------------------------");
    }

SSM自学笔记(七)的更多相关文章

  1. vue 自学笔记(七) 组件细节问题

    前情提要: 这里盘点一下,组件细节的问题 现在我们观察一些用框架开发的网页BiliBili.掘金,会发现很多部分都十分相似或者一模一样,我们甚至可以将其拆分归类.而事实上,页面的确是被一个个组件构成的 ...

  2. SSM自学笔记(六)

    11.MyBatis的Dao层实现方式 1.MyBatis的Dao层实现 1.1 传统开发方式 编写UserDao接口 public interface UserDao { List<User& ...

  3. SSM自学笔记(五)

    10.MyBatis入门操作 1.MyBatis的简介 1.1 原始jdbc操作(查询数据) 1.2 原始jdbc操作(插入数据) ##### 1.3 **原始**jdbc操作的分析 原始jdbc开发 ...

  4. SSM自学笔记(四)

    8.面向切面编程AOP 1.Spring 的 AOP 简介 1.1 什么是 AOP AOP 为 Aspect Oriented Programming 的缩写,意思为面向切面编程,是通过预编译方式和运 ...

  5. SSM自学笔记(三)

    5.Spring JdbcTemplate 1.Spring JdbcTemplate基本使用 1.1 JdbcTemplate概述 它是spring框架中提供的一个对象,是对原始繁琐的Jdbc AP ...

  6. SSM自学笔记(二)

    3.SpringMVC入门 1.Spring与Web环境集成 1.1 ApplicationContext应用上下文获取方式 应用上下文对象是通过new ClasspathXmlApplication ...

  7. SSM自学笔记(一)

    本文内容 Ioc和DI Spring快速入门 Spring配置文件 Spring IoC和DI注解开发 Spring配置数据源 Spring注解开发 Spring整合Junit IoC 和 DI 1. ...

  8. JavaScript高级程序设计之自学笔记(一)————Array类型

    以下为自学笔记. 一.Array类型 创建数组的基本方式有两种: 1.1第一种是使用Array构造函数(可省略new操作符). 1.2第二种是使用数组字面量表示法. 二.数组的访问 2.1访问方法 在 ...

  9. 《Linux内核设计与实现》课本第四章自学笔记——20135203齐岳

    <Linux内核设计与实现>课本第四章自学笔记 进程调度 By20135203齐岳 4.1 多任务 多任务操作系统就是能同时并发的交互执行多个进程的操作系统.多任务操作系统使多个进程处于堵 ...

随机推荐

  1. NAT444技术简介

    嘛,最近老师布置了一道题目与NAT444技术相关,遂收集一波相关资料. 首先来一波名词解释: ICP:网络内容服务商(Internet Content Provider) BRAS:宽带远程接入服务( ...

  2. ARTS起始篇

    ARTS简要说明(每周需要完成以下四项): Algorithm:每周至少做一道 leetcode 的算法题,编程训练.刻意练习. Review:需要阅读并点评至少一篇英文技术文章,这个是四项里面对我最 ...

  3. bat自动创建快捷方式并更换图标

    1 :: 此脚本主要的作用创建1.自动创建快捷方式:2.自动更换快捷方式图标 2 @echo off 3 >nul 2>&1 "%SYSTEMROOT%\system32 ...

  4. PYTHON 得到光标处的句柄

    import win32api import win32gui import time if __name__ == '__main__': while True: point = win32api. ...

  5. C语言:复合语句

    复合语句(compound statement)简称为语句块,它使用大括号把许多语句和声明组合到一起,形成单条语句.语句块与简单的语句不同,语句块不用分号当作结尾.用括号{}括起来组成的一个语句称复合 ...

  6. JMeter之Throughput Controller吞吐量控制器

    吞吐量控制器,它是用来控制该控制器下面元件的执行次数,与控制吞吐量的功能无关.(注:用Constant Throughput Timer可以控制吞吐量tps) 作用:控制其子节点的执行次数与负载比例分 ...

  7. shell脚本(5)-shell变量

    一.变量介绍 将一些数据需要临时存放在内存中,以待后续使用时快速读出. 二.变量分类 1.本地变量: 用户私有变量,只有本用户可以使用,保存在家目录下的.bash_profile..bashrc文件中 ...

  8. Selenium3自动化测试【20】CSS定位元素

    CSS 指层叠样式表 (CascadingStyleSheets),CSS一种用来表现HTML或XML等文件样式的计算机语言,其能够灵活的为页面提供丰富样式的风格. CSS使用选择器为页面元素绑定属性 ...

  9. 关于hashcode和equals方法说明

    一.前言 我们都知道,要比较两个对象是否相等时需要调用对象的equals()方法,即判断对象引用所指向的对象地址是否相等,对象地址相等时,那么与对象相关的对象句柄.对象头.对象实例数据.对象类型数据等 ...

  10. python 连接mysql数据库操作

    import pymysql.cursors # 连接数据库 connect = pymysql.Connect( host='localhost', port=3306, user='root', ...