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. [论文阅读笔记] Structural Deep Network Embedding

    [论文阅读笔记] Structural Deep Network Embedding 本文结构 解决问题 主要贡献 算法原理 参考文献 (1) 解决问题 现有的表示学习方法大多采用浅层模型,这可能不能 ...

  2. GO学习-(4) Go语言基础之变量和常量

    Go语言基础之变量和常量 变量和常量是编程中必不可少的部分,也是很好理解的一部分. 标识符与关键字 标识符 在编程语言中标识符就是程序员定义的具有特殊意义的词,比如变量名.常量名.函数名等等. Go语 ...

  3. Tvm一些基本技术

    Tvm一些基本技术 一.总体流程: TVM的工作流程:首先,将网络表示成统一的表示形式(Intermediate Representation),并进行一些可重用的图优化:然后,利用不同的后端生成对应 ...

  4. GPU加速库AmgX

    GPU加速库AmgX AmgX提供了一条简单的途径来加速NVIDIA GPU上的核心求解器技术.AmgX可以为模拟的计算密集型线性求解器部分提供高达10倍的加速度,特别适合于隐式非结构化方法. 它是一 ...

  5. GPU上稀疏矩阵的基本线性代数

    GPU上稀疏矩阵的基本线性代数 cuSPARSE库为稀疏矩阵提供了GPU加速的基本线性代数子例程,这些子例程的执行速度明显快于仅CPU替代方法.提供了可用于构建GPU加速求解器的功能.cuSPARSE ...

  6. 旷视MegEngine数据加载与处理

    旷视MegEngine数据加载与处理 在网络训练与测试中,数据的加载和预处理往往会耗费大量的精力. MegEngine 提供了一系列接口来规范化这些处理工作. 利用 Dataset 封装一个数据集 数 ...

  7. HiCar SDK概述

    HiCar SDK概述 HUAWEI HiCar SDK 是 HUAWEI HiCar(以下简称 HiCar )为汽车硬件设备提供的软件开发工具包,为汽车硬件厂商接入 HiCar 提供应用 API 接 ...

  8. https ssl(tls)为什么不直接用公钥加密数据?

    很多人都提到了非对称加密速度慢,但这只是一个原因,但不是主要原因,甚至是微不足道的原因. SSL协议到3.0后就已经到头了,取而代之的是TLS,相较于SSL的"安全套接字层"的命名 ...

  9. 痞子衡嵌入式:嵌入式里串口(UART)自动波特率识别程序设计与实现

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是嵌入式里串口(UART)自动波特率识别程序设计与实现. 串口(UART)是嵌入式里最基础最常用也最简单的一种通讯(数据传输)方式,可以说 ...

  10. 【Java编程实战】Metasploit_Java后门运行原理分析以及实现源码级免杀与JRE精简化

    QQ:3496925334 文章作者:MG1937 CNBLOG博客ID:ALDYS4 未经许可,禁止转载 某日午睡,迷迷糊糊梦到Metasploit里有个Java平台的远控载荷,梦醒后,打开虚拟机, ...