一、mybatis 中的核心类有哪些?
在MyBatis中,有几个核心类负责实现数据访问和映射操作。以下是MyBatis中的几个核心类:
1. SqlSessionFactoryBuilder:用于从配置文件或配置对象创建SqlSessionFactory实例的构建器类。
2. SqlSessionFactory:SqlSessionFactory是SqlSession的工厂类,它是线程安全的,用于创建SqlSession实例。SqlSession是用于执行SQL语句和管理事务的主要接口。
3. SqlSession:SqlSession是与数据库进行交互的主要接口。它提供了执行SQL语句、获取Mapper接口的实例、控制事务提交和关闭会话等方法。
以上三者使用的代码实现:
public void test1() throws IOException {
SqlSessionFactoryBuilder sfb=new SqlSessionFactoryBuilder();
SqlSessionFactory build = sfb.build(Resources.getResourceAsStream("mybatis-config.xml"));
SqlSession sqlSession = build.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.selectAll();
userList.forEach(System.out::println);
}
4. Configuration:Configuration是MyBatis的核心配置类,它包含了MyBatis的全局配置信息,包括数据库连接信息、映射器文件配置、插件配置等。
5. Executor:Executor是执行SQL语句的接口,它定义了一些方法用于执行SQL语句、处理结果集等。
6. StatementHandler:StatementHandler是执行SQL语句的核心类,它负责创建和管理PreparedStatement对象,执行SQL语句并处理结果集。
7. ParameterHandler:ParameterHandler是处理SQL语句中的参数的接口,它负责设置SQL语句中的参数值。
8. ResultSetHandler:ResultSetHandler是处理SQL语句返回结果集的接口,它负责将结果集映射到Java对象。
9. MappedStatement:MappedStatement是映射器文件中一条SQL语句的映射信息,包括SQL语句,参数映射信息,结果集映射信息等。
这些是MyBatis中的一些核心类,它们共同协作实现了数据访问和映射功能。
二、mybatis 框架中都用到了那些核心的设计模式?
在MyBatis框架中,使用了以下一些核心的设计模式:
1. Builder模式:MyBatis使用了Builder模式来构建SqlSessionFactory和Configuration对象。通过使用链式调用和方法分步构建的方式,创建复杂的对象,提高了代码的可读性和可维护性。
2. 工厂模式:MyBatis使用了工厂模式来创建SqlSessionFactory和SqlSession对象。SqlSessionFactoryBuilder负责创建SqlSessionFactory实例,而SqlSessionFactory则负责创建SqlSession实例。这种方式将对象的创建和使用分离,并且可以通过配置文件来实现具体的对象创建方式,提高了系统的灵活性和可扩展性。
3. 代理模式:MyBatis使用了动态代理模式来实现Mapper接口的代理对象。MyBatis会根据Mapper接口的定义动态生成代理对象,代理对象内部封装了底层的SQL执行逻辑,并将Mapper接口的方法调用转发给真正的SQL执行器。
4. 模板方法模式:MyBatis中的Executor和StatementHandler类使用了模板方法模式。Executor是执行SQL语句的接口,定义了一个模板方法execute,具体的SQL执行逻辑由其子类实现。同样,StatementHandler也是一个抽象类,定义了处理SQL语句的模板方法,具体的SQL处理逻辑由其子类实现。
5. 装饰器模式:MyBatis中的Plugin机制使用了装饰器模式。Plugin是一个接口,定义了对MyBatis底层对象的增强操作。通过实现Plugin接口,并将其注册到MyBatis的配置中,可以在MyBatis的执行过程中对底层对象进行拦截和增强操作。
6. 映射器模式:MyBatis使用了映射器模式,将SQL语句和Java对象之间的映射关系定义在映射器文件中。映射器文件中的select、insert等SQL语句与Java方法的映射关系,让开发人员可以将精力集中在编写Java逻辑上,而不用过多关注SQL语句的编写和参数映射等细节。
这些设计模式在MyBatis框架中起到了重要的作用,它们使得框架的设计更加灵活、可扩展,并帮助开发人员编写更加优雅和可维护的代码。
三、mybatis 的主键自增如何实现,接口传递多个参数如何解决?
主键自增的实现如下两种方式:
1、通过last_insert_id()查询主键(自增主键)
方式1:通过selectKey标签将查询的id回填到指定属性中
标签:< selectKey id="" parameterType="" order="AFTER|BEFORE">
<!--
keyProperty 主键的属性
order:在执行之前获取还是在执行之后获取
resultType 主键的返回值类型
-->
<insert id="insertUser1" >
<selectKey keyProperty="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
insert into tb_user (username,password) values (#{username},#{password})
</insert>
2、 直接映射主键(自增主键)
方式2:使用useGeneratedKeys使用生成的id,并回填写到指定的属性中
<!--
useGeneratedKeys:使用自动生成的id
keyProperty:将生成的id添加到指定的属性中,id属性值表示的是实体类中的属性名
-->
<insert id="insertUser1" useGeneratedKeys="true" keyProperty="id">
insert into tb_user (username,password) values (#{username},#{password})
</insert>
关于接口传递多个参数的解决方案,MyBatis提供了多种方式:
-
使用@Param注解:在映射器接口方法的参数上使用@Param注解,可以指定每个参数的名称,然后在SQL语句中通过参数名称引用对应的参数。
-
使用Map传递参数:将多个参数封装为一个Map对象,通过key-value的方式传递,然后在SQL语句中通过Map的key来获取对应的值。
-
使用POJO/DTO对象:创建一个专门的POJO(Plain Old Java Object)或DTO(Data Transfer Object)对象,将多个参数封装到该对象中,然后在SQL语句中通过对象的属性名来获取对应的值,也就是创建数据表的映射类。
四、mybtais xml配置文件中的 #{} 和 ${} 之间的区别是什么?当前后字段不一致怎么办?
MyBatis XML配置文件中的`#{}`和`${}`的区别如下:
1. `#{}`:称为预编译语句占位符,用于替代SQL语句中的参数。在执行SQL语句前,MyBatis会将`#{}`替换为具体的参数值,以保证安全性和防止SQL注入的问题。`#{}`可以防止参数值中的特殊字符影响SQL语句的解析和执行过程。
2. `${}`:称为文本替换占位符,用于字符串拼接和替换。在XML配置文件中,`${}`会被替换成对应参数的文本值。`${}`是直接字符串替换,不会进行预编译处理,因此需要注意潜在的安全风险,避免将用户输入直接拼接到SQL语句中,可能导致SQL注入问题。另外,`${}`在属性值中也可以使用。
关于字段名称不一致的情况,可以通过以下方式解决:
1. 使用别名:在SQL语句中使用别名为字段取一个更加直观的名称,例如`SELECT id AS userId, name AS userName FROM user WHERE id = #{id}`。这样,使用`#{id}`作为参数时,MyBatis会根据别名来解析对应的字段。
2. 使用Map传递参数:将多个参数封装为一个Map对象,在Map中使用键值对的方式表示参数名称和参数值。在SQL语句中通过Map的key来获取对应的值。这样,可以忽略参数名称和字段名称的不一致。
3. 使用@Param注解:在映射器接口方法的参数上使用@Param注解,可以给参数指定一个名称,然后在SQL语句中通过注解指定的名称来引用对应的参数。
4、自定义结果映射(ResultMap):在 resultMap 标签中对每个字段进行重命名,要和创建的实体类的字段名一致。
注意,如果使用`${}`进行字段拼接,在字段名称不一致的情况下,可能会导致SQL语句拼接错误或无法找到对应的字段。因此,建议在字段拼接时使用`#{}`,以确保参数值的安全性和正确性。
五、mybatis怎么开启批处理,动态sql如何实现?
通过< foreach >标签开启批处理
foreach 标签的作用是遍历集合或者数组
参数 | 描述 | 取值 |
---|---|---|
collection | 容器类型 | list、array、map(可以在形参上加注解改变名称) |
open | 起始符 | ( |
close | 结束符 | ) |
separator | 分隔符 | , |
index | 下标号 | 从0开始,依次递增 |
item | 当前项 | 任意名称(循环中通过 #{任意名称} 表达式访问) |
批量增加
<!-- insert into 表名 (字段名1,字段名2,...) values (值1,...),(值1,...) ,(值1,...) -->
<insert id="insertProduct">
insert into product (p_name,p_time,p_state,p_price) values
<foreach collection="productList" item="product" separator=",">
(#{product.name},#{product.time},#{product.state},#{product.price})
</foreach>
</insert>
批量删除
<!-- delete from 表名 where p_id in (id1,id2,..) -->
<delete id="deleteProduct">
delete from product where p_id in
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</delete>
常用的动态SQL标签如下:
< sql >
sql标签的作用是提取公共的sql代码片段
sql id属性:唯一标识
include refid属性:参照id
< if >
if标签的作用适用于条件判断
test 属性:判断条件(必填)
< where >
where 标签作用是添加where条件。 如果没有条件,不会加上where。 会自动去掉前的and|or等关键字
< set >
set 标签的作用是添加set,与where类似
特点:
1、如果set有条件自动加上set关键字,如果没有则不会set关键字
2、会自动去除后面的 ,
< choose >
choose标签作用是条件选择。类似于Java中的多重if
choose 、when 、otherwise
< trim >
< trim prefix="" suffix="" prefixOverrides="" suffixOverrides="" >代替< where > 、< set >
prefix 前缀
suffix 后缀
prefixOverrides 前缀覆盖
suffixOverrides 后缀覆盖
六、mybatis 中的一对一映射和一对多 映射关系的 xml 配置文件有哪些不同点?
association: 一对一的关联映射
property:实体类中属性名称(在Person类中定义的Passport属性的名称)
javaType:映射对应java类型
collection:一对多的关联映射
property:关联的实体类中的集合的属性名
ofType: 集合泛型的类型
多对多映射就是多个一对多映射,通过一个中间关联表来实现
多对一映射就是多个一对一映射
七、mybatis 中延时加载策略怎么实现,一级缓存和二级缓存怎么实现?
MyBatis中的延迟加载策略、一级缓存和二级缓存是实现高效数据访问和性能优化的重要特性。下面是对它们的简要介绍:
1. 延迟加载策略(Lazy Loading):延迟加载是指在需要访问关联对象时才进行加载,而不是立即加载所有关联对象。MyBatis中通过配置关联对象的`fetchType`属性为`lazy`来实现延迟加载。当需要访问关联对象时,MyBatis会发起额外的查询来加载关联对象的数据。
2. 一级缓存(Local Cache):一级缓存是指在同一个SqlSession中,对于相同的查询语句,MyBatis会缓存查询结果。当再次执行相同的查询时,MyBatis会直接从缓存中获取结果,而不需要再次执行查询。一级缓存是默认开启的,可以通过配置`localCacheScope`属性来控制缓存的作用范围。
3. 二级缓存(Second Level Cache):二级缓存是指在多个SqlSession之间共享缓存。它可以跨越多个SqlSession,当一个SqlSession执行查询后,查询结果会被缓存起来,其他SqlSession可以直接从缓存中获取结果,而不需要再次执行查询。二级缓存需要手动配置,并且需要在Mapper XML文件中指定缓存的实现方式。
要启用二级缓存,需要进行以下步骤:
- 在MyBatis的配置文件中,配置`<setting name="cacheEnabled" value="true"/>`来启用缓存。
- 在Mapper XML文件中,使用`<cache/>`标签来配置缓存的实现方式,如`<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>`。
需要注意的是,一级缓存和二级缓存是相互独立的,一级缓存只在当前SqlSession中有效,而二级缓存是在多个SqlSession之间共享的。
通过合理配置延迟加载策略、一级缓存和二级缓存,可以提高MyBatis的性能和效率,减少数据库访问次数,从而提升应用程序的响应速度。
八、mybatisPlus 中常用的插件有哪些?
MyBatis-Plus是一个基于MyBatis的增强工具,提供了许多实用的插件来简化开发和提升效率。以下是MyBatis-Plus中常用的插件:
1. 分页插件(PaginationInterceptor):提供了分页查询的功能,可以方便地进行分页查询操作。
2. 乐观锁插件(OptimisticLockerInterceptor):用于实现乐观锁机制,通过版本号或者时间戳来控制并发更新操作。
3. SQL执行分析插件(SqlExplainInterceptor):用于输出SQL语句的执行计划,方便开发人员进行SQL性能优化。
4. 性能分析插件(PerformanceInterceptor):用于输出SQL语句的执行时间和慢查询日志,帮助开发人员进行性能调优。
5. 动态表名插件(DynamicTableNameInterceptor):用于动态切换表名,可以根据不同的条件选择不同的表进行操作。
6. 自动填充插件(MetaObjectHandler):用于自动填充实体类中的字段,例如创建时间、更新时间等。
7. 逻辑删除插件(ISqlInjector):用于逻辑删除数据,通过在SQL语句中增加条件来实现逻辑删除操作。
8. 多租户插件(TenantLineHandler):用于实现多租户的数据隔离,可以根据不同的租户ID来过滤数据。
以上是MyBatis-Plus中常用的插件,它们提供了丰富的功能和扩展点,可以根据具体的需求选择合适的插件来增强MyBatis的功能。