6.面试题--MyBatis

本文详细介绍了MyBatis框架,包括其作为半ORM框架的特点、优点(如灵活性、减少代码量和与Spring集成)、缺点(如SQL编写工作量和数据库移植性)、适用场景以及关键组件的生命周期。同时,还比较了MyBatis与Hibernate的区别,强调了预编译的作用和SQL注入防范,以及一级缓存和二级缓存的差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

六、MyBatis

什么是Mybatis

Mybatis是一个半ORM框架,它简化了JDBC操作,让开发者只需关注SQL语句本身,而无需处理底层连接、语句创建等细节。Mybatis支持XML或注解配置,可灵活映射POJO与数据库记录,自动生成并执行SQL,最终将结果映射回Java对象。这大大减少了JDBC代码量,提高了开发效率。

Mybatis的优缺点(重点)

优点

  • 基于SQL编程,灵活度高,不影响应用程序或数据库设计。SQL写在XML里面,与代码解耦,便于管理。提供XML标签,支持编写动态SQL语句,并可重用。
  • 与JDBC相比,代码量大幅减少,无需处理连接等冗余代码。
  • 兼容各种数据库,因为Mybatis底层使用JDBC来连接数据库,所以只要JDBC支持的数据库Mybatis都支持。
  • 能够与Spring很好地集成。
  • 提供映射标签,支持对象与数据库的字段关系映射。

缺点

  • 当字段和关联表较多时,SQL编写工作量大,对开发人员编写SQL 语句的功底有一定要求。
  • SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。

MyBatis框架适用场合

  1. 需要灵活DAO层解决方案:Mybatis专注于SQL,提供了足够的灵活性。
  2. 性能要求高或需求变化多:如互联网项目,Mybatis是不错的选择。

Mybatis组件

  • SqlSessionFactoryBuilder:的作用是生成SqlSessionFactory实例,一旦生成了,它的生命周期就结束了。

  • SqlSessionFactory:用于创建SqlSession实例,它是重量级的,包含了创建SqlSession所需的全部配置信息。在整个应用的生命周期内被重用,而不是每次需要时都创建一个新的实例。

  • SqlSession:提供了在数据库上执行命令所需的所有方法,类似于JDBC中的Connection。它是轻量级的,应用于每个方法调用或每个事务中,方法结束时,应该关闭SqlSession,以释放数据库资源。

  • Mapper:当你通过SqlSession调用getMapper(Class type)方法时,MyBatis会动态地生成一个实现了该Mapper接口的代理对象。这个代理对象的生命周期与SqlSession相同。

MyBatis与Hibernate有哪些不同(重点)

ORM(Object-Relational Mapping)是一种技术,它让开发者能在面向对象的语言中,通过对象与数据库表之间的映射,直接操作数据库数据,无需编写SQL或处理数据库底层细节。

开发模式与自动化程度

  • Hibernate:全自动的对象关系映射(ORM)框架,几乎无需手写SQL,降低开发难度。
  • MyBatis:半自动的ORM框架,手写SQL,灵活控制数据库操作。

SQL管理与优化

  • Hibernate:自动生成SQL,复杂查询可能不够优化,性能问题。
  • MyBatis:手写SQL,易于优化,支持动态SQL,SQL语句更加灵活复用。

学习难度

  • Hibernate:需理解映射、事务、缓存等复杂概念,才能有效使用Hibernate。
  • MyBatis:上手相对容易,尤其对于熟悉JDBC的开发者。

预编译的作用

预编译主要对SQL的执行进行优化。经过预编译的SQL多数情况下可以直接执行,数据库服务器无需再次编译,从而提升了性能。此外,预编译语句对象可以重复利用,对于相同的SQL,可以直接使用缓存的预编译对象,进一步提高了效率。

更为关键的是,预编译有助于防止SQL注入攻击。由于预编译后的参数不会再进行SQL编译,系统默认其为普通参数而非SQL语句,从而增强了系统的安全性。

MyBatis中${}和#{}的区别(重点)

#{}可以有效防止SQL注入,#{}是通过PreparedStatement的占位符?来实现的。PreparedStatement会先对SQL语句进行预编译,然后再将参数值设置到占位符上,这样就避免了SQL注入的风险。
${}是字符串替换、是拼接符。MyBatis在处理${}时,会把sql中的${}替换成变量的值。
#{}对应的变量值在替换时,对于字符串类型的变量,会自动在变量值周围加上单引号,以符合SQL语法。
${}替换后的变量值不会自动加上单引号。

MyBatis的插件运行原理,如何编写一个插件。

MyBatis插件机制主要依赖于JDK 的动态代理技术,为特定的接口( Executor、StatementHandler、ParameterHandler、ResultSetHandler)创建代理对象来拦截并增强这些接口方法。

编写插件步骤

  • 编写一个类实现MyBatis的Interceptor 接口,并重写 intercept() 方法。在这个方法中,你可以使用反射来调用目标方法,并在调用前后添加自定义逻辑。
  • 在插件类上使用 @Intercepts注解标识它是一个插件,并使用 @Signature注解指定要拦截的接口、方法以及参数类型。
  • 在MyBatis的配置文件中(如 mybatis-config.xml),使用 标签来配置自定义插。或者在MyBatis的配置文件(MpConfig),使用@Bean注解配置自定义插件。
//自定义插件
@Intercepts({  
    @Signature(  
        type = Executor.class,  
        method = "update",  
        args = {MappedStatement.class, Object.class})  
})  
public class ExamplePlugin implements Interceptor {  
    @Override  
    public Object intercept(Invocation invocation) throws Throwable {  
        System.out.println("Before update method");  
        Object result = invocation.proceed(); // 调用原始方法  
        System.out.println("After update method");  
        return result;  
    }  
  
    @Override  
    public Object plugin(Object target) {  
        return Plugin.wrap(target, this);  
    }  
  
    @Override  
    public void setProperties(Properties properties) {  
        //可以使用 properties 来传递配置参数  
    }  
}

MyBatis一级缓存和二级缓存的区别

作用域:一级缓存是SqlSession级别的,仅在当前SqlSession中有效;而二级缓存是mapper级别的,整个应用共享,可以跨线程使用。

开启方式:一级缓存默认开启,无需额外配置;而二级缓存默认不开启,需要手动配置。

缓存地址:一级缓存主要存储在SqlSession内部;二级缓存则通常存储在应用的外部,如内存或硬盘。

存储对象:一级缓存存储的是具体的查询结果集;二级缓存存储的则是mapper映射文件对应的namespace下的数据对象。

xml中结果类型映射方式

  • 通过在查询的 sql 语句中定义字段名的别名,让字段名的别名和实体类 的属性名一致。
<select id=”selectorder” parametertype=”int” resultetype= me.gacl.domain.order”> 
select order_id id, order_no orderno ,order_price price form orders where order_id=#{id}; 
</select>
  • 通过来映射字段名和实体类属性名的一一对应的关系。
<resultMap type=”me.gacl.domain.order” id=”orderMap”>
<!–用id属性来映射主键字段–>
<id property=”id” column=”order_id”>
<!–用result属性来映射非主键字段,property为实体类属性名,column 为数据表中的属性–> 
<result property = “orderno” column =”order_no”/> 
<result property=”price” column=”order_price” />
 </reslutMap>
 
<select id="getOrder" parameterType="int" resultMap="orderMap"> 
select * from orders where order_id=#{id} 
</select>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值