用注解还是用 xml 配置?
常用注解:@Insert、@Select、@Update、@Delete、@Param、@Results、
@Result
在 MyBatis 的工程中,我们有两种配置 SQL 的方式。一种是在 Mapper.xml 中集中
管理,一种是在 Mapper 接口上,用注解方式配置 SQL。很多同学在工作中可能两种方
式都用过。那到底什么时候用 XML 的方式,什么时候用注解的方式呢?
注解的缺点是 SQL 无法集中管理,复杂的 SQL 很难配置。所以建议在业务复杂的项
目中只使用 XML 配置的形式,业务简单的项目中可以使用注解和 XML 混用的形式。
Mapper 接口无法注入或 Invalid bound statement (not found)
我们在使用 MyBatis 的时候可能会遇到 Mapper 接口无法注入,或者 mapper
statement id 跟 Mapper 接口方法无法绑定的情况。基于绑定的要求或者说规范,我们
可以从这些地方去检查一下:
1、扫描配置,xml 文件和 Mapper 接口有没有被扫描到
2、namespace 的值是否和接口全类名一致
3、检查对应的 sql 语句 ID 是否存在
怎么获取插入的最新自动生成的 ID
在 MySQL 的插入数据使用自增 ID 这种场景,有的时候我们需要获得最新的自增 ID,
比如获取最新的用户 ID。常见的做法是执行一次查询,max 或者 order by 倒序获取最
大的 ID(低效、存在并发问题)。在 MyBatis 里面还有一种更简单的方式:
insert 成功之后,mybatis 会将插入的值自动绑定到插入的对象的 Id 属性中,我们
用 getId 就能取到最新的 ID。
<insert id="insert" parameterType="com.gupaoedu.domain.Blog">
insert into blog (bid, name, author_id)
values (#{bid,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, #{author,jdbcType=CHAR})
</insert>
blogService.addBlog(blog);
 
如何实现模糊查询 LIKE
1、字符串拼接
在 Java 代码中拼接%%(比如 name = "%" + name + "%"; ),直接 LIKE。因为没
有预编译,存在 SQL 注入的风险,不推荐使用。
2、CONCAT(推荐)
<when test="empName != null and empName != ''">
AND e.emp_name LIKE CONCAT(CONCAT('%', #{emp_name, jdbcType=VARCHAR}),'%')
</when>
3、bind 标签
<select id="getEmpList_bind" resultType="empResultMap" parameterType="Employee">
<bind name="pattern1" value="'%' + empName + '%'" />
<bind name="pattern2" value="'%' + email + '%'" />
SELECT * FROM tbl_emp
<where>
<if test="empId != null">
emp_id = #{empId,jdbcType=INTEGER},
</if>
<if test="empName != null and empName != ''">
AND emp_name LIKE #{pattern1}
</if>
<if test="email != null and email != ''">
AND email LIKE #{pattern2}
</if>
</where>
ORDER BY emp_id
</select>
什么时候用#{},什么时候用${}?
在 Mapper.xml 里面配置传入参数,有两种写法:#{} 、${}。作为 OGNL 表达式,
System.out.println(blog.getBid()); 
 
都可以实现参数的替换。这两种方式的区别在哪里?什么时候应该用哪一种?
要搞清楚这个问题,我们要先来说一下 PrepareStatement 和 Statement 的区别。
1、两个都是接口,PrepareStatement 是继承自 Statement 的;
2、Statement 处理静态 SQL,PreparedStatement 主要用于执行带参数的语句;
3、PreparedStatement 的 addBatch()方法一次性发送多个查询给数据库;
4、PS 相似 SQL 只编译一次(对语句进行了缓存,相当于一个函数),比如语句相
同参数不同,可以减少编译次数;
5、PS 可以防止 SQL 注入。
MyBatis 任意语句的默认值:PREPARED
这两个符号的解析方式是不一样的:
#会解析为 Prepared Statement 的参数标记符,参数部分用?代替。传入的参数会
经过类型检查和安全检查。
(mybatis-standalone - MyBatisTest - testSelect())
 
==> Preparing: select * from blog where bid = ?
==> Parameters: 1(Integer)
<==
Columns: bid, name, author_id
<==
Row: 1, 咕泡学院, 1001
<==
Total: 1
查询结果:Blog{bid=1, name='咕泡学院', authorId='1001'}
$只会做字符串替换,比如参数是咕泡学院,结果如下:
(mybatis-standalone - MyBatisTest - selectBlogByBean ())
==> Preparing: select bid,name,author_id authorId from blog where name = '咕泡学院'
==> Parameters:
<==
Columns: bid, name, authorId
<==
Row: 1, 咕泡学院, 1001
<==
Total: 1
查询结果:[Blog{bid=1, name='咕泡学院', authorId='1001'}]
#和$的区别:
1、 是否能防止 SQL 注入:$方式不会对符号转义,不能防止 SQL 注入
2、 性能:$方式没有预编译,不会缓存
结论:
1、 能用#的地方都用#
2、 常量的替换,比如排序条件中的字段名称,不用加单引号,可以使用$
对象属性是基本类型 int double,数据库返回 null 是报错
使用包装类型。如 Integer,不要使用基本类型如 int。
If test !=null 失效了?
在实体类中使用包装类型。
XML 中怎么使用特殊符号,比如小于 &
1、转义< < (大于可以直接写)
2、使用<![CDATA[ ]]>——当 XML 遇到这种格式就会把[]里面的内容原样输出,不
进行解析
 
1、resultType 和 resultMap 的区别?
resultType 是<select>标签的一个属性,适合简单对象(POJO、JDK 自带类型:
Integer、String、Map 等),只能自动映射,适合单表简单查询。
<select id="selectAuthor" parameterType="int" resultType="com.gupaoedu.domain.Author">
select author_id authorId, author_name authorName
from author where author_id = #{authorId}
</select>
resultMap 是一个可以被引用的标签,适合复杂对象,可指定映射关系,适合关联
复合查询。
<resultMap id="BlogWithAuthorResultMap"
type="com.gupaoedu.domain.associate.BlogAndAuthor">
<id column="bid" property="bid" jdbcType="INTEGER"/>
<result column="name" property="name" jdbcType="VARCHAR"/>
<!-- 联合查询,将 author 的属性映射到 ResultMap -->
<association property="author" javaType="com.gupaoedu.domain.Author">
<id column="author_id" property="authorId"/>
<result column="author_name" property="authorName"/>
</association>
</resultMap>
2、collection 和 association 的区别?
association:一对一
<!-- 另一种联合查询(一对一)的实现,但是这种方式有“N+1”的问题 -->
<resultMap id="BlogWithAuthorQueryMap" type="com.gupaoedu.domain.associate.BlogAndAuthor">
<id column="bid" property="bid" jdbcType="INTEGER"/>
<result column="name" property="name" jdbcType="VARCHAR"/>
<association property="author" javaType="com.gupaoedu.domain.Author"
column="author_id" select="selectAuthor"/> <!-- selectAuthor 定义在下面
-->
</resultMap>
collection:一对多、多对多
<!-- 查询文章带评论的结果(一对多) -->
<resultMap id="BlogWithCommentMap" type="com.gupaoedu.domain.associate.BlogAndComment"
extends="BaseResultMap" >
<collection property="comment" ofType="com.gupaoedu.domain.Comment">
<id column="comment_id" property="commentId" />
<result column="content" property="content" />
</collection>
</resultMap>
<!-- 按作者查询文章评论的结果(多对多) -->
<resultMap id="AuthorWithBlogMap" type="com.gupaoedu.domain.associate.AuthorAndBlog" >
<id column="author_id" property="authorId" jdbcType="INTEGER"/>
<result column="author_name" property="authorName" jdbcType="VARCHAR"/>
<collection property="blog" ofType="com.gupaoedu.domain.associate.BlogAndComment">
<id column="bid" property="bid" />
<result column="name" property="name" />
<result column="author_id" property="authorId" />
<collection property="comment" ofType="com.gupaoedu.domain.Comment">
<id column="comment_id" property="commentId" />
<result column="content" property="content" />
</collection>
</collection>
</resultMap> 
3、PrepareStatement 和 Statement 的区别?
两个都是接口,PrepareStatement 是继承自 Statement 的;
Statement 处理静态 SQL,PreparedStatement 主要用于执行带参数的语句;
PreparedStatement 的 addBatch()方法一次性发送多个查询给数据库;
PS 相似 SQL 只编译一次(对语句进行了缓存,相当于一个函数),减少编译次
数;
PS 可以防止 SQL 注入;
MyBatis 默认值:PREPARED
4、跟踪 update()流程,绘制每一步的时序图(4 个)
自行绘制。
5、总结:MyBatis 里面用到了哪些设计模式?(已讲解)
第三次课已讲解,笔记中有。
6、当我们传入 RowBounds 做翻页查询的时候,使用 limit 物理分页,代替原来的逻辑分页
基于 mybatis-standalone,MyBatisTest.java —— testSelectByRowBounds()
>代码在 interceptor 包中
7、在未启用日志组件的情况下,输出执行的 SQL,并且统计 SQL 的执行时间(先实现查询
的拦截)
>代码在 interceptor 包中 
 
 
 

mybatis(十一)mybatis常见问题的更多相关文章

  1. MyBatis(十一):MyBatis架构流程浅析

    架构分层 我们将MyBatis架构分为三层,分别为接口层.数据处理层和框架支撑层 接口层:提供外部接口调用的API,使用端通过这些API来操作数据库,接口层收到请求后会调用数据处理层完成具体的数据处理 ...

  2. 【Mybatis】MyBatis之配置自定义数据源(十一)

    本例是在[Mybatis]MyBatis之配置多数据源(十)的基础上进行拓展,查看本例请先学习第十章 实现原理 1.扩展Spring的AbstractRoutingDataSource抽象类(该类充当 ...

  3. Hello Mybatis 02 mybatis generator

    接着上一篇文章通过Mybatis完成了一个User的CRUD的功能之后,这篇开始还需要建立一个Blog类,这样就可以模拟一个简单的微博平台的数据库了. 数据库准备 首先我们,还是需要在数据库中新建一个 ...

  4. 【Mybatis】MyBatis之动态SQL(六)

    MyBatis 的强大特性之一便是它的动态 SQL,本章介绍动态 SQL 查看本章,请先阅读[Mybatis]MyBatis对表执行CRUD操作(三). 本例表结构 CREATE TABLE `emp ...

  5. 【Mybatis】MyBatis之Sql配置文件的使用(四)

    上一章[Mybatis]MyBatis对表执行CRUD操作(三),已经讲了基本操作,本章介绍Sql配置文件中常用功能 1.插入返回主键 2.参数值的获取方式 3.resultMap使用 插入返回主键 ...

  6. MyBatis笔记----MyBatis 入门经典的两个例子: XML 定义与注解定义

    ----致敬MyBatis官方开放文档让大家翻译,不用看书直接看文档就行了,mybatis的中文文档还需要完备的地方 简介 什么是 MyBatis ? MyBatis 是支持定制化 SQL.存储过程以 ...

  7. 【Mybatis】MyBatis对表执行CRUD操作(三)

    本例在[Mybatis]MyBatis配置文件的使用(二)基础上继续学习对表执行CRUD操作 使用MyBatis对表执行CRUD操作 1.定义sql映射xml文件(EmployeeMapper.xml ...

  8. 【Mybatis】MyBatis配置文件的使用(二)

    本例在[Mybatis]MyBatis快速入门(一)基础上继续学习XML映射配置文件 MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置(settings)和属性(properti ...

  9. 【转】Mybatis学习---MyBatis知识、原始Dao开发和mapper代理开发

    [原文]https://www.toutiao.com/i6594610137560777223/ 一.什么是MyBatis MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及 ...

随机推荐

  1. Javadoc命令与API

    Javadoc命令与API Javadoc工具会抽取类,成员,方法的文档注释生成与这个类配套的API帮助文档 Javadoc命令和文档注释小公司基本不用,但我们应养成良好的编码习惯,所以还是了解一下 ...

  2. 通过js给某个标签添加内容或者删除标签

    添加内容 //先保存div中原来的html var tag = document.getElementById("tag").innerHTML; //构造新的内容 var cou ...

  3. 鸿蒙的多媒体及Menu组件及小程序的多媒体组件

    目录: js业务逻辑层 视图渲染层 css属性设置 效果图 微信小程序展示 内网穿透工具下载 我们在搭建一个小程序或者网站的时候,往往要加载很多的图片,音频和视频文件.如果都从服务器获取静态资源,这样 ...

  4. Uber如何解决2000多个微服务带来的复杂性问题?

    Uber如何解决2000多个微服务带来的复杂性问题? Adam Gluck 架构头条 2020-10-29 https://mp.weixin.qq.com/s/N7fVDZVm8uC9wVvd9DQ ...

  5. 翻页bug 在接口文档中应规范参数的取值区间 接口规范

    <?php$a=array("red","green","blue","yellow","brown&q ...

  6. muduo 网络库的整体架构图和一个简化版本的架构设计

    https://blog.csdn.net/adkada1/article/details/54342275 简析 https://blog.csdn.net/amoscykl/article/det ...

  7. RocketMQ 的几个简单问题与答案

    1 单机版消息中心 一个消息中心,最基本的需要支持多生产者.多消费者,例如下: class Scratch { public static void main(String[] args) { // ...

  8. Http系列:断点续传与多线程下载

    前言 当下载电影时,我常常会想中断下载后,为什么点击开始时会在中断的地方继续下载呢?又或者在看在线电影时,为什么可以按着播放条拖动就能看到想看的片段呢? http的range请求将解决以上困惑. 多线 ...

  9. 分布式kv存储系统之Etcd集群

    etcd是什么? etcd是一个高可用的分布式键值数据库,可用于服务发现,etcd采用 raft 一致性算法,基于 Go 语言实现.其特点有简单易用,所谓简单易用是指安装配置简单,提供http/htt ...

  10. 关于MongoDB的简单理解(三)--Spring Boot篇

    一.前言 Spring Boot集成MongoDB非常简单,主要为加依赖,加配置,编码. 二.说明 环境说明: JDK版本为15(1.8+即可) Spring Boot 2.4.1 三.集成步骤 3. ...