Mybatis行为配置之Ⅲ—其他行为配置项说明

专栏精选

引入Mybatis

Mybatis的快速入门

Mybatis的增删改查扩展功能说明

mapper映射的参数和结果

Mybatis复杂类型的结果映射

Mybatis基于注解的结果映射

Mybatis枚举类型处理和类型处理器

再谈动态SQL

Mybatis配置入门

Mybatis行为配置之Ⅰ—缓存

Mybatis行为配置之Ⅱ—结果相关配置项说明

文章目录

  • 专栏精选
  • 引言
  • 摘要
  • 正文
      • defaultExecutorType
      • defaultStatementTimeout
      • defaultResultSetType
      • safeRowBoundsEnabled
      • safeResultHandlerEnabled
      • jdbcTypeForNull
      • defaultScriptingLanguage
      • defaultEnumTypeHandler
      • callSettersOnNulls
      • useActualParamName
      • returnInstanceForEmptyRow
  • 总结

引言

大家好,我是奇迹老李,一个专注于分享开发经验和基础教程的博主。欢迎来到我的频道,这里汇聚了汇集编程技巧、代码示例和技术教程,欢迎广大朋友们点赞评论提出意见,重要的是点击关注喔 🙆,期待在这里与你共同度过美好的时光🕹️。今天要和大家分享的内容是Mybatis行为配置之Ⅲ—其他常用配置项说明。做好准备,Let’s go🚎🚀

摘要

在这篇文章中,我们将了解剩下的关于Mybatis行为的配置,在mybatis项目开发过程中这些配置可能并不常用,而且大多数情况下都是使用默认配置,了解这些配置的意义可以让我们在解决很多罕见异常问题时有的放矢,不至于手忙脚乱。那么准备好开启今天的神奇之旅了吗?

正文

首图

今天我们介绍Mybatis中最后几个控制Mybatis行为的配置项,它们是

defaultExecutorType

备注:配置默认的执行器。

默认值:SIMPLE

可选值:

说明对应的Executor实现类
SIMPLE普通的执行器,使用JDBC默认StatementSimpleExecutor
REUSE预处理语句执行器,使用JDBC的PreparedStatementReuseExecutor
BATCH重用语句+批量更新执行器BatchExecutor

建议值:SIMPLE

建议原因:SIMPLE比较通用。如果有特殊需求,可以通过 SqlSessionFactoryBuilder#openSession(ExecutorType execType)方法获取到包含对应的Executor的SqlSession。

注:Executor保存在 org.apache.ibatis.session.defaults.DefaultSqlSession类中。

批量插入数据的代码示例

 public class EnvConfigTest {    private SqlSessionFactory sqlSessionFactory;    private SqlSession sqlSession;  @Test    public void testBatchInsert(){    List<AppTestEntity> list=new ArrayList<>();    AppTestEntityBuilder builder = new AppTestEntityBuilder();    builder.setAppName("test-name").setAppCode("test-name-code").setAuthType("1").setCreator("junit");    list.add(builder.build());    //省略n个list.add    //关键在ExecutorType.BATCH  SqlSession session = this.sqlSessionFactory.openSession(ExecutorType.BATCH);    ApplicationRepository mapper = session.getMapper(ApplicationRepository.class);    list.stream().forEach(o->{    mapper.addApp(o);    });    session.commit();    session.close();    }    }

defaultStatementTimeout

备注:等待数据库响应的秒数。这项配置需要数据库驱动的支持,在Mysql中此项配置基本无效,在postgres数据库中此配置有效
默认值:null
可选值:任意正整数
建议值:根据实际情况设置
建议原因:取决于数据库硬件和配置

Postgres配置下的测试代码:

public class PostgresTest {  private SqlSessionFactory sqlSessionFactory;  private SqlSession sqlSession;  @Before  public void before(){  try (InputStream inputStream = PostgresTest.class.getResourceAsStream("/mybatis-config.xml")){  this.sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream,"postgres9");  this.sqlSession=this.sqlSessionFactory.openSession();  } catch (IOException e) {  throw new RuntimeException(e);  }  }  @After  public void after(){  this.sqlSession.clearCache();  this.sqlSession.close();  }  //新增十万条数据@Test  public void testBatchInsert(){  List<AppTestEntity> list=new ArrayList<>();  AppTestEntityBuilder builder = new AppTestEntityBuilder();  builder.setAppName("test-name").setAppCode("test-name-code").setAuthType("1").setCreator("junit");  for (int i = 0; i < 100000; i++) {  AppTestEntity e = builder.build();  e.setId(((long) i+1));  list.add(e);  }  //省略n个list.add  SqlSession session = this.sqlSessionFactory.openSession(ExecutorType.BATCH);  ApplicationRepository mapper = session.getMapper(ApplicationRepository.class);  list.stream().forEach(o->{  mapper.addApp(o);  });  session.commit();  session.close();  }  //查询测试@Test  public void testFetchSize(){  SimpleQueryMapper mapper = this.sqlSession.getMapper(SimpleQueryMapper.class);  long start = System.currentTimeMillis();  List<AppTestEntity> list = mapper.queryList("1");  long gap = System.currentTimeMillis() - start;  System.out.println("selected result size: "+list.size());  System.out.println("selected time: "+gap);  }  
}

配置 <setting name="defaultFetchSize" value="1"/>后的输出

selected result size: 100000
selected time: 8994

配置 <setting name="defaultFetchSize" value="1000"/>后的输出

selected result size: 100000
selected time: 413

不配置情况下的输出

selected result size: 100000
selected time: 418

细节 这里需要注意,此配置会被 fetchSize属性覆盖。fetchSize可以通过以下方式设置

  1. 注解的方式
@Select(value = "select * from app_test where auth_type=#{type}")  
@Options(fetchSize = 1000)  
List<AppTestEntity> queryList(@Param("type") String type);
  1. 标签的方式
<select id="queryList" resultType="AppTestEntity" fetchSize="1000">  select * from app_test where auth_type=#{type}
</select>

defaultResultSetType

备注:指定语句默认的滚动策略
可选值:

配置值说明
FORWARD_ONLY索引只能向后方滚动,不能往前
SCROLL_SENSITIVE索引可向前后滚动,且更新敏感
SCROLL_INSENSITIVE索引可向前后滚动,且更新不敏感
DEFAULT默认,效果和不设置相同

默认值:null(DEFAULT)
建议值:不设置
建议原因:不常用,此配置是对jdbc的行为控制,而在mybatis项目中不会直接操作jdbc

safeRowBoundsEnabled

备注:是否允许在嵌套语句(子查询)中使用分页API(RowBounds)。如果允许使用则设置为 false
默认值:false
建议值:
建议原因:

此配置常见的生效情况是,调用了 sqlSession#selectList(String statement,Object param,RowBounds rowBounds)这个方法,而参数statement又是嵌套语句,如以下测试代码:

@Test  
public void testSafeRow(){  List objects = this.sqlSession.selectList("top.sunyog.mybatis.mapper.SimpleQueryMapper.queryAppDetail", 1, new RowBounds(0, 1));  for (Object obj : objects) {  System.out.println(obj);  }  
}

此代码在默认配置情况下可以正常输出

AppTestEntity{id=null, appName='测试应用1', appCode='ceshi', authType='1', createDate=2023-10-31, creator='admin', appStatus='3', authTypeDict=DictTest{dictName='NONE', dictCode='1', dictType='app_auth_type', dictSort=0}, appStatusDict=DictTest{dictName='正常应用', dictCode='3', dictType='app_status', dictSort=0}, services=[ServiceTestEntity{id=3, serviceName='注册中心', serviceCode='nacos-service', servicePath='/nacos', appId=1}]}

而配置 <setting name="safeRowBoundsEnabled" value="true"/>后,会报错

org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: org.apache.ibatis.executor.ExecutorException: Mapped Statements with nested result mappings cannot be safely constrained by RowBounds. Use safeRowBoundsEnabled=false setting to bypass this check.
### The error may exist in mapper/SimpleQueryMapper.xml
### The error may involve top.sunyog.mybatis.mapper.SimpleQueryMapper.queryAppDetail
### The error occurred while handling results
### SQL: select t1.*             ,t2.dict_code as auth_type_dc,t2.dict_name as auth_type_dn,t2.dict_type as auth_type_dt,t2.dict_sort as auth_type_ds         from (             select id,app_name,app_code,auth_type,create_date,creator,app_status from app_test where id=?         ) t1 left join (             select dict_code,dict_name,dict_type,dict_sort from dict_test where dict_type='app_auth_type'         ) t2 on t1.auth_type=t2.dict_code
### Cause: org.apache.ibatis.executor.ExecutorException: Mapped Statements with nested result mappings cannot be safely constrained by RowBounds. Use safeRowBoundsEnabled=false setting to bypass this check.

safeResultHandlerEnabled

备注:是否允许在嵌套语句中使用结果处理器(ResultHandler)。如果允许使用则设置为 false
默认值:true
建议值:按实际情况设置
建议原因:
结果处理器ResultHandler的使用方法见Mybatis基于注解的结果映射这篇文章

jdbcTypeForNull

备注:当没有为参数指定特定的 JDBC 类型时,空值的默认 JDBC 类型。 某些数据库驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER
可选值:org.apache.ibatis.type.JdbcType 常量
默认值:OTHER
建议值:不设置
建议原因:

defaultScriptingLanguage

备注:指定动态 SQL 生成使用的默认脚本语言。
默认值:org.apache.ibatis.scripting.xmltags.XMLLanguageDriver
建议值:不设置
建议原因:不常用

defaultEnumTypeHandler

备注:指定枚举类型的默认TypeHandler,关于枚举类型的TypeHandler使用示例,见[[Mybatis基础#枚举类型映射]]
默认值:EnumTypeHandler
建议值:按实际情况设置,建议设置为 EnumOrdinalTypeHandler
建议原因:实际应用中,枚举类型大多数都是顺序编码的字典值

callSettersOnNulls

备注:指定当结果集中值为 null 的时候是否调用映射对象的 setter(map 对象时为 put)方法
默认值:false
建议值:true
建议原因:返回值中某个字段为null时,再map对象中也会插入这个对应的key,这样可以减少对map的 containsKey方法操作。

通过以下代码测试设置的行为

@Test  
public void testNullSet(){  SimpleQueryMapper mapper = this.sqlSession.getMapper(SimpleQueryMapper.class);  //在这之前先执行这个sql//update app_test set creator=null where id=13;List<Map<String, Object>> list = mapper.queryMapRes(13);  System.out.println(list);  
}

默认设置时的输出:

[{app_name=test-name, auth_type=1, id=13, create_date=2023-11-30, app_code=test-name-code}]

配置 <setting name="callSettersOnNulls" value="true"/>时的输出

[{app_name=test-name, auth_type=1, creator=null, id=13, create_date=2023-11-30, app_code=test-name-code}]

useActualParamName

备注:允许使用方法签名中的名称作为语句参数名称。 为了使用该特性,项目必须采用 Java 8 编译,并且加上 -parameters 选项
默认值:true
建议值:true
建议原因:

parameters选项的添加方式为修改maven的pom.xml文件

细节:这个插件安装或修改后,需要执行maven:cleanmaven:compile后才能生效

<project>
...<build>  <plugins>            <plugin>                <groupId>org.apache.maven.plugins</groupId>  <artifactId>maven-compiler-plugin</artifactId>  <configuration>                  <compilerArgs>                        <arg>-parameters</arg>  </compilerArgs>                </configuration>            </plugin>        </plugins>    </build>
</project>

新增测试代码

@Test  
public void testMethodParam(){  SimpleQueryMapper mapper = this.sqlSession.getMapper(SimpleQueryMapper.class);  List<AppTestEntity> list = mapper.getAppByStatusAndAuthType("3","1");  System.out.println(list);  
}
public interface SimpleQueryMapper {//注意,这里的入参没有添加@Param注解List<AppTestEntity> getAppByStatusAndAuthType(String status,String authType);  
}
<select id="getAppByStatusAndAuthType" resultType="appTestEntity">  <include refid="top.sunyog.mybatis.mapper.ApplicationRepository.query_column"></include>  where app_status=#{status} and auth_type=#{authType}  
</select>

配置 <setting name="useActualParamName" value="false"/>后执行报错

org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: org.apache.ibatis.binding.BindingException: Parameter 'status' not found. Available parameters are [0, 1, param1, param2]
### Cause: org.apache.ibatis.binding.BindingException: Parameter 'status' not found. Available parameters are [0, 1, param1, param2]

默认配置或 <setting name="useActualParamName" value="true"/>配置下,打印结果

[AppTestEntity{id=1, appName='测试应用1', appCode='ceshi', authType='1', createDate=2023-10-31, creator='admin', appStatus='3', authTypeDict=null, appStatusDict=null, services=null}]

returnInstanceForEmptyRow

备注:当返回行的所有列都是空时,默认返回 null。 当开启这个设置时,MyBatis会返回一个空实例。 请注意,它也适用于嵌套的结果集
默认值:false
建议值:true
建议原因:可减少空指针验证

测试代码

public interface SimpleQueryMapper {@Select("select name,code from empty_table_test where 1=1 limit 0,1")  Map<String, Object> queryEmptyMap(int i);  
}public class EnvConfigTest {@Test  public void testReturnEmptyObj(){  SimpleQueryMapper mapper = this.sqlSession.getMapper(SimpleQueryMapper.class);  Map<String,Object> entity = mapper.queryEmptyMap(112);  System.out.println(entity);  }
}

新增可为空的测试表

create table empty_table_test  
(  name int         null,  code varchar(32) null  
);
insert into empty_table_test(name,code) values(null,null),(null,null)

默认配置下的输出

null

配置 <setting name="returnInstanceForEmptyRow" value="true"/>时的输出

{}

总结

今天介绍的配置项在日常工作中很多都不是很常用,但了解这些配置可以减少很多不必要的错误,甚至解决一些罕见的异常问题。如 returnInstanceForEmptyRow这个配置能在很大程度上减少空指针异常的出现。


📩 联系方式
邮箱:qijilaoli@foxmail.com

❗版权声明
本文为原创文章,版权归作者所有。未经许可,禁止转载。更多内容请访问奇迹老李的博客首页

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/583921.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电子工程师如何接私活赚外快?

对电子工程师来说&#xff0c;利用业余时间接私活是个很常见的技术&#xff0c;不仅可以赚取额外收入&#xff0c;也能提升巩固技术&#xff0c;可以说国内十个工程师&#xff0c;必有五个在接私活养家糊口&#xff0c;如果第一次接私活&#xff0c;该如何做&#xff1f; 很多工…

再升级|川石教育鸿蒙应用开发4.0教程发布

全新鸿蒙蓄势待发 HarmonyOS是一款面向未来的全场景分布式智慧操作系统。 对于消费者而言&#xff0c;HarmonyOS用一个统一的软件系统从根本上解决消费者面对大量智能终端体验割裂的问题&#xff0c;为消费者带来统一、便利、安全的智慧化全场景体验。 对于开发者而言&#xf…

十二:爬虫-Scrapy框架(上)

一&#xff1a;Scrapy介绍 1.Scrapy是什么&#xff1f; Scrapy 是用 Python 实现的一个为了爬取网站数据、提取结构性数据而编写的应用框架(异步爬虫框架) 通常我们可以很简单的通过 Scrapy 框架实现一个爬虫&#xff0c;抓取指定网站的内容或图片 Scrapy使用了Twisted异步网…

(切图笔记)layui表格单元格添加超链接 以及传参方法 亲测可用 附代码

layui在切图网日常的工作中常常用到&#xff0c;特别是它的layer弹窗&#xff0c;基本可以满足网站切图时候遇到的绝大多数弹窗的情况&#xff0c;参数比较丰富 灵活&#xff0c;是不可多得的网页插件之一&#xff0c;我见很多人说layui过时了&#xff0c;这是相比于vue正流行的…

Java8 - 更优雅的字符串连接(join)收集器 Collectors.joining

Java8中的字符串连接收集器 在JDK8中&#xff0c;可以采用函数式编程&#xff08;使用 Collectors.joining 收集器&#xff09;的方式对字符串进行更优雅的连接。 Collectors.joining 收集器 支持灵活的参数配置&#xff0c;可以指定字符串连接时的 分隔符&#xff0c;前缀 和…

Sentinel-3如何处理并下载LST数据-陆地表面温度”(Land Surface Temperature)

LST 通常指的是“陆地表面温度”&#xff08;Land Surface Temperature&#xff09;。陆地表面温度是指地球表面上陆地部分的温度&#xff0c;而不包括水体表面。LST 是遥感技术中一个重要的参数&#xff0c;可以通过卫星遥感等手段进行测量和监测。 陆地表面温度对于许多领域…

浅谈高并发以及三大利器:缓存、限流和降级

引言 高并发背景 互联网行业迅速发展&#xff0c;用户量剧增&#xff0c;系统面临巨大的并发请求压力。 软件系统有三个追求&#xff1a;高性能、高并发、高可用&#xff0c;俗称三高。三者既有区别也有联系&#xff0c;门门道道很多&#xff0c;全面讨论需要三天三夜&#…

人工智能_机器学习072_SVM支持向量机_人脸识别模型训练_训练时间过长解决办法_数据降维_LFW人脸数据建模与C参数选择---人工智能工作笔记0112

我们先来看一下之前的代码: import numpy as np 导入数学计算库 from sklearn. svm import SVC 导入支持向量机 线性分类器 import matplotlib.pyplot as plt 加载人脸图片以后,我们用pyplot把人脸图片数据展示一下 from sklearn.model_selection import train_test_split 人脸…

Unity之组件的生命周期

PS&#xff1a;第二天&#xff0c;依旧在摸鱼学unity 一、组件的概念 我本身是由Web后端转到了游戏后端&#xff0c;最近因为工作原因在学ET框架。学到了 ECS 编程模式开发&#xff08;E —— Entity&#xff0c;C —— Component &#xff0c; S —— System&#xff09;实体、…

【rosbag】rosbag命令--查看提取bag中的内容

1.查看消息 rosbag info --.bag topics是其中的话题内容&#xff0c;/imu中只写了包含imu的数据&#xff0c;但是imu是9轴的&#xff0c;到底磁力计信息是否包含在其中呢&#xff1f; 2.将bag中的某个话题转为txt 将file_name.bag文件中topic_name话题的消息转换到Txt_name.…

BIT-666 的 2023 年度总结

<<< 年度总结 >>> <<< 年度数据 >>> ◆ 发博情况 ◆ 学习成就 ◆ 代码提交 ◆ 博文表现 <<< 年度创作 >>> ◆ LLM - LLaMA2 <<< 年度风景 >>> ◆ 春 - 中关村软件园 - 百望山 ◆ 夏 - 乌兰…

Python开发一个电商平台历史价格查询软件

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 环境介绍: python 3.8 pycharm 专业版 第三方模块使用 requests ——> 发送 HTTP 请求 execjs ——> 用来执行JavaScript代码 pyecharts ——> 生成…

视频美颜sdk是什么?美颜sdk贴纸技术详解

如今&#xff0c;贴纸技术作为视频美颜的一个创新分支&#xff0c;为用户提供了更加丰富多彩的互动体验。本文将深入探讨视频美颜SDK中的贴纸技术&#xff0c;揭示其技术原理、应用场景以及未来发展趋势。 一、贴纸技术的背后&#xff1a;图像处理与人脸识别 这一步骤是实现贴…

关于IDEA中Git版本回滚整理

Git分区理解 git的版本回滚本质上就是回滚不同的分区&#xff0c;所以咱们有必要简单了解一下git的分区。git在本地有三大分区&#xff1a;暂存区、工作区、版本库。 暂存区: add后的代码&#xff0c;绿色。 **工作区&#xff1a;**正在编写&#xff0c;还未add的部分&#…

【Vue】事件修饰符详解

✨ 专栏介绍 在当今Web开发领域中&#xff0c;构建交互性强、可复用且易于维护的用户界面是至关重要的。而Vue.js作为一款现代化且流行的JavaScript框架&#xff0c;正是为了满足这些需求而诞生。它采用了MVVM架构模式&#xff0c;并通过数据驱动和组件化的方式&#xff0c;使…

【SpringBoot篇】详解Bean的管理(获取bean,bean的作用域,第三方bean)

文章目录 &#x1f354;Bean的获取&#x1f384;注入IOC容器对象⭐代码实现&#x1f6f8;根据bean的名称获取&#x1f6f8;根据bean的类型获取&#x1f6f8;根据bean的名称和类型获取 &#x1f384;Bean的作用域⭐代码实现&#x1f388;注意 &#x1f384;第三方Bean⭐代码实现…

设计模式-对象池模式

设计模式专栏 模式介绍模式特点应用场景对象池模式和工厂模式的区别代码示例Java实现对象池模式Python实现对象池模式 对象池模式在spring中的应用 模式介绍 对象池模式是一种创建型设计模式&#xff0c;它将对象预先创建并初始化后放入一个池中&#xff0c;以供其他对象使用。…

IDEA 2022.2 安装教程

1.下载2020.3版本IDEA 链接&#xff1a;https://pan.baidu.com/s/1IFK8VRjT7vM2VM75ToveGQ?pwd176m 提取码&#xff1a;176m 2.安装 下载完成后&#xff0c;双击exe安装包&#xff0c;出现IDEA安装欢迎首页&#xff1a; 3.将 ja - netfiltet 文件复制到idea安装目录附件 …

云上攻防--云服务对象存储(域名接管)弹性计算(元数据泄露)

云上攻防–云服务&&对象存储(域名接管)&&弹性计算(元数据泄露) 目录标题 云上攻防--云服务&&对象存储(域名接管)&&弹性计算(元数据泄露)对象存储权限配置错误域名接管AK/SK泄漏&#xff1a; 弹性计算元数据泄露加固措施 对象存储 各个厂商对于…

纯CSS实现马里奥效果,回忆一下童年吧

&#x1f4e2; 鸿蒙专栏&#xff1a;想学鸿蒙的&#xff0c;冲 &#x1f4e2; C语言专栏&#xff1a;想学C语言的&#xff0c;冲 &#x1f4e2; VUE专栏&#xff1a;想学VUE的&#xff0c;冲这里 &#x1f4e2; CSS专栏&#xff1a;想学CSS的&#xff0c;冲这里 &#x1f4…