Mybitis详解

概述

MyBatis 是一款优秀的持久层框架,一个半 ORM(对象关系映射)框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

ORM是什么

ORM(Object Relational Mapping),对象关系映射,是一种为了解决关系型数据库数据与简单Java对象(POJO)的映射关系的技术。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系型数据库中。

为什么预编译可以避免SQL注入

预编译(Prepared Statement)可以避免SQL注入攻击的主要原因是它使用参数化查询(Parameterized Query)。下面是一些解释:

  1. 参数化查询:预编译语句将SQL查询字符串和查询参数分开处理。查询参数通过占位符(如?)表示,而不是直接将用户输入的值嵌入到查询字符串中。这样做可以防止恶意用户输入的数据被解释为SQL代码。
  2. 自动转义:当使用参数化查询时,数据库驱动程序会自动对查询参数进行转义处理,确保输入的内容按照字面值进行解释,而不会被误认为是SQL代码。这样可以防止用户输入的特殊字符破坏SQL语句的结构。
  3. 预编译优化:预编译语句在执行之前已经被数据库服务器进行了编译和优化,使得相同的查询可以多次使用相同的执行计划,提高了查询的性能。
    通过使用预编译语句,开发人员可以将用户输入的数据作为参数传递给查询,而不是直接将其拼接到SQL语句中。这种方式有效地防止了SQL注入攻击,因为恶意用户无法通过输入特殊字符来改变原本的查询结构或执行恶意代码。
    需要注意的是,虽然预编译可以防止大多数的SQL注入攻击,但并不是万能的。在编写SQL查询时,仍然需要遵循其他的安全性最佳实践,如输入验证、权限控制等,以确保应用程序的安全性。

#{},${}区别

#可以作为占位符KaTeX parse error: Expected 'EOF', got '#' at position 24: … 为了防止sql注入,我们使用#̲ #{}是预编译处理,{}是字符串替换。mybatis在处理#{}时,会将sql中的#{}替换为?号,
调用PreparedStatement的set方法来赋值;mybatis在处理 时,就是把 {}时,就是把 时,就是把{}替换成变量的值。使用#{}可以有效的防止SQL注入,提高系统安全性。
(1)$符号一般用来当作占位符,常使用Linux脚本的人应该对此有更深的体会吧。既然是占位符,当然就是被用来替换的
(2)预编译的机。制预编译是提前对SQL语句进行预编译,而其后注入的参数将不会再进行SQL编译。我们知道,
SQL注入是发生在编译的过程中,因为恶意注入了某些特殊字符,最后被编译成了恶意的执行操作。而预编译机制则可以很好的防止SQL注入

Mybatis中用到了哪些设计模式

日志模块:代理模式、适配器模式
数据源模块:代理模式、工厂模式
缓存模块:装饰器模式
初始化阶段:建造者模式
代理阶段:策略模式
数据读写阶段:模板模式
插件化开发:责任链模式

Hibernate与mybatis区别

mybatis 是半自动orm,hibernate是全自动;mybatis结合了hibernate和JDBC两者的特点,比较灵活。
mybatis使用简单方便

Hibernate和MyBatis都是Java持久化框架,但它们在设计理念、实现方式和使用方法上有一些不同之处。

  1. ORM vs. SQL Mapping:
    ○ Hibernate是一个全功能的ORM(对象关系映射)框架,它将数据库表映射到Java对象,并提供了丰富的查询语言(HQL)来操作这些对象。
    ○ MyBatis是一个基于XML配置文件或注解的SQL映射框架,它允许开发者编写原生的SQL查询,并将查询结果映射到Java对象中。
  2. 灵活性:
    ○ Hibernate提供了更高级的抽象,隐藏了大部分SQL细节,因此在简单的CRUD操作上更方便,但在复杂查询或性能调优方面可能略显不足。
    ○ MyBatis更为灵活,允许开发者直接编写和优化SQL,因此在需要对SQL进行精细控制或需要调优的情况下更为适用。
  3. 性能:
    ○ 由于Hibernate提供了自动化的对象关系映射和延迟加载等功能,因此在某些情况下可能会导致性能损失,尤其是在处理大量数据时。
    ○ MyBatis允许开发者直接控制SQL的生成和执行过程,因此可以更精确地优化性能。
  4. 学习曲线:
    ○ Hibernate的学习曲线相对较陡,因为它提供了丰富的功能和复杂的配置选项。
    ○ MyBatis相对来说更简单,更容易上手,因为它更贴近SQL的使用方式。
  5. 社区和支持:
    ○ Hibernate拥有庞大的社区和广泛的文档支持,但由于其复杂性,解决问题可能需要更多的时间和经验。
    ○ MyBatis虽然社区规模相对较小,但也有一定的用户基础和文档支持,且由于其简单性,通常能够更快速地解决问题。

综上所述,选择Hibernate还是MyBatis取决于项目的需求和开发团队的技术栈偏好。如果需要快速上手并且对SQL有较强的控制需求,MyBatis可能更适合;如果项目对ORM的支持和自动化映射有较高需求,同时不介意学习一些复杂性,那么Hibernate可能更合适。
Hibernate中load和get方法的区别
1.get()采用立即加载方式,而load()采用延迟加载; get()方法执行的时候,会立即向数据库发出查询语句,
而load()方法返回的是一个代理(此代理中只有一个id属性),只有等真正使用该对象属性的时候,才会发出sql语句

mybatis一级缓存和二级缓存

一级缓存:mybatis的一级缓存的作用域是session,当openSession()后,如果执行相同的sql(相同语句和参数),mybatis不进去执行sql,而是从缓存中命中返回;
二级缓存:Mybatis的二级缓存的作用域是mapper的namespace,同一个namespace中查询sql可以从缓存中命中。二级缓存可以跨session的;
1、一级缓存Mybatis的一级缓存是指SQLSession,一级缓存的作用域是SQlSession,Mabits默认开启一级缓存;2、Mybatis默认是没有开启二级缓存的

1)一级缓存 Mybatis的一级缓存是指SQLSession,一级缓存的作用域是SQlSession, Mabits默认开启一级缓存。 在同一个SqlSession中,执行相同的SQL查询时;第一次会去查询数据库,并写在缓存中,第二次会直接从缓存中取。 当执行SQL时候两次查询中间发生了增删改的操作,则SQLSession的缓存会被清空。
每次查询会先去缓存中找,如果找不到,再去数据库查询,然后把结果写到缓存中。 Mybatis的内部缓存使用一个HashMap,key为hashcode+statementId+sql语句。Value为查询出来的结果集映射成的java对象。 SqlSession执行insert、update、delete等操作commit后会清空该SQLSession缓存。
2)二级缓存 二级缓存是mapper级别的,Mybatis默认是没有开启二级缓存的。 第一次调用mapper下的SQL去查询用户的信息,查询到的信息会存放代该mapper对应的二级缓存区域。 第二次调用namespace下的mapper映射文件中,相同的sql去查询用户信息,会去对应的二级缓存内取结果
mybatis的二级缓存默认是存在本地的

  1. 一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或
    close 之后,该 Session 中的所有 Cache 就将清空。
  2. 二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于其存储作用域为Mapper(Namespace),并且可自定义存储源,如 Ehcache。作用域为 namespance 是指对该namespance 对应的配置文件中所有的 select 操作结果都缓存,这样不同线程之间就可以共用二级缓存。启动二级缓存:在 mapper 配置文件中:二级缓存可以设置返回的缓存对象策略:。当 readOnly="true"时,表示二级缓存返回给所有调用者同一个缓存对象实例,调用者可以 update 获取的缓存实例,但是这样可能会造成其他调用者出现数据不一致的情况(因为所有调用者调用的是同一个实例)。当 readOnly="false"时,返回给调用者的是二级缓存总缓存对象的拷贝,即不同调用者获取的是缓存对象不同的实例,这样调用者对各自的缓存对象的修改不会影响到其他的调用者,即是安全的,所以默认是 readOnly=“false”;
  3. 对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存 Namespaces)的进行了 C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear。

1.Mybatis 中有一级缓存和二级缓存,采用装饰设计模式;
2.默认情况下一级缓存是开启的,而且是不能关闭的 ,一级缓存是指 SqlSession 级别的缓存,当在同一个 SqlSession 中进行相同的 SQL 语句查询时,第二次以后的查询不会从数据库查询,而是直接从缓存中获取,一级缓存最多缓存 1024 条 SQL
3.二级缓存是指可以跨 SqlSession 的缓存。 是 mapper 级别的缓存,对于 mapper 级别的缓存不同的sqlsession 是可以共享的,需要额外整合到第三方缓存 例如Redis、MongoDB、oscache、ehcache等。
一级、二级缓存 采用装饰模式设计封装

  1. MyBatis默认实现了自己的二级缓存(PerpetualCache),内部使用HashMap实现,无法实现分布式,并且服务器重启后就没有缓存了
  2. MyBatis二级缓存只适用于不常进行增、删、改的数据,比如国家行政区省市区街道数据。一但数据变更,MyBatis会清空缓存。因此二级缓存不适用于经常进行更新的数据。
  3. MyBatis二级缓存是按命名空间(namespace)进行缓存的,可以指定某个命名空间下的sql进行缓存
  4. MyBatis二级缓存的对象必须实现Serializable接口

MyBatis-Plus saveBatch批量插入快原因

MyBatis-Plus 的 saveBatch 方法实现批量插入的快速原因主要有以下几点:

  1. SQL批处理:MyBatis-Plus 在执行 saveBatch 方法时,会将多个插入操作合并为一条 SQL 语句,然后使用 JDBC 批处理机制执行,这样可以减少与数据库的交互次数,提高了插入的效率。
  2. 缓存优化:MyBatis-Plus 在执行 saveBatch 方法时,会优化缓存机制,将需要插入的对象按照一定的规则进行分组,减少了对数据库的频繁访问,从而提高了插入的速度。
  3. 事务控制:MyBatis-Plus 在执行 saveBatch 方法时,会默认开启事务,将多个插入操作作为一个整体提交或回滚,保证了数据的一致性和完整性。
  4. 批量插入SQL的优化:MyBatis-Plus 在生成批量插入的 SQL 语句时,会采用一些优化措施,比如使用多值插入语法、参数占位符等,以提高 SQL 的执行效率。
  5. 数据库优化:MyBatis-Plus 通过合理设计表结构、建立索引等数据库优化措施,进一步提升了批量插入的效率。
    综上所述,MyBatis-Plus 的 saveBatch 方法能够实现批量插入的快速,主要是通过 SQL 批处理、缓存优化、事务控制、批量插入 SQL 的优化以及数据库优化等多种技术手段的综合应用。
    简明:使用MyBatis-Plus实现IService接口中批处理saveBatch()方法,对底层源码进行查看时,可发现其实是for循环插入,但是与第一点相比,为什么性能上提高了
    因为利用分片处理(batchSize = 1000) + 分批提交事务的操作,从而提高性能,并非在Connection上消耗性能
    mybatis plus saveBatch 速度慢,批处理 rewriteBatchedStatements=true
    MySQL Jdbc驱动在默认情况下会无视executeBatch()语句,把我们期望批量执行的一组sql语句拆散,一条一条地发给MySQL数据库,直接造成较低的性能。
    只有把rewriteBatchedStatements参数置为true, 驱动才会帮你批量执行SQL (jdbc:mysql://ip:port/db?rewriteBatchedStatements=true)。不过,驱动具体是怎么样批量执行的? 你是不是需要看一下内幕,才敢放心地使用这个选项? 下文会给出答案。

什么是ORM,有哪些常用框架

ORM(Object-Relational Mapping,对象-关系映射)是一种编程技术,用于将面向对象编程语言中的对象模型与关系数据库中的关系模型进行映射,从而实现数据的持久化和操作。ORM工具可以让开发人员使用面向对象的方式操作数据库,而不需要编写SQL语句,大大简化了数据库操作。
在Java领域,有许多优秀的ORM框架。以下是一些常用的Java ORM框架:

  1. Hibernate:Hibernate是最知名的Java ORM框架之一,它提供了强大的对象关系映射和查询功能,支持多种数据库。
  2. Spring Data JPA:Spring Data是Spring Framework的一个子项目,Spring Data JPA是其中一个模块,提供了对JPA(Java Persistence API)的支持,简化了数据访问层的开发。
  3. MyBatis:MyBatis是一种半自动化的持久层框架,它允许开发者通过XML或注解配置SQL语句和映射关系,灵活性较高。
  4. EclipseLink:EclipseLink是Eclipse基金会的持久化框架,实现了JPA标准,提供了高性能的对象-关系映射解决方案。
  5. QueryDSL:QueryDSL是一个Java领域的类型安全的动态查询框架,可以用于构建类型安全的SQL查询,与JPA、Hibernate等ORM框架兼容。
  6. ActiveJDBC:ActiveJDBC是一个简单而强大的Java ORM框架,它提供了活跃记录模式(Active Record)的实现,易于学习和使用。
  7. jOOQ:jOOQ是一种类型安全的SQL构建器,它允许开发者使用Java编程语言创建类型安全的SQL查询,并提供了与关系数据库交互的灵活性。
    这些是一些常用的Java ORM框架,开发者可以根据项目需求和个人偏好选择合适的框架进行开发。每个框架都有其优势和特点,需要根据具体情况进行选择。

Mybatis用的什么连接池

MyBatis 并没有内置连接池,而是通过与其他连接池整合来管理数据库连接。常见的连接池包括:

  1. Druid:阿里巴巴开源的高性能数据库连接池,提供了强大的监控和扩展功能,被广泛应用于企业级项目中。
  2. HikariCP:轻量级、高性能的 JDBC 连接池,相比其他连接池具有更快的启动速度和更低的资源消耗,被认为是目前性能最好的连接池之一。
  3. Apache Commons DBCP:Apache 基金会提供的数据库连接池,功能齐全,使用简单,被广泛应用于各种 Java 项目中。
  4. C3P0:另一个常用的 JDBC 连接池,提供了连接池管理、连接池监控等功能,适用于大多数 Java 项目。
    在 MyBatis 中配置连接池通常是在数据源配置中进行,可以通过在配置文件中配置相关的数据源信息,然后通过 MyBatis 的配置对象将数据源传入。以下是一个简单的 MyBatis 数据源配置示例,使用 Druid 连接池:
<dataSource type="com.alibaba.druid.pool.DruidDataSource">
    <property name="driver" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
    <property name="username" value="root"/>
    <property name="password" value="password"/>
    <!-- 其他 Druid 连接池配置 -->
</dataSource>

在以上配置中, 标签指定了数据源的类型为 DruidDataSource,然后通过 标签配置了数据库连接的相关信息。

Mybatis 是否支持延迟加载

是的,MyBatis 提供了延迟加载(Lazy Loading)的支持。延迟加载是一种优化技术,可以在需要时才从数据库中加载相关的数据,而不是在一开始就全部加载。
MyBatis 支持两种类型的延迟加载:

  1. 按需延迟加载(On-Demand Lazy Loading):当使用延迟加载配置时,只有在访问关联对象的属性时,MyBatis 才会触发额外的查询来加载这些属性。这样可以避免在一次查询中加载大量的数据,提高性能。
  2. 分步延迟加载(Aggressive Lazy Loading):分步延迟加载是指在查询主对象时,只加载主对象的数据,并不加载关联对象的数据。当访问关联对象属性时,MyBatis 会发起额外的查询来加载关联对象的数据。这种方式可以减少一次性加载大量数据的开销。
    要启用延迟加载,你需要在 MyBatis 的映射文件中配置相应的延迟加载策略。你可以通过、、、等元素来配置延迟加载。
    需要注意的是,延迟加载只适用于关联对象,对于基本类型或简单字段,MyBatis 会立即加载。
    总的来说,MyBatis 提供了灵活的延迟加载机制,可以根据需求选择合适的延迟加载方式,从而提高查询性能和减少资源消耗。

Mybatis可以实现动态SQL么

是的,MyBatis 可以实现动态 SQL。动态 SQL 是指在运行时根据不同的条件生成不同的 SQL 语句,从而实现动态的查询、更新或删除操作。
MyBatis 提供了多种方式来实现动态 SQL:

  1. XML 标签方式:MyBatis 的 XML 映射文件中提供了丰富的动态 SQL 标签,如 、、、、、、、 等,你可以根据需要组合使用这些标签来构建动态 SQL 语句。
<select id="selectByCondition" resultType="...">
    SELECT * FROM users
    <where>
        <if test="name != null">
            AND name = #{name}
        </if>
        <if test="age != null">
            AND age = #{age}
        </if>
    </where>
</select>
  1. 注解方式:除了 XML 文件外,你还可以使用 MyBatis 的注解方式来构建动态 SQL。在注解中使用 @SelectProvider、@UpdateProvider、@DeleteProvider、@InsertProvider 注解,以及对应的提供器类,来动态生成 SQL 语句。
@SelectProvider(type = UserSqlProvider.class, method = "selectByCondition")
List<User> selectByCondition(@Param("name") String name, @Param("age") Integer age);
3. Provider 类方式:通过编写 Provider 类来动态生成 SQL 语句。Provider 类是一个普通的 Java 类,其中的方法可以根据参数来动态生成 SQL 语句。
public class UserSqlProvider {
    public String selectByCondition(String name, Integer age) {
        SQL sql = new SQL().SELECT("*").FROM("users");
        if (name != null) {
            sql.WHERE("name = #{name}");
        }
        if (age != null) {
            sql.WHERE("age = #{age}");
        }
        return sql.toString();
    }
}

通过以上方式,你可以灵活地根据业务需求动态生成 SQL 语句,实现动态的查询、更新或删除操作。

MyBatis-Plus有什么用

MyBatis-Plus 是一个基于 MyBatis 的增强工具库,它简化了 MyBatis 的开发,提供了更便捷的 CRUD 操作、分页、条件构造器、代码生成等功能。以下是 MyBatis-Plus 的一些主要功能和用途:

  1. 简化 CRUD 操作: MyBatis-Plus 提供了丰富的 API,通过继承 MyBatis-Plus 提供的基础 Mapper 接口,可以方便地进行增删改查操作,无需手动编写 XML 映射文件。
  2. 强大的条件构造器: MyBatis-Plus 提供了强大的条件构造器,可以方便地进行动态 SQL 查询。它支持多种条件查询方式,如等于、不等于、大于、小于、模糊查询等,同时支持 Lambda 表达式,提高了查询条件的灵活性和可读性。
  3. 集成分页功能: MyBatis-Plus 提供了内置的分页插件,可以方便地进行分页查询,支持各种常见的数据库(如 MySQL、Oracle、SQL Server 等),并且可以自动解析分页参数,减少了手动编写分页逻辑的工作量。
  4. 代码生成器: MyBatis-Plus 提供了代码生成器工具,可以根据数据库表自动生成对应的 Entity 类、Mapper 接口和 Service 类,大大提高了开发效率。
  5. 乐观锁和逻辑删除: MyBatis-Plus 支持乐观锁和逻辑删除功能,可以在实体类中通过注解标记需要使用的字段,简化了在业务中处理并发和软删除的逻辑。
  6. 通用的 Service 和 Wrapper: MyBatis-Plus 提供了通用的 Service 类,内置了常见的增删改查操作,同时还提供了 Wrapper 类,用于构建复杂的查询条件。

总的来说,MyBatis-Plus 提供了一系列便捷的功能和工具,可以大大提高 MyBatis 的开发效率,减少重复劳动,同时也提高了代码的可读性和可维护性。

  • 19
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

思静语

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值