用注解还是用 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. Http中的options请求

    引自:https://www.jianshu.com/p/5cf82f092201.https://www.cnblogs.com/mamimi/p/10602722.html 一.options是什 ...

  2. 大数据系列1:一文初识Hdfs

    最近有位同事经常问一些Hadoop的东西,特别是Hdfs的一些细节,有些记得不清楚,所以趁机整理一波. 会按下面的大纲进行整理: 简单介绍Hdfs 简单介绍Hdfs读写流程 介绍Hdfs HA实现方式 ...

  3. QTextEdit的paste

    By 鬼猫猫 20130117 http://www.cnblogs.com/muyr/ 背景 QTextEdit中粘贴一大段文字时,EasyDraft中粘贴进去的文字们的格式就乱了,处于无格式.还有 ...

  4. linux GPU上多个buffer间的同步 —— ww_mutex、dma-fence的使用 笔记

    原文链接:https://www.cnblogs.com/yaongtime/p/14111134.html   WW-Mutexes   在GPU中一次Render可能会涉及到对多个buffer的引 ...

  5. Property or method "previewUrl" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components,

    Property or method "previewUrl" is not defined on the instance but referenced during rende ...

  6. 一键配置 github 可用的 hosts

    最近发现访问 Github 各种不畅通, 静态资源经常加载不出来. 写了一个一键脚本修改本机 /etc/hosts 文件, 切换到可用的 IP (数据来自 https://gitee.com/xuew ...

  7. unstable sort

    $sort (aggregation) - MongoDB Manual https://docs.mongodb.com/manual/reference/operator/aggregation/ ...

  8. 在Ubuntu下安装Jenkins

    一.安装Jenkins 1. 确保Java环境已经安装配置好 java -version 2. 将存储库密钥添加到系统 wget -q -O - https://pkg.jenkins.io/debi ...

  9. LOJ10199轻拍牛头

    题目描述 原题来自:USACO 2008 Dec. Silver 今天是 Bessie 的生日,并且现在是聚会的游戏时间.Bessie 让编号为 1~N 的 N 头奶牛围成一个圈坐(所以除了最后一头牛 ...

  10. Elasticsearch如何保证数据不丢失?

    目录 如何保证数据写入过程中不丢 直接落盘的 translog 为什么不怕降低写入吞吐量? 如何保证已写数据在集群中不丢 in-memory buffer 总结 LSM Tree的详细介绍 参考资料 ...