MyBatis系列

简介: MyBatis系列

一:Mybatis中#{}和${}的区别

1、#{}是预编译处理,${}是字符串替换。

2、Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的 set方法来赋值;

3、Mybatis在处理${}时,就是把${}替换成变量的值。

4、使用#{}可以有效的防止SQL注入,提高系统安全性。

二:Mybatis的执行流程

1、读取 MyBatis 配置文件:mybatis-config.xml 为 MyBatis 的全局配置文件,配 置了 MyBatis 的运行环境等信息,例如数据库连接信息。

2、加载映射文件。映射文件即 SQL 映射文件,该文件中配置了操作数据库的 SQL 语句,需要在MyBatis 配置文件 mybatis-config.xml 中加载。 mybatis-config.xml 文件可以加载多个映射文件,每个文件对应数据库中的一张 表。

3、构造会话工厂:通过 MyBatis 的环境等配置信息构建会话工厂 SqlSessionFactory。

4、创建会话对象:由会话工厂创建 SqlSession 对象,该对象中包含了执行 SQL 语句的所有方法。

5、Executor执行器:MyBatis底层定义了一个Executor 接口来操作数据库,它将 根据 SqlSession 传递的参数动态地生成需要执行的 SQL 语句,同时负责查询缓存 的维护。

6、MappedStatement 对象:在 Executor 接口的执行方法中有一个 MappedStatement 类型的参数,该参数是对映射信息的封装,用于存储要映射的 SQL 语句的 id、参数等信息。

7、输入参数映射:输入参数类型可以是 Map、List 等集合类型,也可以是基本 数据类型和 POJO 类型。输入参数映射过程类似于 JDBC 对 preparedStatement 对 象设置参数的过程。

8、输出结果映射:输出结果类型可以是 Map、 List 等集合类型,也可以是基本 数据类型和 POJO 类型。输出结果映射过程类似于 JDBC 对结果集的解析过程。  

三:Mybatis如何获取生成的主键

使用insert标签中的useGeneratedKeys和keyProperty 属性

<insert id = "saveUser" useGeneratedKeys = "true" KeyProperty = "id">
     insert into tb_user(user_name,password,gender,addr) values(#{username},#{password},#{gender},#{addr})
</insert>

属性说明:

1、useGeneratedKeys:是够获取自动增长的主键值。true表示获取。

2、keyProperty :指定将获取到的主键值封装到哪儿个属性里

四:JDBC有什么缺点,Mybatis是如何解决的

1、数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库连接池可解 决此问题。 解决:在mybatis-config.xml中配置数据链接池,使用连接池管理数据库连接。

2、Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代 码。 解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。

3、向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参 数一一对应。 解决: Mybatis自动将java对象映射至sql语句。

4、对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装 成pojo对象解析比较方便。

解决:Mybatis自动将sql执行结果映射至java对象

五:为什么需要预编译

定义:

SQL 预编译指的是数据库驱动在发送 SQL 语句和参数给 DBMS 之前对 SQL 语句进行编译, 这样 DBMS 执行 SQL 时,就不需要重新编译。

为什么需要预编译:

JDBC 中使用对象 PreparedStatement 来抽象预编译语句,使用预编译。预编译阶段可以优 化 SQL 的执行。预编译之后的 SQL 多数情况下可以直接执行,DBMS 不需要再次编译,越 复杂的SQL,编译的复杂度将越大,预编译阶段可以合并多次操作为一个操作。同时预编译 语句对象可以重复利用。把一个 SQL 预编译后产生的 PreparedStatement 对象缓存下来, 下次对于同一个SQL,可以直接使用这个缓存的 PreparedState 对象。Mybatis默认情况下, 将对所有的 SQL 进行预编译。 还有一个重要的原因,防止SQL注入

六:Mybatis如何进行批量操作

使用foreach标签


foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。foreach标签的属性主 要有item,index,collection,open,separator,close。

item 表示集合中每一个元素进行迭代时的别名,随便起的变量名;

index 指定一个名字,用于表示在迭代过程中,每次迭代到的位置,不常用;


open  表示该语句以什么开始,常用“(”;

separator 表示在每次进行迭代之间以什么符号作为分隔符,常用“,”;

close   表示以什么结束,常用“)”。

在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是 在不同情况下,该属性的值是不一样的,主要有一下3种情况:

1. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list

2. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array

3. 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封 装成map,实际上如果你在传入参数的时候,在MyBatis里面也是会把它封装成一个Map 的, map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封 装的map里面的key

<!-- 批量保存(foreach插入多条数据两种方法)
       int addEmpsBatch(@Param("emps") List<Employee> emps); -->
 <!-- MySQL下批量保存,可以foreach遍历 mysql支持values(),(),()语法 --> //推荐使用
<insert id="addEmpsBatch">
    INSERT INTO emp(ename,gender,email,did)
    VALUES
    <foreach collection="emps" item="emp" separator=",">
        (#{emp.eName},#{emp.gender},#{emp.email},#{emp.dept.id})
    </foreach>
 </insert>
<!-- 这种方式需要数据库连接属性allowMutiQueries=true的支持
 如jdbc.url=jdbc:mysql://localhost:3306/mybatis?allowMultiQueries=true -->  
<insert id="addEmpsBatch">
    <foreach collection="emps" item="emp" separator=";">                         
        
        INSERT INTO emp(ename,gender,email,did)
        VALUES(#{emp.eName},#{emp.gender},#{emp.email},#{emp.dept.id})
    </foreach>
 </insert>

七:实体类的属性名和表字段中的名称不一样,怎么解决

第1种: 通过在查询的SQL语句中定义字段名的别名,让字段名的别名和实体类的属性名一致

<select id="getOrder" parameterType="int" 
resultType="com.jourwon.pojo.Order">
 select order_id id, order_no orderno ,order_price price form orders 
where order_id=#{id};
 </select>

第2种: 通过 来映射字段名和实体类属性名的一一对应的关系。  

<select id="getOrder" parameterType="int" resultMap="orderResultMap">
 select * from orders where order_id=#{id}
 </select>
 <resultMap type="com.jourwon.pojo.Order" id="orderResultMap">
 <!–用id属性来映射主键字段–>
 <id property="id" column="order_id">
性–>
 <!–用result属性来映射非主键字段,property为实体类属性名,column为数据库表中的属
<result property ="orderno" column ="order_no"/>
 <result property="price" column="order_price" />
 </reslutMap>

八:什么是Mybatis的接口绑定,有哪几种实现方式

接口绑定,就是在MyBatis中任意定义接口,然后把接口里面的方法和SQL语句绑定,我们直接调 用接口方法就可以,这样比起原来了SqlSession提供的方法我们可以有更加灵活的选择和设置。

接口绑定有两种实现方式

1. 通过注解绑定,就是在接口的方法上面加上 @Select、@Update等注解,里面包含Sql语句来 绑定;

2. 通过xml里面写SQL来绑定, 在这种情况下,要指定xml映射文件里面的namespace必须为 接口的全路径名。当Sql语句比较简单时候,用注解绑定, 当SQL语句比较复杂时候,用xml 绑定,一般用xml绑定的比较多

九:Mybatis的一级缓存和二级缓存

1. 一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session f lush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认打开一级缓存。

2. 二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于其 存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。默认不打开二级缓 存,要开启二级缓存,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状 态),可在它的映射文件中配置 3. 对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了 C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear

十:Mybatis是如何进行分页的,原理是什么

Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页,可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。

分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截 待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。

举例:select * from student,拦截sql后重写为:select t.* from (select * from student) t limit 0, 10

相关文章
|
设计模式 存储 Java
深拷贝与浅拷贝,就是这么简单
深拷贝与浅拷贝,就是这么简单
|
8月前
|
人工智能 开发者
阿里巴巴AI Coding 分享会—— Qoder Together 上海站来啦!
Qoder Together,不止技术分享,更是思维共振与灵感迸发。我们面向全球AI Coding爱好者,邀请Qoder团队、实战用户、AI Coding探索者齐聚一堂,交流激发创意,碰撞拓展边界,重新定义智能编程未来。
515 1
|
7月前
|
Linux 数据库
Linux 环境 国产银河麒麟V10操作系统安装 Polardb-X 数据库 单机版 rpm 包 教程
本文介绍在国产银河麒麟V10操作系统上安装Polardb-X单机版数据库的完整过程。基于RPM包方式部署,步骤与CentOS 7.9类似,涵盖系统环境确认、依赖安装、用户配置、初始化数据目录及启动服务等关键环节,并通过命令验证运行状态,助力国产化平台数据库搭建。
2664 2
|
9月前
|
Web App开发 缓存 安全
如何在谷歌Chrome浏览器加载Activex控件?
ActiveX控件是微软开发的一系列策略性面向对象程序技术和工具,能实现网页与本地系统的深度交互。IE流行的互联网早期,大量的ActiveX控件被应用于各种场景,学校,银行,企业官网等,但其核心局限在于严重依赖Windows和IE浏览器,存在巨大的安全风险,随着浏览器安全升级,最新版浏览器已经都不支持Activex/OCX控件,但是大量企业面临历史业务无法升级,只能用IE浏览器继续苟延残喘,如何在新版谷歌Chrome上加载IE的Activex/OCX控件成为一个难题。
496 0
|
Kubernetes 安全 Devops
「迁移急救包」全云平台无缝迁移云效实操手册
阿里云云效是国内领先的一站式DevOps平台,提供代码全生命周期管理、智能化交付流水线及精细化研发管控,支持多种开发场景。本文详细介绍了从其他平台(如Coding)向云效迁移的完整方案,包括代码仓库、流水线、制品仓库及项目数据的迁移步骤,帮助用户实现高效、安全的平滑迁移,提升研发效率与协作能力。
1007 29
|
Dart 前端开发 JavaScript
springboot自动配置原理
Spring Boot 自动配置原理:通过 `@EnableAutoConfiguration` 开启自动配置,扫描 `META-INF/spring.factories` 下的配置类,省去手动编写配置文件。使用 `@ConditionalXXX` 注解判断配置类是否生效,导入对应的 starter 后自动配置生效。通过 `@EnableConfigurationProperties` 加载配置属性,默认值与配置文件中的值结合使用。总结来说,Spring Boot 通过这些机制简化了开发配置流程,提升了开发效率。
1043 17
springboot自动配置原理
|
Cloud Native 安全 Java
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
714 1
|
Java
hashCode()和 equals()方法的默认实现
在Java中,`hashCode()` 和 `equals()` 方法的默认实现由 `Object` 类提供。`equals()` 默认比较对象引用是否相同,`hashCode()` 则返回对象的内存地址的整数表示。为了确保哈希表等数据结构的正确性,当重写 `equals()` 时,通常也需要重写 `hashCode()`。
766 9
|
Java 关系型数据库 数据库连接
mybatis中的useGeneratedKeys和keyProperty
在 MyBatis 中,`useGeneratedKeys` 和 `keyProperty` 是用于处理数据库自动生成主键的关键配置。通过这些配置,可以方便地获取和使用数据库生成的主键值,提高开发效率和代码可读性。确保正确配置和使用这两个属性,可以在应用程序中高效地进行数据库操作。
1073 25
|
SpringCloudAlibaba JavaScript Dubbo
【SpringCloud Alibaba系列】Dubbo dubbo-admin安装教程篇
本文介绍了 Dubbo-Admin 的安装和使用步骤。Dubbo-Admin 是一个前后端分离的项目,前端基于 Vue,后端基于 Spring Boot。安装前需确保开发环境(Windows 10)已安装 JDK、Maven 和 Node.js,并在 Linux CentOS 7 上部署 Zookeeper 作为注册中心。
4341 1
【SpringCloud Alibaba系列】Dubbo dubbo-admin安装教程篇

热门文章

最新文章