用注解还是用 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. mongodb简单运用

    mongodb NoSQL(Not Only SQL),意思是"不仅仅是 SQL",指的是非关系型数据库,是对不同于传统的关系型数据库的数据库管理系统的统称. NoSQL 用于超大 ...

  2. 安卓开发视频教程!想找工作的你还不看这份资料就晚了!Android校招面试指南

    前言 准备面试其实已经准备了挺久了,当时打算面试准备了差不多以后,跟公司谈谈涨薪的事情,谈不拢的话,就年后直接找其他的公司.谁想到婚假还没休完,老板就在公司宣布了撤出上海的决定,愿意去深圳的就去,不愿 ...

  3. SICP 解题集 — SICP 解题集 https://sicp.readthedocs.io/en/latest/

    SICP 解题集 - SICP 解题集 https://sicp.readthedocs.io/en/latest/

  4. Spring Filter过滤表单中的非法字符

    使用Spring Filter过滤表单中的非法字符 1 package test.filter; 2 3 import java.io.IOException; 4 import java.util. ...

  5. 同时执行多个$.getJSON() 出现数据混乱的问题的解决

    $.getJSON() $.getJSON( url [, data ] [, success(data, textStatus, jqXHR) ] ) url是必选参数,表示json数据的地址: d ...

  6. centos 7_本地源制作

    1.安装工具 yum install yum-utils createrepo yum-plugin-priorities   2.自己创建一个阿里源 vim /etc/yum.repos.d/ope ...

  7. Phoenix简介概述,Phoenix的Java API 相关操作优秀案例

    Phoenix简介概述,Phoenix的Java API 相关操作优秀案例 一.Phoenix概述简介 二.Phoenix实例一:Java API操作 2.1 phoenix.properties 2 ...

  8. form(form基础、标签渲染、错误显示 重置信息、form属性、局部钩子、全局钩子)

    form基础 Django中的Form使用时一般有两种功能: 1.生成html标签 2.验证输入内容 要想使用django提供的form,要在views里导入form模块 from django im ...

  9. SpringApplication.run

    SpringApplication.run一共做了两件事,分别是 创建SpringApplication对象 利用创建好的SpringApplication对象,调用run方法 1.创建SpringA ...

  10. 图片轮播展示效果-2D实现

    图片的轮播展示效果如果使用2D实现,需要将3D中存在的近大远小效果使用图片的缩放呈现,因此需要存储和计算图片的位置同时还要计算存储图片的缩放信息.将所有图片的位置连线看作是一个椭圆,就可以根据图片的个 ...