1. 类型名对应

当实体类与表中字段完全一致时,mapper文件里返回类型用resultType,否则要用resultMap,并且建立resultMap映射

package com.rf.domain;

import java.util.Date;

public class User {
// `id` INT(11) NOT NULL AUTO_INCREMENT,
private int id;
//`username` VARCHAR(32) NOT NULL COMMENT '用户名称',
private String usernameabc;
//`birthday` DATETIME DEFAULT NULL COMMENT '生日',
private Date birthdayabc;
//`sex` CHAR(1) DEFAULT NULL COMMENT '性别',
private String sexabc;
//`address` VARCHAR(256) DEFAULT NULL COMMENT '地址',PRIMARY KEY (`id`)
private String addressbc; //getter and setter 省略
}
public interface UserMapper {
public List<User> findAllResultMap();
}
<resultMap id="userResultMap" type="user">
<id column="uid" property="id"></id>
<result column="NAME" property="username"></result>
<result column="PASSWORD" property="username"></result>
</resultMap>
<select id="findAllResultMap" resultMap="userResultMap">
SELECT id AS uid,username AS NAME,password AS PASSWORD FROM USER
</select>

2. 多条件查询

  • 使用 #{arg0}-#{argn} 或者 #{param1}-#{paramn} 获取参数
  • 使用注解,引入 @Param() 注解获取参数
  • 使用pojo对象传递参数
<!--   多条件查询方式1  利用arg或param传递-->
<select id="findByNameAndId" resultMap="UserMapperResult" parameterType="user">
<!--select * from user where id = #{arg0} and username = #{arg1}-->
<!-- 多条件查询方式2 利用@param传递-->
<!--select * from user where id = #{id} and username = #{username}-->
select * from user where id = #{id} and username = #{usernameabc}
</select>
//相同的包名,接口名,方法名,返回类型及参数类型
public interface UserMapper {
public List<User> findAll();
//方式1
// public User findByNameAndId(int id,String username);
//方式2 <!-- 多条件查询方式2 利用@param传递-->
// public User findByNameAndId(@Param("id") int id, @Param("username") String username);
//方式3 <!-- 多条件查询方式2 利用对象传递-->
public User findByNameAndId(User user);
}
   @Test
public void testUserMapperResult() throws IOException {
//1.加载核心配置文件import org.apache.ibatis.io.Resources;
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.获取SqlSessionFactory 工厂对象
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//3.获取会话对象
SqlSession sqlSession = sessionFactory.openSession();
//映射查询
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// User user = mapper.findByNameAndId(2,"应颠");
User user = new User();
user.setId(2);
user.setUsernameabc("应颠");
User user1 = mapper.findByNameAndId(user);
System.out.println(user1); }

3. 模糊查询

<mapper namespace="com.r'f.mapper.UserMapper">
<select id="findByUsername1" parameterType="string" resultType="user">
select * from user where username like #{username}
</select>
</mapper>
<mapper namespace="com.rf.mapper.UserMapper">
<!--不推荐使用,因为会出现sql注入问题-->
<select id="findByUsername2" parameterType="string" resultType="user">
select * from user where username like '${value}'
</select>
</mapper>
  • #{} :表示一个占位符号,可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入。#{} 可以接收简单类型值或pojo属性值(实体类)。如果parameterType传输单个简单类型值, #{} 括号中名称随便写。
  • ${} :表示拼接sql串通过 ${} 可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换,会出现sql注入问题。${} 可以接收简单类型值或pojo属性值。如果parameterType传输单个简单类型值, ${} 括号中只能是value。

4.返回主键

  • 添加属性useGeneratedKeys:useGeneratedKeys="true" 声明返回主键   keyProperty="id" 把返回主键的值,封装到实体的id属性中,只适用于主键自增的数据库,mysql和sqlserver支持,oracle不支持
  • 借助selectKey 标签
<selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID();
</selectKey>
  • selectKey 适用范围广,支持所有类型数据库keyColumn="id" 指定主键列名,keyProperty="id" 指定主键封装到实体的id属性中,resultType="int" 指定主键类型,order="AFTER" 设置在sql语句执行前(后),执行此语句,Oracle用before
<!-- 返回主键-->
<insert id="save" parameterType="user" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
INSERT INTO user(username,birthday,sex,address) values(#{usernameabc},#{birthdayabc},#{sexabc},#{addressabc})
</insert>
<!-- 返回主键2-->
<insert id="save2" parameterType="user">
<selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
select LAST_INSERT_ID()
</selectKey>
INSERT INTO user(username,birthday,sex,address) values(#{usernameabc},#{birthdayabc},#{sexabc},#{addressabc})
</insert> //根据username模糊查询user表
@Test
public void testsave2() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = factory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setUsernameabc("子慕");
user.setAddressabc("北京");
user.setBirthdayabc(new Date());
user.setSexabc("男");
mapper.save2(user);
     sqlSession.commit();
System.out.println("返回主键:" + user.getId()); }

5.动态sql

  • if标签 完成多标签查询
<!--
where标签相当于 where 1=1,但是如果没有条件,就不会拼接where关键字
-->
<select id="findByIdAndUsernameIf" parameterType="user" resultType="user">
SELECT * FROM `user`
<where>
<if test="id != 0">
AND id = #{id}
</if>
<if test="username != null">
AND username = #{username}
</if>
</where>
</select>
  • set标签:动态更新表数据,如果该属性有值就更新,没有值不做处理
<!--
set标签在更新的时候,自动加上set关键字,然后去掉最后一个条件的逗号
-->
<update id="updateIf" parameterType="user">
UPDATE `user`
<set>
<if test="username != null">
username = #{username},
</if>
<if test="birthday != null">
birthday = #{birthday},
</if>
<if test="sex !=null">
sex = #{sex},
</if>
<if test="address !=null">
address = #{address},
</if>
</set>
WHERE id = #{id}
</update>
  • foreach标签:实现多值查询,遍历
<foreach>标签用于遍历集合,它的属性:
• collection:代表要遍历的集合元素,collection
• open:代表语句的开始部分
• close:代表结束部分
• item:代表遍历集合的每个元素,生成的变量名
• sperator:代表分隔符

<!--
如果查询条件为普通类型 List集合,collection属性值为:collection 或者 list
-->
<select id="findByList" parameterType="list" resultType="user" >
SELECT * FROM `user`
<where>
<foreach collection="collection" open="id in(" close=")" item="id"
separator=",">
#{id}
</foreach>
</where>
</select>

<!--
如果查询条件为普通类型 Array数组,collection属性值为:array
-->
<select id="findByArray" parameterType="int" resultType="user">
SELECT * FROM `user`
<where>
<foreach collection="array" open="id in(" close=")" item="id"
separator=",">
#{id}
</foreach>
</where>
</select>
  • SQL语句片段抽取:映射文件中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的
<!--抽取的sql片段-->
<sql id="selectUser">
SELECT * FROM `user`
</sql>
<select id="findByList" parameterType="list" resultType="user" >
<!--引入sql片段-->
<include refid="selectUser"></include>
<where>
<foreach collection="collection" open="id in(" close=")" item="id"
separator=",">
#{id}
</foreach>
</where>
</select>

6.核心配置文件标签

  • plugins标签

    • MyBatis可以使用第三方的插件来对功能进行扩展,分页助手PageHelper是将分页的复杂操作进行封装,使用简单的方式即可获得分页的相关数据
    • 导入通用PageHelper的坐标 --在mybatis核心配置文件中配置PageHelper插件 --测试分页数据获取
         @Test
      public void testPageHelper() throws IOException {
      InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
      SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(resourceAsStream);
      SqlSession sqlSession = factory.openSession();
      UserMapper mapper = sqlSession.getMapper(UserMapper.class);
      //设置分页参数
      PageHelper.startPage(3,2);
      List<User> users = mapper.findAll();
      for (User user : users) {
      System.out.println(user);
      }
      System.out.println(users.size());
      //其他分页的数据
      PageInfo<User> pageInfo = new PageInfo<User>(users);
      System.out.println("总条数:"+pageInfo.getTotal());
      System.out.println("总页数:"+pageInfo.getPages());
      System.out.println("当前页:"+pageInfo.getPageNum());
      System.out.println("每页显示长度:"+pageInfo.getPageSize());
      System.out.println("是否第一页:"+pageInfo.isIsFirstPage());
      System.out.println("是否最后一页:"+pageInfo.isIsLastPage());
      }

7. 多表查询

  • 一对一,用association标签关联,property="user" 封装实体的属性名,javaType="user" 封装实体的属性类型
<mapper namespace="com.mapper.OrdersMapper">

    <resultMap id="ordermap" type="com.domain.Orders">
<id property="id" column="id"></id>
<result property="uid" column="uid"></result>
<result property="total" column="total"></result>
<result property="ordertime" column="ordertime"></result> <association property="user" javaType="com.domain.User">
<id column="uid" property="id"></id>
<result column="username" property="username"></result>
<result column="birthday" property="birthday"></result>
<result column="sex" property="sex"></result>
<result column="address" property="address"></result>
</association>
</resultMap>
<!-- 查询所有订单,与此同时查询出每个订单所属的用户-->
<select id="findAllWithUser" parameterType="com.domain.Orders" resultMap="ordermap">
select * from orders o left join user u on o.uid= u.id;
</select>
</mapper>
  • 一对多,用collection标签管理,property="orderList" 封装到集合的属性名,ofType="order”封装集合的泛型类型
   <resultMap id="userMap" type="com.domain.User">
<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>
<!-- property对应实体类中的属性,ofType 表明封装的类型 -->
<collection property="ordersList" ofType="com.domain.Orders">
<id property="id" column="oid"></id>
<result property="uid" column="uid"></result>
<result property="total" column="total"></result>
<result property="ordertime" column="ordertime"></result>
</collection> </resultMap> <!-- //查询所有用户,与此同时查询出该用户具有的订单-->
<select id="findAllWithOrder" resultMap="userMap">
SELECT *,o.id oid FROM USER u LEFT JOIN orders o ON u.id=o.uid
</select>
  • 多对多,用collection标签管理,property="orderList" 封装到集合的属性名,ofType="order”封装集合的泛型类型

        <resultMap id="userMap" type="com.domain.User">
    <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>
    <!-- property对应实体类中的属性,ofType 表明封装的类型 -->
    <collection property="ordersList" ofType="com.domain.Orders">
    <id property="id" column="oid"></id>
    <result property="uid" column="uid"></result>
    <result property="total" column="total"></result>
    <result property="ordertime" column="ordertime"></result>
    </collection> <collection property="roleList" ofType="com.domain.Sys_role">
    <!-- column对应的是 sys_user_role的属性roleid-->
    <id property="id" column="roleid"></id>
    <result property="roleName" column="roleName"></result>
    <result property="roleDesc" column="roleDesc"></result>
    </collection> </resultMap> <select id="findAllRoles" resultMap="userMap">
    SELECT * ,sr.roleDesc,sr.rolename FROM USER u LEFT JOIN sys_user_role sur ON u.id=sur.userid
    LEFT JOIN sys_role sr ON sur.roleid =sr.id </select>

8. 嵌套查询

  • 一对一:使用<resultMap>+<association>做配置,通过column条件,执行select查询
RoleMapper.xml
<!--一对一嵌套查询-->
<resultMap id="orderMap" type="order">
<id column="id" property="id"></id>
<result column="ordertime" property="ordertime"></result>
<result column="money" property="money"></result>
<!--根据订单中uid外键,查询用户表-->
<association property="user" javaType="user" column="uid"
select="com.lagou.mapper.UserMapper.findById"></association>
</resultMap>
<select id="findAllWithUser" resultMap="orderMap" >
SELECT * FROM orders
</select>
UserMapper.xml
<select id="findById" parameterType="int" resultType="user">
SELECT * FROM `user` where id = #{uid}
</select>

UserMapper.java
public interface UserMapper {
public User findById(Integer id);
}
  • 一对多:使用<resultMap>+<collection>做配置,通过column条件,执行select查询

    OdrersMapper.xml
    
    <select id="findByUid" resultType="com.domain.Orders" parameterType="int">
    select * from orders where uid=#{id}
    </select>
     UserMapper.xml
    
    <collection property="ordersList" ofType="com.domain.Orders" column="id" select="com.mapper.OrdersMapper.findByUid"></collection>
    
    <select id="findAllWithOrders" resultMap="userMap">
    select * from user
    </select>
  • 多对多:使用<resultMap>+<collection>做配置,通过column条件,执行select查询
UserMapper.xml
<collection property="roleLise" ofType="com.domain.Sys_role" column="userid" select="com.mapper.Sys_roleMapper.findByUid"></collection>
<select id="findAllWithRole" resultMap="userMap">
select * from user
</select> Sys_roleMapper.xml <select id="findByUid" parameterType="int" resultType="com.domain.Sys_role">
SELECT sr.id,sr.roleDesc,sr.rolename FROM sys_role sr LEFT JOIN sys_user_role sur ON sr.id=sur.roleid
WHERE sur.userid=#{id}
</select>
  • 优点:简化多表查询操作
  • 缺点:执行多次sql语句,浪费数据库性能

mybatis复杂映射的更多相关文章

  1. 【Mybatis高级映射】一对一映射、一对多映射、多对多映射

    前言 当我们学习heribnate的时候,也就是SSH框架的网上商城的时候,我们就学习过它对应的高级映射,一对一映射,一对多映射,多对多映射.对于SSM的Mybatis来说,肯定也是差不多的.既然开了 ...

  2. MyBatis 关系映射XML配置

    关系映射 在我看来这些实体类就没啥太大关联关系,不就是一个sql语句解决的问题,直接多表查询就完事,程序将它设置关联就好 xml里面配置也是配置了sql语句,下面给出几个关系的小毛驴(xml) 一对多 ...

  3. mybatis高级映射(一对一,一对多)

    mybatis高级映射 一对一关联映射 需求:查询订单信息,关联查询用户信息(一个订单对应一个用户) (1)通过resultType实现 sql语句: select orders.* , USER.u ...

  4. MyBatis 查询映射自定义枚举

    背景                  MyBatis查询若想映射枚举类型,则需要从 EnumTypeHandler 或者 EnumOrdinalTypeHandler 中选一个来使用         ...

  5. Mybatis sql映射文件浅析 Mybatis简介(三)

    简介 除了配置相关之外,另一个核心就是SQL映射,MyBatis 的真正强大也在于它的映射语句. Mybatis创建了一套规则以XML为载体映射SQL 之前提到过,各项配置信息将Mybatis应用的整 ...

  6. Mybatis sql映射文件浅析 Mybatis简介(三) 简介

    Mybatis sql映射文件浅析 Mybatis简介(三)   简介 除了配置相关之外,另一个核心就是SQL映射,MyBatis 的真正强大也在于它的映射语句. Mybatis创建了一套规则以XML ...

  7. Mybatis一对一映射

    一.Mybatis一对一映射 本例讲述使用mybatis开发过程中常见的一对一映射查询案例.只抽取关键代码和mapper文件中的关键sql和配置,详细的工程搭建和Mybatis详细的流程代码可参见&l ...

  8. (十一)mybatis之映射器(select)

    映射器 映射器的主要元素有八种: 元素名称 描述 select 查询语句,可自定义参数 insert 插入语句,执行后返回插入的条数 update 更新语句,执行后返回更新的条数 delete 删除语 ...

  9. Mybatis输入输出映射_动态sql_关联关系(一对一、一对多、多对多)

    Mybatis输入输出映射_动态sql_关联关系(一对一.一对多.多对多)输入输出映射parameterType完成输入映射parameterType可以传入的参数有,基本数据类型(根据id查询用户的 ...

  10. mybatis中映射文件和实体类的关联性

    mybatis的映射文件写法多种多样,不同的写法和用法,在实际开发过程中所消耗的开发时间.维护时间有很大差别,今天我就把我认为比较简单的一种映射文件写法记录下来,供大家修改建议,争取找到一个最优写法~ ...

随机推荐

  1. Jmeter+Ant+Jenkins接口自动化框架

    最近应公司要求,搭建一套接口自动化环境.看到通知邮件,没有多想就确定了Jmeter路线.可能有些人会 说,为啥不用python,相对而言高大上一些.因为公司内部现在项目有用到Jmeter,正好可以结合 ...

  2. Windows 10 版本 21H1 发布,百度网盘下载

    请访问原文链接:https://sysin.org/article/windows-10/,查看最新版.原创作品,转载请保留出处. Windows 10, version 21H1, all edit ...

  3. Web前端自动化测试Cypress实践总结

    本文主要首先主要介绍了什么是自动化测试,接着对常用的自动化测试框架进行了对比分析,最后,介绍了如果将自动化测试框架Cypress运用在项目中. 一.自动化测试概述 为了保障软件质量,并减少重复性的测试 ...

  4. 3 Python相对路径地址的的一个问题

    构建程序xiaojie_test.py import os from xxx.yyy import test test() 同目录下构建一个目录xxx,并且目录中有/tmp/results/graph ...

  5. nvJPEG库

    nvJPEG库 GPU加速的JPEG解码器,编码器和代码转换器 nvJPEG库是高性能的GPU加速库,用于解码,编码和转码JPEG格式的图像.nvJPEG2000库用于解码JPEG 2000格式的图像 ...

  6. PyTorch 数据并行处理

    PyTorch 数据并行处理 可选择:数据并行处理(文末有完整代码下载) 本文将学习如何用 DataParallel 来使用多 GPU. 通过 PyTorch 使用多个 GPU 非常简单.可以将模型放 ...

  7. 使用NVIDIA A100 TF32获得即时加速

    使用NVIDIA A100 TF32获得即时加速 NVIDIA A100带来了我们公司历史上最大的单代性能增长.这是一个新的结构创新,这是一个多功能的支持,这是一个多功能的结构支持.TF32是用于深度 ...

  8. adb安装 mac和Windows

    一.mac安装 参考地址https://blog.csdn.net/VSRfind/article/details/79593098 1.首先安装一个软件 在用Mac进行Android开发之前,我们一 ...

  9. JUC 并发编程--09, 阻塞队列: DelayQueue, PriorityBlockingQueue ,SynchronousQueue, 定时任务线程池: ScheduledThreadPoolExecutor

    先看DelayQueue 这个是用优先级队列实现的无界限的延迟队列,直接上代码: /** * 这个是 {@link DelayQueue} 延时队列 的验证使用类 */ class MyDelayed ...

  10. 【C++】秒级时间戳,毫秒级时间戳

    时间戳,秒级 测试代码: #include <iostream> #include <time.h> #include <windows.h> using name ...