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. GO学习-(29) Go语言操作etcd

    Go语言操作etcd etcd是近几年比较火热的一个开源的.分布式的键值对数据存储系统,提供共享配置.服务的注册和发现,本文主要介绍etcd的安装和使用. etcd etcd介绍 etcd是使用Go语 ...

  2. Python+Selenium学习笔记1 - pip命令

    1.用pip命令安装模块 pip install 模块名 e.g. pip install qrcode 2.用pip卸载模块 pip uninstall 模块名 e.g. pip uninstall ...

  3. 多视觉任务的全能: HRNet

    多视觉任务的全能: HRNet HRNet是微软亚洲研究院的王井东老师领导的团队完成的,打通图像分类.图像分割.目标检测.人脸对齐.姿态识别.风格迁移.Image Inpainting.超分.opti ...

  4. Tesla T4视频编码性能分析

    Tesla T4视频编码性能分析 从开普勒开始的所有 NVIDIA GPUs 都支持完全加速的硬件视频编码: GPUs 支持完全加速的硬件视频解码.最近发布的图灵硬件提供了张量核心和更好的机器学习性能 ...

  5. runtime系统的Cello

    runtime系统的Cello 通过充当一个现代的.功能强大的runtime系统,Cello使许多以前在C中不切实际或笨拙的事情变得简单,例如: 通用数据结构 多态函数 接口/类型类 构造函数/析构函 ...

  6. C语言代码区错误以及编译过程

    C语言代码区错误 欲想了解C语言代码段会有如何错误,我们必须首先了解编译器是如何把C语言文本信息编译成为可以执行的机器码的. 背景介绍 测试使用的C语言代码 导入标准库,定义宏变量,定义结构体,重命名 ...

  7. 《精通 ASP.NET Core MVC (第七版)》开始发售

    学习 Web 开发技术很难吗?没有适合的学习资料,确实很枯燥,很难.如果有一本如同良师益友的优秀图书辅助,就很轻松,一点也不难! 对于优秀的技术图书来说,必须从读者的角度来编写,而不是从作者的角度来编 ...

  8. 使用ElementTree解析,操作xml

    一.最近在实际工作中需要对一部分接口进行测试,接口的入参与出参都是xml格式的数据,所以用到了python内部模块ElementTree对xml进行解析,并根据实际需求操作xml数据 二.代码示例 # ...

  9. VNC 相关

    vncserver启动报错root A VNC server is already running as :1 [root@42 ~]# service vncserver startStarting ...

  10. Mysql数据库值的添加、修改、删除及清空

    3.MySQL数据管理 第一种方式:不太建议,看起来复杂些 -- 学生表的 gradeid 字段,要去引用 年级表的 gradeid -- 定义外键key -- 给这个外键添加约束,(执行引用),RE ...