Mybatis动态SQL与连接池优化实践指南

创始人
2024-12-29 10:52:02
0 次浏览
0 评论

Mybatis连接池_动态sql语句_多表查询实现

Mybatis在处理多表查询时,主要使用动态SQL语句和连接池技术来提高查询效率。
在Mybatis中,动态SQL语句使用“if”、“where”、“foreach”等标签来实现条件的灵活匹配。
实现多表查询,首先定义实体类,然后编写SQL语句,定义持久层DAO接口,以及配置文件。
方法一创建`AccountUser`类和`AccountDao.xml`文件来查询账户信息。
第二种方法通过更改`Account`类和`AccountDao`接口重新定义查询逻辑。
对于一对一查询(多对一),在`AccountDao`接口中添加相应的查询方法,并配置`AccountDao.xml`文件来查询账户和用户的关系。
对于一对多查询,接口中也定义了查询方法,并在配置文件中完成相关配置。
在实现多对多查询时,首先明确自己的业务需求,然后编写相应的SQL语句。
例如,在`Role`的持久层接口中添加一个查询方法,并在配置文件中定义查询逻辑,最终实现。
角色和用户之间的多对多查询。

动态sql写法

动态SQL在编程中发挥着重要作用,尤其是在处理复杂查询和动态状态过滤时。
它允许在程序执行过程中根据条件动态生成SQL语句,提高代码的灵活性和可维护性。
下面,我们将探讨一些编写动态SQL的常见方法,目的是帮助开发人员更高效地编写SQL查询。
处理动态SQL时,基本概念是使用参数化查询。
通过将数据作为参数传递给SQL语句,而不是直接将其包含在SQL字符串中,可以避免SQL注入攻击,同时提高代码的可读性和可维护性。
例如,使用准备好的SQL语句(例如准备好的MySQL语句),我们可以编写动态生成的SELECT语句来查询数据库。
假设我们有一个包含多个要在查询中使用的字段名的数组,我们可以编写以下代码:sqlDECLARE@fieldsNVARCHAR(MAX)='';DECLARE@sqlNVARCHAR(MAX)='SELECT'+@fields+'FROMtable_name';虽然@fieldsLIKE'%,%'BEGINSET@fields=REPLACE(@fields,',',',',1);ENDSET@sql=CONCAT(@sql,'',@fields);EXECsp_executesql@sql;在上面的例子中,我们使用Loop将字段名称集合转换为逗号分隔的字符串并将其插入SQL查询中。
最后,使用sp_executesql存储过程执行动态生成的SQL语句。
编写动态SQL的另一种方法是使用预定义的SQL模板并替换动态参数。
例如,在.NETFramework中,您可以使用“StringBuilder”类动态构建SQL语句并使用“SqlBulkCopy”或“SqlConnection”来执行查询。
这种方式也避免了SQL注入的风险,提高了代码的安全性和可读性。
简而言之,动态SQL为开发人员提供了一种灵活、安全的方式来创建SQL查询,特别是在处理动态数据和复杂查询条件时。
使用参数化查询、预准备语句和动态SQL模板,开发人员可以编写安全高效的SQL代码,从而增强应用程序的性能和稳定性。

MybatisPlus是如何实现动态SQL语句的?原理你懂吗?

Mybatis-Plus(简称MP)是Mybatis的增强工具;那么如何推广呢?实际上,它涵盖了一些原始方法,因此您无需编写xml进行开发;直接调用这些方法,就像在JPA中一样。

在这篇文章中,下面我们来阅读MP的具体实现,看看这些增强功能是如何实现的。

入口类:MybatisSqlSessionFactoryBuilder

入口类中MybatisSqlSessionFactoryBuilder#build方法通过在应用启动时自定义动态配置xml文件注入到Mybatis中。

publicclassMybatisSqlSessionFactoryBuilderextendsSqlSessionFactoryBuilder{publicSqlSessionFactorybuild(Configurationconfiguration){//...if(globalConfig.isEnableSqlRun省略许多行ner()){newSqlRunnerInjector().inject(configuration);}//...省略一些行returnsqlSessionFactory;}}

包含2个来自Mybatis的MP2功能类

extendsMybatisConfiguration类继承:MP动态脚本构建;注册等逻辑判断。

SqlRunnerInjector:MP默认注入动态方法的一些xml脚本方法。

MybatisConfiguration类

这里重点分析MybatisConfiguration类,在MybatisConfiguration中MP初始化了自己的MybatisMapperRegistry,MybatisMapperRegistry是MP加载自定义SQL方法的注册表。

MybatisConfiguration中的很多方法都是使用MybatisMapperRegistry重写实现的

AddMapper重载,实现注册MP动态脚本的功能有以下三种方法。

publicclassMybatisConfigurationextendsConfiguration{/***Mapper注册表*/protectedfinalMybatisMapperRegistrymybatisMapperRegistry=newMybatisMapperRegistry(this);//..../***初始化调用*/publicMybatisConfiguration(){super();this.mapUnderscoreToCamelCase=true;languageRegistry.setDefaultDriverClass(MybatisXMMLanguageDriver.class);}/***加载MybatisPlusSQL程序:*

1SQL转XML加载

*

2加载SQL到SqlProvider

*

3、XmlSql和SqlProvider不能包含相同的SQL

*

调整的SQL优先级:gistry*/@OverridepublicvoidaddMapper(Classtype){mybatisMapperRegistry.addMapper(type);}//....省略一些行

MybatisMapperRegistryMP用MP自己的MybatisMapperAnnotationBuilder覆盖mybatis的MapperAnnotationBuilder

publicclassMybatisMapperRegistryextendsMapperRegistry{@OverridepublicvoidaddMapper(Classtype){//...省略一些行MybatisMapperAnnotationBuilderparser=newMybatisMapperAnnotationBuilder(config,type);parse();//...一些字符串省略}}

在MybatisMapperRegistry类的addMapper方法中;我们实际上是MP的主类MybatisMapperAnnotationBuilderMybatisMapperAnnotationBuilder类是MP实现动态脚本的主类。

MybatisMapperAnnotationBuilder动态构建

在MP的主类MybatisMapperAnnotationBuilder的分析方法中,MP会遍历Mapper类来一一加载//...(Methodmethod:type.getMethods()){/**For循环码;MP判断方法是否有@Select@Insert等mybatis注解方法**/parseStatement(method);InterceptorIgnoreHelper。
initSqlParserInfoCache(cache,mapperName,method);SqlParserHelper.initSqlParserInfoCache(mapperName,method);}/**这2行代码注入MP默认方法列表**/if(GlobalConfigUtils.isSupperMapperChildren(configuration,type)){GlobalConfigUtils.getSqlInjector(配置),检查器,);}//...跳过一些行}@OverridepublicvoidinspectInject(MapperBuilderAssistantbuilderAssistant,Class<?>mapperClass){Class<?>modelClass=extractModelClass(mapperClass);//...跳过一些行ListmethodList=this.getInfoMethodList(TableInfoClass);bleInfoHelper.initTableInfo(builderAssistant,modelClass);//循环注入自定义methodList.forEach(m->m.inject(builderAssistant,mapperClass,modelClass,tableInfo));mapperRegistryCache.add(classNamefractor);}}qds类型SqlInjector{@OverridepublicListgetMethodList(Class<?>mapperClass){returnStream.of(newInsert(),//...跳过一些行newSelectPage()).collect(toList());}}

在MybatisMapperAnnotationBuilder中;MP实际上是将框架自定义的动态SQL语句注册到Mybatis引擎中。
AbstractMethod实现了特定方法的SQL语句结构。

具体的AbstractMethod实例类,构造单独的方法SQL语句

以SelectById类为例

/***ID*/publicclassSelectByIdextendsAbstractMethod{@OverridepublicMappedStatementinjectMappedStatement(ID*/publicclassSelectByIdextendsAbstractMappedStatement(outline)>mapperClass,Class<?>mOdelclass,tabledfotableinfo){/**id="xyz">**/sqlmethodsqlmethod=与sqlmethod.edelections_id=sqlmethod.by_id=sqlmetsourceqlsource=NewRawsqlsource(Configuration,String.format(sqlMethod.getSql(),sqlSelectColumns(tableInfo,false),tableInfo.getTableName(),tableInfo.getKeyColumn(),tableInfo.getKeyProperty()相关的MyBatisxmethodlmethodid相关)));,tableInfo.getLogicDeleteSql(true,true)),Object.class);/**将xml方法转换为mybatisMa额外。
pedStatement**/returnthis.addSelectMappedStatementForTable(mapperClass,getMethod(sqlMethod),sqlSource,tableInfo);}}

至此MP就完成了启动时加载自定义方法xml配置的过程.}#是{variable}的动态替换和预编译。

总结一下

MP重写并替换了十多个mybatis类型,主要如下图所示:

一般来说,MP的mybatis增强方法有点困难,不够直观。
ybatisMapperAnnotationBuilder构建自定义方法的xml文件并将其转换为mybatis的源代码,因此您只有一个Mybatis类。
继承和覆盖:例如SqlSessionFactoryBean如下。
licclassYourSqlSessionFactoryBeanextendsSqlSessionFactoryBeanimplementsApplicationContextAware{privateResource[]mapperLocations;@OverridepublicvoidsetMapperLocations(Resource...mapperLocations){super.setMapperLocations(/**Locations)临时存储来自mybatis的默认mapperxml文件路径。
**/this.mapperLocations=mapperLocations;}/***{@inheritDoc}*/@OverridepublicvoidafterPropertiesSet()throwsException{ConfigurableListableBeanFactorybeanFactory=the/The*BeanFactory(selfBeanFactory=get**pass)指定的方法被构造为xmlresource并原生定义。
可以将资源一起注入到mybatis中;从而实现MP自定义动态SQL与原生SQL的共生关系**/this.setMapperLocations(InjectMapper.getMapperResource(this.db)Type,beanFactory,this.mapperLocations));super.afterPropertiesSet();}}

在这篇文章中,我们简单介绍了MP实现动态语句的实现过程并给出了一种可能性。
更方便的方式。

来源:juejin.cn/post/6883081187103866894

Mybatis动态sql语句if标签和where标签结合巧妙使用

Mybatis允许你巧妙地结合动态SQL的if和where标签来实现灵活的查询条件。
假设您需要根据电话号码和姓名搜索用户数据。
第一个SQL查询如下所示:SELECT*FROMusersWHEREmobileLIKE'%{mobile}'ANDgender=#{gender}Mapper.xml文件中配置的动态SQL为:SELECT*FROMusersANDgender=#{gender}--如果没有传递性别,则添加此条件<。
/otherwise>
ANDmobileLIKE#{mobile}</select>代码块2-2中改进了性别条件,使用if标签判断性别是否为0或现在仅当它为1时才执行查询。
这是代码:ANDgender=#{genderer}如果要查询所有用户信息,不指定性别和用户名,请将代码块2-3改为if即可去掉标签:<!--去掉if标签-->ANDmobileLIKE#{mobile},通过组合if标签可以根据接收到的参数灵活动态调整SQL查询条件。
这在处理各种场景中的用户查询时特别有用。
热门文章
1
Python代码实现:如何判断三角形的三... python三角形三条边长,判断能否构成三角形Python三角形的三个长边如下:...

2
高效掌握:CMD命令轻松启动、关闭及登录... 如何用cmd命令快速启动和关闭mysql数据库服务开发中经常使用MySQL数据库...

3
SQL字段默认值设置全攻略:轻松实现自动... sql如何设置字段默认值设置SQL中某个字段的默认值;需要遵循几个步骤。首先您需...

4
MySQL查询加速秘籍:PolarDB ... mysql中in大量数据导致查询速度慢怎么优化?在MySQL中处理大量数据时,查...

5
SQL2000数据库备份压缩技巧:优化空... 怎么将SQL2000中的较大的备份数据库压缩变小更改数据库属性-选项-恢复模型很...

6
SQL字符串处理技巧:单引号使用与转义标... SQL语句中,字符串类型的值均使用什么符号标明?单引号如果字符串内有单引号,请小...

7
Windows环境下Redis安装指南与... redis安装windowsredis基本简介与安装安装Redis首先需要获取安...

8
深度解析:Redis性能优势与局限性,助... redis有哪些优缺点?Redis的全称是RemoteDictionary.Se...

9
深入解析:MySQL数据库的特性与应用 mysql是什么MySQL是一个关系数据库管理系统。MySQL是一个开源关系数据...

10
MySQL自增主键重置攻略:解决用尽问题... MySQL让有数据的表主键从1开始连续自增当您需要MySQL中的数据表使用连续数...