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. 启动dubbo消费端过程提示No provider available for the service的问题定位与解决

    文/朱季谦 某次在启动dubbo消费端时,发现无法从zookeeper注册中心获取到所依赖的消费者API,启动日志一直出现这样的异常提示 Failed to check the status of t ...

  2. React-setState的那些事儿

    关于setState,使用过react的人应该再熟悉不过了,在hooks还不那么普及的时候,除了使用函数式组件,我们使用最多的应该就是类创建react的组件了,而在类组件中我们通常会使用state来管 ...

  3. C#中使用swagger小技巧

    C#中使用swagger小技巧 swaggerUI显示的接口内容主要用于开发阶段便于与前端联调,不适合发布到对外的站点. 有以下两种方式,让接口不显示在SwaggerUI中 1.使用属性 [ApiEx ...

  4. Task01:初识数据库

    本章主要讲解数据库安装和数据库基本介绍,考虑易用性及普及度,本课程采取mysql进行教学. 1.1 初识数据库 数据库是将大量数据保存起来,通过计算机加工而成的可以进行高效访问的数据集合.该数据集合称 ...

  5. 【NX二次开发】修改dlx对话框标题的方法

    修改dlx名称, 修改对话框标题的方法: theDialog->TopBlock()->FindBlock("Dialog")->GetProperties()- ...

  6. 在Visual Studio 中使用git——同步到远程服务器-上(十一)

    在Visual Studio 中使用git--什么是Git(一) 在Visual Studio 中使用git--给Visual Studio安装 git插件(二) 在Visual Studio 中使用 ...

  7. 无需会员将有道云笔记脑图转换xmind

    我的烦恼 有道云笔记有脑图功能,我平时经常用到,之所以很少用到其他脑图工具,是因为我一直用有道云笔记写笔记.因此编辑脑图和查看脑图比较方便,但是需要将脑图导出的时候目前只支持图片和xmind,但是需要 ...

  8. 《MySQL面试小抄》索引考点二面总结

    <MySQL面试小抄>索引考点二面总结 我是肥哥,一名不专业的面试官! 我是囧囧,一名积极找工作的小菜鸟! 囧囧表示:小白面试最怕的就是面试官问的知识点太笼统,自己无法快速定位到关键问题点 ...

  9. 『无为则无心』Python基础 — 14、Python流程控制语句(while循环语句)

    目录 1.什么是循环结构 2.while循环 (1)while循环的语法 (2)while循环的应用 3.while语句的死循环 4.break和continue 5.while循环嵌套 (1)应用场 ...

  10. 配置中心之Nacos简介,使用及Go简单集成

    简介 为什么需要配置中心 ​ 我们现在有一个项目, 使用Gin进行开发的, 配置文件我们知道是一个config.yaml的文件, 也知道这个配置文件在项目启动时会被加载到内存中使用; 考虑三种情况: ...