一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是面试题,也是你 Java 知识点的扫盲贴。
回答Mybatis的运行涉及到Executor、StatementHandler、ParameterHandler、ResultSetHandler等组件,插件的工作原理就是在这些组件执行过程中,插入一些自定义的代码逻辑。MyBatis插件机制允许用户自定义拦截器(实现Interceptor接口),以在执行SQL的各个阶段进行额外的处理。说一下Mybatis的工作原理?实现机制Mybatis使用JDK动态代理,为目标对象生成代理对象。从而在目标对象方法调用时被拦截器拦截处理。publicclassPluginimplementsInvocationHandler{/***创建代理对象*/publicstaticObjectwrap(Objecttarget,Interceptorinterceptor){//获取拦截器关注的类和方法签名的映射Map<Class<?>,Se
回答Executor执行器是Mybatis核心组件,它负责执行SQL语句并处理数据库的交互,主要包括SQL语句的生成、参数绑定、执行、缓存处理以及结果集的映射等。Mybatis内置了三种基本的Executor。SimpleExecutor:每执行一次update或select,就开启一个Statement对象,用完立刻关闭Statement对象。ReuseExecutor:执行update或select,以sql作为key查找Statement对象,存在就使用,不存在就创建,用完后,不关闭Statement对象,而是放置于Map<String,Statement>内,供下一次使用。BatchExecutor:支持批处理的执行器,支持批量更新操作,依赖JDBC的批处理。publicExecutornewExecutor(Transactiontransaction,Executo
回答Mybatis支持两种分页:手动分页和分页插件。手动分页手动分页指在SQL语句中添加LIMIT和OFFSET(或类似的关键字)来实现的。publicinterfaceUserMapper{@Select("SELECTid,name,emailFROMt_userLIMIT#{limit}OFFSET#{offset}")List<User>selectUsersWithPagination(@Param("limit")intlimit,@Param("offset")intoffset);}分页插件MyBatis提供了多种分页插件,可以自动处理分页逻辑,常用的分页插件有PageHelper和MyBatis-Plus。PageHelperPageHelper定义@ConfigurationpublicclassM
回答Mybatis中可以用resultMap中的<result>属性来映射以及SQL别名。CREATETABLEt_user(idINTNOTNULLPRIMARYKEY,nameVARCHAR(50),emailVARCHAR(50))ENGINE=InnoDB;publicclassUser{privateIntegeruserId;privateStringuserName;privateStringuserEmail;//gettersandsetters}第一种,SQL语句中定义字段名的别名。<selectid="selectUserById"parameterType="int"resultType="com.damingge.domain.User">selectidasuserId,name
回答是的,MyBatis的Mapper接口不需要显式实现,因为MyBatis内部使用动态代理机制在运行时生成这些接口的实现。动态代理JDK的动态代理机制可以在运行时创建接口的代理实例。MyBatis基于动态代理为每个Mapper接口生成一个代理对象,从而无需手动实现接口。核心流程注册Mapper接口:在MyBatis配置文件或代码中注册Mapper接口。<mappernamespace="com.damingge.mapper.UserMapper"/>sqlSessionFactory.getConfiguration().addMapper(UserMapper.class);获取Mapper接口代理对象:通过SqlSession获取Mapper接口的代理对象。UserMapperuserMapper=sqlSession.getMapper(UserM
回答Mybatis的Mapper支持四种参数传递方式。单个参数:当Mapper方法只有一个参数时,SQL语句中支持使用#{}占位符来引用该参数。publicinterfaceUserMapper{UserselectUserById(Integerid);}<selectid="selectUserById"parameterType="java.lang.Integer"resultMap="User">SELECTid,name,emailFROMt_userWHEREid=#{id}</select>**多个参数:**当Mapper方法有多个参数时,使用@Param注解为每个参数指定名称。MyBatis会将这些参数放入Map中,键为参数名称。publicinterfaceUserMapper{User
回答支持。Mybatis通过association、collection标签来实现一对一和一对多的关联查询。一对一关联查询一对一关联查询支持两种方式:嵌套查询和结果集嵌套映射。核心是通过association标签支持。publicclassUser{privateIntegerid;privateStringname;privateAddressaddress;//gettersandsetters}publicclassAddress{privateIntegerid;privateStringcity;privateStringprovince;//gettersandsetters}嵌套查询(NestedQueries)<mappernamespace="com.damingge.mapper.UserMapper"><resultMapid=&
回答支持,Mybatis支持两种批量操作。foreach标签foreach主要用在构建in条件中,它可以在SQL语句中遍历一个集合。foreach标签的属性主要有item,index,collection,open,separator,close。item:表示集合中每一个元素进行迭代时的别名,随便起的变量名。index:指定一个名字,用于表示在迭代过程中,每次迭代到的位置,不常用。open:表示该语句以什么开始,常用“(”。separator:表示在每次进行迭代之间以什么符号作为分隔符,常用“,”。close:表示以什么结束,常用“)”。collection:指定要遍历的集合或数组。publicinterfaceUserMapper{voidbatchInsertUser(@Param("userList")List<User>userList);void
回答#{}和${}是MyBatis两种不同的占位符,#{}为预编译处理,而${}是字符串替换。#{}${}用途传递参数,防止SQL注入传递参数,不能防止SQL注入实现机制MyBatis将#{}中的内容替换为?,并在运行时通过PreparedStatement的set方法设置参数值。MyBatis将${}中的内容直接替换为参数值,即将参数直接拼接到SQL字符串中。安全性安全性高,可以有效防止SQL注入。存在安全隐患,直接拼接SQL字符串容易导致SQL攻击。使用场景#{}用在动态SQL参数赋值,防止SQL注入。@Select("SELECT*FROMt_userwhereid=#{id}")UserselectUserById(@Param("id")Longid);//#{}解析替换为?===>SELECT*FROMt_userwhereid=?
回答支持。Mybatis内置了一些动态SQL的标签,允许开发者根据不同的条件构建不同的SQL,提高代码的灵活性和可维护性。如<if>、<choose>、<when>、<otherwise>、<trim>、<where>、<set>和<foreach>等。<if>元素:根据条件动态包含SQL片段。<mappernamespace="com.damingge.mapper.EmployeeMapper"><selectid="selectEmployeeByCondition"resultType="com.damingge.model.Employee">SELECT*FROMt_employee<
回答Mybatis内置了强大了事务性查询缓存机制。默认情况下,Mybatis定义了两级缓存,并且提供Cache接口扩展,提高了框架的扩展性。一级缓存:也叫“本地缓存”,默认情况下开启(SqlSession级别的缓存)二级缓存:也叫“全局缓存”,基于namespace级别的缓存,需要手动开启和配置。实现原理一级缓存Mybatis一级缓存由PerpetualCache实现,采用Map结构存储数据。其作用域是SqlSession,各个SqlSession之间的缓存相互隔离。每次查询后,结果会被缓存到PerpetualCache中,后续相同查询直接取缓存数据。核心实现类和方法BaseExecutor:负责执行SQL,管理一级缓存。publicabstractclassBaseExecutorimplementsExecutor{//...其他代码省略@Overridepublic<E>
回答支持。延迟加载的意思是在使用的时候才去加载,这是一种性能优化策略。延迟加载针对有延迟设置的关联对象推迟查询,而主查询是直接执行SQL语句。优点:先从单表查询,需要时再从关联表查询,减少不必要的数据加载,提升数据库性能。不足:延迟加载会增加数据库访问次数以及增加事务管理的复杂性。扩展延迟加载配置1、Mybatis默认没有开启延迟加载,需要在全局配置文件mybatis-config.xml中进行设置,核心配置项:lazyLoadingEnabled:全局开关,启用或禁用延迟加载。aggressiveLazyLoading:侵入式延迟加载开关,false表示按需加载。<configuration><!--其他配置--><settings><!--延迟加载开关--><settingname="lazyLoadingEnabled&
回答Mybatis包含一些核心组件如Configuration、SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper等。它的生命周期也就是这些组件的生命周期。如下:ConfigurationMyBatis加载配置文件(如mybatis-config.xml)和映射文件(如XXXMapper.xml),生成一个全局配置对象(Configuration),它是一个单例。SqlSessionFactoryMyBatis基于加载的配置文件创建SqlSessionFactory。它是用来创建SqlSession,类比于数据库连接池。SqlSessionFactory是一个单例,它的生命周期是应用作用域。SqlSession通过SqlSessionFactory创建SqlSession。SqlSession类比于JDBC的Connec
回答Mybatis是一款ORM框架,实现了SQL到Java对象的映射转换,简化了持久层代码的开发工作。其核心流程分两步,一是创建会话工厂,二是会话运行。加载配置文件,MyBatis加载全局配置文件(如mybatis-config.xml)和映射文件(如XXXMapper.xml),配置数据库连接、映射器、插件等信息,生成一个全局配置对象(Configuration)。创建SqlSessionFactory,MyBatis基于加载的配置文件创建SqlSessionFactory(用于生成SqlSession)。获取SqlSession,通过SqlSessionFactory获取SqlSession。SqlSession是MyBatis执行SQL操作的核心。执行SQL,Mybatis内部定义了Executor接口来操作数据库,它根据SqlSession传递的参数动态地生成执行SQL,并支持查询
回答Mybatis是一款优秀的持久层框架。它支持自定义SQL、存储过程以及高级映射。Mybatis简化了JDBC代码操作,它通过XML或注解配置将原始类型、接口和JavaPOJO(PlainOldJavaObjects)映射为数据库中的记录。扩展Mybatis优点半ORM框架,Mybatis内部封装了JDBC操作,研发人员仅需关注SQL本身。//1.加载配置文件Propertiespro=newProperties();pro.load(newFileReader("resource/jdbc.properties"));//2.获取配置文件中连接数据库的信息Stringurl=pro.getProperty("url");Stringuser=pro.getProperty("user");Stringpassword=pro.