一、Mybatis 中$与#的区别

#相当于对数据 加上 双引号,$相当于直接显示数据

1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order
by "111", 如果传入的值是id,则解析成的sql为order by "id".

2.
$将传入的数据直接显示生成在sql中。如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id,  如果传入的值是id,则解析成的sql为order by id.

3.
#方式能够很大程度防止sql注入。

4.$方式无法防止Sql注入。

5.$方式一般用于传入数据库对象,例如传入表名.

6.一般能用#的就别用$.

MyBatis排序时使用order
by 动态参数时需要注意,用$而不是#

二、Mybatis映射文件里的<selectkey>

我们在数据库插入一条数据(主键是数据库生成)的时候,经常是需要返回插入这条数据的(数据库生成的)主键。

比如插入用户信息JavaBean时,id不需要我们设置(自增),那么插入后,我们想马上得这个JavaBean的ID。

可以下面这样改:

  1. <insert id="saveUser" parameterType="cn.itcast.mybatis.pojo.User">
  2. <selectKey keyColumn="id" keyProperty="id" order="AFTER"
  3. resultType="int">
  4. SELECT LAST_INSERT_ID()
  5. </selectKey>
  6. INSERT INTO `user`
  7. (username,birthday,sex,address) VALUES
  8. (#{username},#{birthday},#{sex},#{address})
  9. </insert>

其中:

selectKey
标签实现主键返回 
keyColumn:

主键对应的表中的哪一列

keyProperty:

主键对应的pojo中的哪一个属性

order:

设置在执行insert语句前执行查询id的sql,还是在执行insert语句之后执行查询id的sql

MySQL填AFTER ,Oracle填BEFORE

resultType:

设置返回的id的类型

三、映射xml文件中的resultMap

1.介绍

resultType可以指定将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功

如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系
,resultMap实质上还需要将查询结果映射到pojo对象中。

比如对于数据库里user_id这种字段,逆向工程会生成userId属性的pojo


2.使用(由resultType改用resultMap

  1. <!-- resultMap最终还是要将结果映射到pojo上,type就是指定映射到哪一个pojo -->
  2. <!-- id:设置ResultMap的id -->
  3. <resultMap type="cn.ssm.pojo.order" id="orderResultMap">
  4. <result property="userId" column="user_id" />//只要写那个不一样的就行了!
  5. </resultMap>
  6. <!-- 查询所有的订单数据 -->
  7. <select id="queryOrderAll" resultMap="orderResultMap">
  8. SELECT id, user_id,
  9. number,
  10. createtime, note FROM `order`
  11. </select>

其中:property:主键在pojo中的属性名,column:主键在数据库中的列名

四、动态SQL(基于OGNL表达式)

1.if标签

  1. <!-- 根据条件查询用户 -->
  2. <select id="queryUserByWhere" parameterType="user" resultType="user">
  3. SELECT id, username, birthday, sex, address FROM `user`
  4. WHERE 1=1
  5. <if test="sex != null and sex != ''">
  6. AND sex = #{sex}
  7. </if>
  8. <if test="username != null and username != ''">
  9. AND username LIKE
  10. '%${username}%'
  11. </if>
  12. </select>

2.where标签

上面的例子里,还得写个1=1 防止出现 where and 这种错误情况。其实这种情况可以通过where标签解决

  1. <!-- 根据条件查询用户 -->
  2. <select id="queryUserByWhere" parameterType="user" resultType="user">
  3. SELECT id, username, birthday, sex, address FROM `user`
  4. <!-- where标签可以自动添加where,同时处理sql语句中第一个and关键字 -->
  5. <where>
  6. <if test="sex != null">
  7. AND sex = #{sex}
  8. </if>
  9. <if test="username != null and username != ''">
  10. AND username LIKE
  11. '%${username}%'
  12. </if>
  13. </where>
  14. </select>

3.SQL片段

Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的。

把上面例子中的id, username, birthday, sex, address提取出来,作为sql片段,如下:

  1. <!-- 声明sql片段 -->
  2. <sql id="userFields">
  3. id, username, birthday, sex, address
  4. </sql>
  5. <!-- 根据条件查询用户 -->
  6. <select id="queryUserByWhere" parameterType="user" resultType="user">
  7. <!-- 使用include标签加载sql片段;refid是sql片段id -->
  8. SELECT <include refid="userFields" /> FROM `user`
  9. <where>
  10. <if test="sex != null">
  11. AND sex = #{sex}
  12. </if>
  13. <if test="username != null and username != ''">
  14. AND username LIKE
  15. '%${username}%'
  16. </if>
  17. </where>
  18. </select>

如果要使用别的Mapper.xml配置的sql片段,可以在refid里面加上对应的Mapper.xml的namespace

4.foreach标签

向sql传递数组或List,mybatis使用foreach解析,比如:

根据多个id查询用户信息

查询sql:

SELECT * FROM user WHERE id IN (1,10,24)

  1. <!-- 根据ids查询用户 -->
  2. <select id="queryUserByIds" parameterType="queryVo" resultType="user">
  3. SELECT * FROM `user`
  4. <where>
  5. <!-- foreach标签,进行遍历 -->
  6. <!-- collection:遍历的集合,这里是QueryVo的ids属性 -->
  7. <!-- item:遍历的项目,可以随便写,,但是和后面的#{}里面要一致 -->
  8. <!-- open:在前面添加的sql片段 -->
  9. <!-- close:在结尾处添加的sql片段 -->
  10. <!-- separator:指定遍历的元素之间使用的分隔符 -->
  11. <foreach collection="ids" item="item" open="id IN (" close=")"
  12. separator=",">
  13. #{item}
  14. </foreach>
  15. </where>
  16. </select>

五、多表查询


多表查询的时候通常会要返回多个表的数据,即多个pojo的部分数据。


5.1一对一查询(两张表)


此时要么采取新建pojo(继承一个pojo再加上新需要的)去包裹查出来的数据,要么在原pojo里组合另外一个pojo(作为成员对象),即继承和组合
两种方法。

5.1.1采用继承的方法(正常采用resultType即可)

5.1.2采用组合的方式

那么此时多个pojo会有相同属性,如何映射?采取resultMap


pojo可能会要改成下面这样:


那么此时查询结果对pojo的映射得改改了

  1. <resultMap type="order" id="orderUserResultMap">
  2. <id property="id" column="id" />
  3. <result property="userId" column="user_id" />
  4. <result property="number" column="number" />
  5. <result property="createtime" column="createtime" />
  6. <result property="note" column="note" />
  7. <!-- association :配置一对一属性 -->
  8. <!-- property:order里面的User属性名 -->
  9. <!-- javaType:属性类型 -->
  10. <association property="user" javaType="user">
  11. <!-- id:声明主键,表示user_id是关联查询对象的唯一标识-->
  12. <id property="id" column="user_id" />
  13. <result property="username" column="username" />
  14. <result property="address" column="address" />
  15. </association>
  16. </resultMap>
  17. <!-- 一对一关联,查询订单,订单内部包含用户属性 -->
  18. <select id="queryOrderUserResultMap" resultMap="orderUserResultMap">
  19. SELECT
  20. o.id,o.user_id,o.number,o.createtime,o.note,u.username,u.address
  21. FROM
  22. `order` o
  23. LEFT JOIN `user` u ON o.user_id = u.id
  24. </select>

5.2一对多查询

如下:



那么映射文件如下:

  1. <resultMap type="user" id="userOrderResultMap">
  2. <!-- 配置主键,将主键相同的记录映射到一个集合里去-->
  3. <id property="id" column="id" />
  4. <result property="username" column="username" />
  5. <result property="birthday" column="birthday" />
  6. <result property="sex" column="sex" />
  7. <result property="address" column="address" />
  8. <!-- 配置一对多的关系 -->
  9. <collection property="orders" javaType="list" ofType="order">
  10. <!-- 配置主键,是关联Order的唯一标识 -->
  11. <id property="id" column="oid" />
  12. <result property="number" column="number" />
  13. <result property="createtime" column="createtime" />
  14. <result property="note" column="note" />
  15. </collection>
  16. </resultMap>
  17. <!-- 一对多关联,查询订单同时查询该用户下的订单 -->
  18. <select id="queryUserOrder" resultMap="userOrderResultMap">
  19. SELECT
  20. u.id,u.username,u.birthday,u.sex,u.address,o.id oid,o.number,o.createtime,o.note
  21. FROM
  22. `user` u
  23. LEFT JOIN `order` o ON u.id = o.user_id
  24. </select>

Mybatis入门简版(补充)的更多相关文章

  1. Mybatis入门简版(二)

    一.Dao层开发的方式 以前dao层开发比较繁琐,写了接口还得写实现类,实际上用了Mybatis之后写实现类非常重复,都是重复的代码.那么此时改成另外一种简单形式. 遵循以下四个原则(名称.形参.返回 ...

  2. Mybatis入门简版(一)

    一.Mybatis介绍 MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动.创建connection.创 ...

  3. Underscore源码阅读极简版入门

    看了网上的一些资料,发现大家都写得太复杂,让新手难以入门.于是写了这个极简版的Underscore源码阅读. 源码: https://github.com/hanzichi/underscore-an ...

  4. Spring Boot 实战 —— MyBatis(注解版)使用方法

    原文链接: Spring Boot 实战 -- MyBatis(注解版)使用方法 简介 MyBatis 官网 是这么介绍它自己的: MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过 ...

  5. Java Persistence with MyBatis 3(中文版) 第一章 MyBatis入门

    本章将涵盖以下话题: ž  MyBatis是什么? ž  为什么选择MyBatis? ž  MyBatis安装配置 ž  域模型样例 1.1 MyBatis是什么 MyBatis是一个简化和实现了Ja ...

  6. MyBatis从入门到精通(1):MyBatis入门

    作为一个自学Java的自动化专业211大学本科生,在学习和实践过程中"趟了不少雷",所以有志于建立一个适合同样有热情学习Java技术的参考"排雷手册". 最近在 ...

  7. Spring Boot (七): Mybatis极简配置

    Spring Boot (七): Mybatis极简配置 1. 前言 ORM 框架的目的是简化编程中的数据库操作,经过这么多年的发展,基本上活到现在的就剩下两家了,一个是宣称可以不用写 SQL 的 H ...

  8. SpringBoot2+Netty打造通俗简版RPC通信框架

    2019-07-19:完成基本RPC通信! 2019-07-22:优化此框架,实现单一长连接! 2019-07-24:继续优化此框架:1.增加服务提供注解(带版本号),然后利用Spring框架的在启动 ...

  9. MyBatis入门使用

    MyBatis入门使用 MyBatis简介 MyBatis是支持普通SQL查询.存储过程和高级映射的持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索.MyBati ...

随机推荐

  1. Redis 的底层数据结构(SDS和链表)

    Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件.可能几乎所有的线上项目都会使用到 Redis,无论你是做缓存.或是用作消息中间件,用起来很简单方便 ...

  2. 六星教育php vip视频(分享)

    最近看的一个swoole的课程,应该也算是vip课程了,不是公开的直播课 比较有特点有一定深度,swoole的实战教程一直也不多,结合swoole构建一个新型框架,最后讲解如何实现分布式RPC的调用. ...

  3. 洛谷 P1181数列分段Section I

    星爆气流(弃疗)斩!                                            ——<刀剑神域> 题目:https://www.luogu.org/proble ...

  4. Centos7 C++ 安装使用googletest单元测试

    废话不多说,直接开始吧. 环境说明 系统环境:centos7.0 g++ 版本: g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36) 查看方法: g++ -vers ...

  5. Redis相关安装TCL

    安装相关命令 wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gzsudo tar -xzvf tcl8.6.1-src.tar. ...

  6. JSP实例:彩色验证码

    本例使用一个JavaBean,名为Image.java,包com.zempty.bean下; 三个JSP文件,分别为image.jsp.login.jsp.check.jsp.其中login.jsp是 ...

  7. Hola!

    个人资料 我叫Xenny,当然我还有很多名字,Tony.LTY.唐梦寒.soar.tafhack等等,这些都是我的昵称:但是用的最多的还是Xenny. Xenny的来历很扯,Xen是因为从XD中取了个 ...

  8. MOOC C++笔记(五):继承

    第五周:继承 继承和派生的基本概念 继承:在定义一个新的类B时,如果该类与某个个已有的类A相似(指的是B拥有A的全部特点),那么就可以把A作为一个基类,而把B作为基类的一个派生类(也称子类). 派生类 ...

  9. spring aop介绍和示例

    参考:<Spring in Action> 一.AOP介绍 AOP是Aspect Oriented Programming的缩写,意思是面向切面编程. 应用中有一些功能使用非常普遍,比如事 ...

  10. oracle异机恢复测试

    (一)问题背景 最近在生产环境中,开发人员误操作,使用truncate将oracle数据库某个表的数据全部删除了,在删除之后,开发人员发现自己闯祸了,于是联系值班的DBA进行紧急数据恢复. 经过分析, ...