mybatis复杂映射
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复杂映射的更多相关文章
- 【Mybatis高级映射】一对一映射、一对多映射、多对多映射
前言 当我们学习heribnate的时候,也就是SSH框架的网上商城的时候,我们就学习过它对应的高级映射,一对一映射,一对多映射,多对多映射.对于SSM的Mybatis来说,肯定也是差不多的.既然开了 ...
- MyBatis 关系映射XML配置
关系映射 在我看来这些实体类就没啥太大关联关系,不就是一个sql语句解决的问题,直接多表查询就完事,程序将它设置关联就好 xml里面配置也是配置了sql语句,下面给出几个关系的小毛驴(xml) 一对多 ...
- mybatis高级映射(一对一,一对多)
mybatis高级映射 一对一关联映射 需求:查询订单信息,关联查询用户信息(一个订单对应一个用户) (1)通过resultType实现 sql语句: select orders.* , USER.u ...
- MyBatis 查询映射自定义枚举
背景 MyBatis查询若想映射枚举类型,则需要从 EnumTypeHandler 或者 EnumOrdinalTypeHandler 中选一个来使用 ...
- Mybatis sql映射文件浅析 Mybatis简介(三)
简介 除了配置相关之外,另一个核心就是SQL映射,MyBatis 的真正强大也在于它的映射语句. Mybatis创建了一套规则以XML为载体映射SQL 之前提到过,各项配置信息将Mybatis应用的整 ...
- Mybatis sql映射文件浅析 Mybatis简介(三) 简介
Mybatis sql映射文件浅析 Mybatis简介(三) 简介 除了配置相关之外,另一个核心就是SQL映射,MyBatis 的真正强大也在于它的映射语句. Mybatis创建了一套规则以XML ...
- Mybatis一对一映射
一.Mybatis一对一映射 本例讲述使用mybatis开发过程中常见的一对一映射查询案例.只抽取关键代码和mapper文件中的关键sql和配置,详细的工程搭建和Mybatis详细的流程代码可参见&l ...
- (十一)mybatis之映射器(select)
映射器 映射器的主要元素有八种: 元素名称 描述 select 查询语句,可自定义参数 insert 插入语句,执行后返回插入的条数 update 更新语句,执行后返回更新的条数 delete 删除语 ...
- Mybatis输入输出映射_动态sql_关联关系(一对一、一对多、多对多)
Mybatis输入输出映射_动态sql_关联关系(一对一.一对多.多对多)输入输出映射parameterType完成输入映射parameterType可以传入的参数有,基本数据类型(根据id查询用户的 ...
- mybatis中映射文件和实体类的关联性
mybatis的映射文件写法多种多样,不同的写法和用法,在实际开发过程中所消耗的开发时间.维护时间有很大差别,今天我就把我认为比较简单的一种映射文件写法记录下来,供大家修改建议,争取找到一个最优写法~ ...
随机推荐
- [论文阅读笔记] Structural Deep Network Embedding
[论文阅读笔记] Structural Deep Network Embedding 本文结构 解决问题 主要贡献 算法原理 参考文献 (1) 解决问题 现有的表示学习方法大多采用浅层模型,这可能不能 ...
- GO学习-(4) Go语言基础之变量和常量
Go语言基础之变量和常量 变量和常量是编程中必不可少的部分,也是很好理解的一部分. 标识符与关键字 标识符 在编程语言中标识符就是程序员定义的具有特殊意义的词,比如变量名.常量名.函数名等等. Go语 ...
- Tvm一些基本技术
Tvm一些基本技术 一.总体流程: TVM的工作流程:首先,将网络表示成统一的表示形式(Intermediate Representation),并进行一些可重用的图优化:然后,利用不同的后端生成对应 ...
- GPU加速库AmgX
GPU加速库AmgX AmgX提供了一条简单的途径来加速NVIDIA GPU上的核心求解器技术.AmgX可以为模拟的计算密集型线性求解器部分提供高达10倍的加速度,特别适合于隐式非结构化方法. 它是一 ...
- GPU上稀疏矩阵的基本线性代数
GPU上稀疏矩阵的基本线性代数 cuSPARSE库为稀疏矩阵提供了GPU加速的基本线性代数子例程,这些子例程的执行速度明显快于仅CPU替代方法.提供了可用于构建GPU加速求解器的功能.cuSPARSE ...
- 旷视MegEngine数据加载与处理
旷视MegEngine数据加载与处理 在网络训练与测试中,数据的加载和预处理往往会耗费大量的精力. MegEngine 提供了一系列接口来规范化这些处理工作. 利用 Dataset 封装一个数据集 数 ...
- HiCar SDK概述
HiCar SDK概述 HUAWEI HiCar SDK 是 HUAWEI HiCar(以下简称 HiCar )为汽车硬件设备提供的软件开发工具包,为汽车硬件厂商接入 HiCar 提供应用 API 接 ...
- https ssl(tls)为什么不直接用公钥加密数据?
很多人都提到了非对称加密速度慢,但这只是一个原因,但不是主要原因,甚至是微不足道的原因. SSL协议到3.0后就已经到头了,取而代之的是TLS,相较于SSL的"安全套接字层"的命名 ...
- 痞子衡嵌入式:嵌入式里串口(UART)自动波特率识别程序设计与实现
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是嵌入式里串口(UART)自动波特率识别程序设计与实现. 串口(UART)是嵌入式里最基础最常用也最简单的一种通讯(数据传输)方式,可以说 ...
- 【Java编程实战】Metasploit_Java后门运行原理分析以及实现源码级免杀与JRE精简化
QQ:3496925334 文章作者:MG1937 CNBLOG博客ID:ALDYS4 未经许可,禁止转载 某日午睡,迷迷糊糊梦到Metasploit里有个Java平台的远控载荷,梦醒后,打开虚拟机, ...