一、输入映射和输出映射

mapper.xml映射文件中定义了操作数据库的sql,每条sql就是一个statement,映射文件是MyBatis的核心。

1、parameterType(输入类型)

  • 简单类型(常用于SQL查询的基本类型字段)
  • pojo对象(常用于insert、update操作)
  • vo对象(ViewObject - 表现层对象,pojo的属性一般为基本类型,vo的属性可以是引用类型)

第一步:定义mapper映射文件(定义了statement id、SQL语句、parameterType、resultType)

<!--当查询条件中有多个固定数量的查询条件, 可以通过传入一个vo来进行操作,sql的传参来自vo属性的属性(user.username、user.sex)-->
<select id="findUserByVo" parameterType="cn.it.pojo.QueryVo" resultType="cn.it.pojo.User">
SELECT * FROM user WHERE username LIKE '%${user.username}%' AND sex =#{user.sex}
</select>

第二步:定义mapper接口

List<User> findUserByVo(QueryVo queryVo);

第三步:定义ViewObject(vo封装了User对象,也可以根据需要封装其他内容,用以保存其他查询选项)

package cn.it.pojo;

import java.util.List;

/**
* Created by Eric on 3/12/17.
*/
public class QueryVo {
private User user; private List<Integer> ids; public User getUser() {
return user;
} public void setUser(User user) {
this.user = user;
} public List<Integer> getIds() {
return ids;
} public void setIds(List<Integer> ids) {
this.ids = ids;
}
}

第四步:测试,

    @Test
public void findUserByQueryVo() throws Exception {
SqlSession openSession = sqlSessionFactory.openSession();
UserMapper mapper = openSession.getMapper(UserMapper.class); User user = new User();
user.setUsername("王");
user.setSex("2"); QueryVo queryVo = new QueryVo();
queryVo.setUser(user); List<User> userList = mapper.findUserByVo(queryVo);
for (User userInList : userList) {
System.out.println(userInList);
}
}

2、resultType(输出类型)

  • 输出简单类型(仅在SQL语句返回结果是一行一列是,输出类型才会是基本类型)
  • 输出pojo对象(selectOne)
  • 输出pojo对象列表(selectList)

第一步:定义mapper映射文件

    <!-- 仅在SQL语句返回一行一列的情况下, 才会使用基本类型作为resultType -->
<select id="findUserCount" resultType="int">
SELECT count(*) FROM user
</select>

第二步:定义mapper接口

    int findUserCount();

第三步:测试

    @Test
public void findUserCount() throws Exception {
SqlSession openSession = sqlSessionFactory.openSession();
UserMapper mapper = openSession.getMapper(UserMapper.class); int count = mapper.findUserCount();
System.out.println("查询结果集的行数为: " + count);
}

二、动态SQL拼接

1、if、where、sql、foreach标签的使用

第一步:定义mapper映射文件

    <!-- 动态SQL举例: SELECT * FROM user WHERE 1=1 AND username LIKE '%${username}% AND sex=#{sex}  -->
<select id="findUserByUsernameAndSex" resultType="user" parameterType="user">
SELECT * FROM user
<include refid="user_where"/>
</select> <sql id="user_where">
<!--where标签可以让你省去书写难看的 1=1 ; 并自动帮你把第一个条件sql的AND关键字去掉-->
<where>
<if test="username!=null and username!=''">username LIKE '%${username}%'</if>
<if test="sex!=null and sex!=''">AND sex=#{sex}</if>
</where>
</sql> <!--SQL语句: SELECT * FROM user WHERE id IN (1,2,3,4),foreach标签前的AND可以写,如果是第一个where条件也可以不写 -->
<select id="findUserByIds" parameterType="queryVo" resultType="user">
SELECT * FROM user
<where>
<if test="ids.isEmpty() != true">
AND <foreach collection="ids" item="element" open="id IN (" close=")" separator=",">#{element}</foreach>
</if>
</where>
</select>

第二步:定义mapper接口

    List<User> findUserByUsernameAndSex(User user);

    List<User> findUserByIds(QueryVo queryVo);

第三步:定义输入类型和输出类型(User、QueryVo)

第四步:测试

    @Test
public void findUserByUsernameAndSex() throws Exception {
SqlSession openSession = sqlSessionFactory.openSession();
UserMapper mapper = openSession.getMapper(UserMapper.class); User user1 = new User();
User user2 = new User();
User user3 = new User();
User user4 = new User(); user1.setUsername("王");
user2.setSex("2");
user3.setUsername("王");
user3.setSex("2"); System.out.println("查询'username=王': " + mapper.findUserByUsernameAndSex(user1));
System.out.println("查询'sex=2': " + mapper.findUserByUsernameAndSex(user2));
System.out.println("查询 '王 + 性别' 组合: " + mapper.findUserByUsernameAndSex(user3));
System.out.println("查询'null': " + mapper.findUserByUsernameAndSex(user4));
} @Test
public void findUserByIdSet() throws Exception {
SqlSession openSession = sqlSessionFactory.openSession();
UserMapper mapper = openSession.getMapper(UserMapper.class); List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(16);
list.add(30); QueryVo queryVo = new QueryVo();
queryVo.setIds(list); List<User> userList = mapper.findUserByIds(queryVo);
for (User user : userList) {
System.out.println(user);
}
}

三、关联查询

  • orders表和user表的关联查询

    • 遍历用户表,每个用户有往往有一个或多个订单,称为“一对多查询”;
    • 遍历订单表,每个订单必定关联一个用户,称为“一对一查询”;
  • resultType的改变

    • user表的pojo对象为User.java;orders表的pojo对象为Orders.java。它们只能作为单表查询的parameterType和resultType
    • 联表查询时,字段数增加,需要构建一个新的pojo来作为输入输出类型
      • 自动映射:

        • A、B联表查询,extend A表的pojo,在子类中扩展(B表字段对应的)属性,两表的同名字段问题可以通过SQL alias解决
        • 优点:只要保证resultType的pojo属性名(property)和查询结果的字段名(column)一致,MyBatis可以自动把输出结果注入到resultType对象中
        • 缺点:多表查询,No;一对多查询,No
      • 手动映射:
        • A、B联表查询,将其中一个pojo对象作为属性添加到另一个pojo中
        • 优点:多表查询,OK;一对多查询,OK
        • 缺点:配置繁琐
  • 一对一查询

    • 自动映射(可行)
    • 手动映射(可行)
  • 一对多查询
    • 自动映射(不可行)
    • 手动映射(可行)

1、一对一查询(手动映射)

第一步:定义mapper映射文件

    <!-- 一对一: 手动映射 (列出每一个订单, 每个订单必然有一个下单用户) -->
<select id="findOrdersAndUser" resultMap="ResultMap1">
SELECT a.*, b.id uid, username, birthday, sex, address FROM orders a, user b WHERE a.user_id = b.id
</select>
<resultMap id="ResultMap1" type="cn.manual.pojo.Orders">
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/> <association property="user" javaType="cn.manual.pojo.User">
<id column="uid" property="id"/>
<result column="username" property="username"/>
<result column="birthday" property="birthday"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
</association>
</resultMap>

第二步:定义mapper接口

    List<Orders> findOrdersAndUser();

第三步:定义pojo

第四步:测试

    @Test
public void findOrdersAndUserManual() throws Exception {
SqlSession openSession = sqlSessionFactory.openSession();
UserMapper mapper = openSession.getMapper(Mapper.class); List<Orders> ordersList = mapper.findOrdersAndUser();
for (Orders orders : ordersList) {
System.out.println(orders + " " + orders.getUser());
}
}

2、一对多查询(手动映射)

第一步:定义mapper映射文件

    <!--一多关系: 手动映射 (列出每个用户, 每个用户可能有一笔或者多笔订单) -->
<select id="findUserAndOrders" resultMap="ResultMap2">
SELECT b.id uid, username, birthday, sex, address, a.* FROM orders a, user b WHERE a.user_id=b.id
</select>
<resultMap id="ResultMap2" type="cn.manual.pojo.User">
<id column="uid" property="id"/>
<result column="username" property="username"/>
<result column="birthday" property="birthday"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/> <collection property="ordersList" ofType="cn.manual.pojo.Orders">
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
</collection>
</resultMap>

第二步:定义mapper接口

    List<User> findUserAndOrders();

第三步:定义pojo

第四步:测试

    @Test
public void findUserAndOrders() throws Exception {
SqlSession openSession = sqlSessionFactory.openSession();
UserMapper mapper = openSession.getMapper(Mapper.class); List<User> userList = mapper.findUserAndOrders();
for (User user : userList) {
for (Orders orders : user.getOrders()) {
System.out.println(user + " " + orders);
}
}
}

以上全部代码来自于: https://github.com/echo1937/mybatis-demo的mybatis-exercise模块

MyBatis基本配置和实践(三)的更多相关文章

  1. MyBatis基本配置和实践(五)

    第一步:创建一个Maven工程 第二步:编辑Maven工程的pom.xml,引入mybatis-generator-maven-plugin <?xml version="1.0&qu ...

  2. MyBatis基本配置和实践(四)

    一.Mybatis整合spring 1.整合思路 SqlSessionFactory对象应该放到spring容器中作为单例存在. 传统dao的开发方式中,应该从spring容器中获得sqlsessio ...

  3. MyBatis基本配置和实践(二)

    一.前言 从上一篇文章的junit单元测试环节可以看到,每一次调用MyBatis需要先加载SqlMapConfig.xml文件,再通过SqlSessionFactoryBuilder创建SqlSess ...

  4. MyBatis基本配置和实践(一)

    第一步:创建Java工程和数据库表user 第二步:使用Maven管理项目依赖 第三步:在resources目录下加入log4j.properties 第四步:在resources目录下加入SqlMa ...

  5. DB数据源之SpringBoot+MyBatis踏坑过程(三)手工+半自动注解配置数据源与加载Mapper.xml扫描

    DB数据源之SpringBoot+MyBatis踏坑过程(三)手工+半自动注解配置数据源与加载Mapper.xml扫描 liuyuhang原创,未经允许禁止转载    系列目录连接 DB数据源之Spr ...

  6. SSM ( Spring 、 SpringMVC 和 Mybatis )配置详解

    使用 SSM ( Spring . SpringMVC 和 Mybatis )已经有三个多月了,项目在技术上已经没有什么难点了,基于现有的技术就可以实现想要的功能,当然肯定有很多可以改进的地方.之前没 ...

  7. 2017.2.9 深入浅出MyBatis技术原理与实践-第八章 MyBatis-Spring(二)-----配置文件详解

    深入浅出MyBatis技术原理与实践-第八章 MyBatis-Spring(二) ------配置文件详解 8.2 MyBatis-Spring应用 8.2.1 概述 本文主要讲述通过注解配置MyBa ...

  8. mybatis全局配置mybatis-config.xml

    大部分时候,我们都是在Spring 里面去集成MyBatis.因为Spring 对MyBatis 的一些操作进行的封装,我们不能直接看到它的本质,所以先看下不使用容器的时候,也就是编程的方式,MyBa ...

  9. Mybatis学习-配置、作用域和生命周期

    核心配置文件:Mybatis-config.xml Mybatis的配置文件包含了会深深影响Mybatis行为的设置和属性信息 配置(configuration) 在mybatis-config.xm ...

随机推荐

  1. Mac无法将自定义图标添加到Launchpad的替代方案(桌面双击Shell运行)

    截止在几天之前的Mac OS版本都无法实现将自定义图标添加到Launchpad.我使用的是10.12. 替代的思路就是在桌面新建一个Shell文件,然后使软件在后台运行,最后就是双击Shell文件能自 ...

  2. ZendStudio操作技巧

    1.恢复窗口默认布局 点开菜单栏上的“windows”,出来的菜单中有个“Reset Perspective...”,点这个就行了

  3. 第3章—高级装配—配置profile bean

    配置profile bean 3.1.@profile注解是spring提供的一个用来标明当前运行环境的注解. 我们正常开发的过程中经常遇到的问题是,开发环境是一套环境,qa测试是一套环境,线上部署又 ...

  4. cocos开发环境搭建

    本文大部分内容取材自这篇文章:http://cn.cocos2d-x.org/tutorial/show?id=1448 公欲善其事,必先利其器. 想学习cocos?啥都别说了,先搭环境吧. 需要做的 ...

  5. MySQL Group Replication 介绍

    2016-12-12,一个重要的日子,mysql5.7.17 GA版发布,正式推出Group Replication(组复制) 插件,通过这个插件增强了MySQL原有的高可用方案(原有的Replica ...

  6. java几个经典的算法题目----------二维矩阵算法

    public class testClockwiseOutput { public static void main(String[] args) { //1.构建矩阵数据 int[][] arr = ...

  7. JAVA泛型——逆变

    在上篇<JAVA泛型——协变>这篇文章中遗留以下问题——协变不能解决将子类型添加到父类型的泛型列表中.本篇将用逆变来解决这个问题. 实验准备 我们首先增加以下方法,见代码清单1所示. 代码 ...

  8. XMPP之openfire无法启动

    之前半个月自学ios的时候自己也配置过xmpp框架,也从github上下载了demo试了下,也是很完美运行的,最近想着再回头把XMPP框架系统的学习一下 ,毕竟当时学的时候还是在虚拟机中,卡死了.我这 ...

  9. Nginx Open File Cache

    Nginx 的 open_file_cache 相关配置可以缓存静态文件的元信息,在这些静态文件被频繁访问时可以显着提升性能. 被缓存的文件元信息包括: fd,文件被打开一次后,fd保留使用 size ...

  10. 前端工程师的mysql笔记

    背景 最近常参与后台php项目,虽说刚毕业时自学过一阵子php和mysql,不过长时间没用也忘差不多了,于是把mysql再温习一遍,前端同学也可以一起学习下! mysql安装以及操作 安装 brew ...