当前位置:   article > 正文

【Java编程系列】查询打印出项目中mybatis的所有sql语句,全网独一份,亲自实践可用_mybatis打印sql

mybatis打印sql

1、前言

        最近有一个需求,需要梳理出系统中所用到的全部sql语句,并对sql语句进行校验处理。而我们的ORM框架用的是mybatis,所以此处需要通过mybatis的部分组件,才能得以实现。
        一开始有了思路之后,就打算百度搜索一份现成的工具类之类的代码复制用用,后来找了一阵,发现并没有实际能满足我需求的资料。就算是那个很多人传出的SqlHelper.java这个工具类,也只能根据指定路径或mapper,打印指定的sql信息,不能够打印出我所需要的所有sql语句。所以,只能自己研究之后再开发啦。。。
        因为mybatis会把所有静态或动态的sql静态资源,加载到架构的组件之中,我正是希望通过这一思路,将加载的所有sql全部查询出来即可完成需求的第一步啦。


2、查询打印mybatis加载的所有sql语句

        思路虽然有了,但是实践起来,还得找到着手点。通过mybatis的核心组件的功能,可以定位到sql的组装信息基本都在MappedStatement这个对象中,而这个对象又在另一个组件Configuration中。所以,我们顺藤摸瓜,从起始组件,一个个往后捋,基本就可以得到想要的信息啦。

2.1 获取MappedStatement对象

通过以下代码,获取加载到容器的所有MappedStatement对象的集合:

  1. Reader reader = Resources.getResourceAsReader("mybatis.xml");
  2. SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
  3. Configuration c = sqlSessionFactory.getConfiguration();
  4. List<MappedStatement>  mappedStatements = new ArrayList<>(c.getMappedStatements());

2.2 获取查询出所有sql语句并打印

        首先,需要了解一下MappedStatement这个对象的结构,才能知道从哪里获取到对应的信息。这里,我们不看源代码的类,直接简单粗暴的断点来看,里面究竟有些啥:

        从截图中,可以发现,我们要的sql语句貌似就在sqlSource这个对象的sql字段中,那我们直接取出来看看,通过以下代码:

  1. for (int i = 0; i < mappedStatements.size(); i++) {
  2.     MappedStatement r = mappedStatements.get(i);
  3.     String id = r.getId();
  4.     SqlSource sqlSource =  r.getSqlSource();
  5.     BoundSql boundSql = sqlSource.getBoundSql(id);
  6.     String sql = boundSql.getSql();
  7.     System.out.println(sql);
  8. }

        运行起来只有,发现确实可以打印出有些sql语句了。一开始是不是觉得so easy,但实际这才只是开始的一小部分。
因为开始有报错啦,报错信息如下:

  1. org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'xxxManagementController': Unsatisfied dependency expressed through field 'xxxManageService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'xxxService': Unsatisfied dependency expressed through field 'baseMapper'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xxxMapper' defined in file [xxx\Workplace\xxx-backend\xxx-xxx\target\classes\xxx\xxx\dao\xxxMapper.class]: Cannot resolve reference to bean 'xxxSqlSessionFactory' while setting bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xxxSqlSessionFactory' defined in class path resource [xxx/xxx/config/WebDBConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'setSqlSessionFactory' threw exception; nested exception is org.apache.ibatis.builder.BuilderException: Error evaluating expression 'ew != null and ew.sqlFirst != null'. Cause: org.apache.ibatis.ognl.NoSuchPropertyException: java.lang.String.sqlFirst
  2. at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:643)
  3. at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:130)
  4. at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)
  5. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1422)
  6. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
  7. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
  8. at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
  9. at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
  10. at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
  11. at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
  12. at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:879)
  13. at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)
  14. at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
  15. at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
  16. at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)
  17. at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
  18. at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
  19. at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
  20. at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215)
  21. at xxx.xxx.xxxCofApplication.main(xxxCofApplication.java:20)
  22. Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'xxxService': Unsatisfied dependency expressed through field 'baseMapper'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xxxMapper' defined in file [xxxWorkplace\xxx-backend\xxx-xxx\target\classes\xxx\xxx\dao\xxxMapper.class]: Cannot resolve reference to bean 'xxxSqlSessionFactory' while setting bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xxxSqlSessionFactory' defined in class path resource [xxx/xxx/config/WebDBConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'setSqlSessionFactory' threw exception; nested exception is org.apache.ibatis.builder.BuilderException: Error evaluating expression 'ew != null and ew.sqlFirst != null'. Cause: org.apache.ibatis.ognl.NoSuchPropertyException: java.lang.String.sqlFirst
  23. at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:643)
  24. at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:130)
  25. at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)
  26. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1422)
  27. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
  28. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
  29. at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
  30. at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
  31. at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
  32. at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
  33. at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
  34. at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1287)
  35. at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1207)
  36. at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640)
  37. ... 19 common frames omitted
  38. Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xxxMapper' defined in file [xxxWorkplace\xxx-backend\xxx-xxx\target\classes\xxx\xxx\dao\xxxMapper.class]: Cannot resolve reference to bean 'xxxSqlSessionFactory' while setting bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xxxSqlSessionFactory' defined in class path resource [xxx/xxx/config/WebDBConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'setSqlSessionFactory' threw exception; nested exception is org.apache.ibatis.builder.BuilderException: Error evaluating expression 'ew != null and ew.sqlFirst != null'. Cause: org.apache.ibatis.ognl.NoSuchPropertyException: java.lang.String.sqlFirst
  39. at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:342)
  40. at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:113)
  41. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1699)
  42. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1444)
  43. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
  44. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
  45. at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
  46. at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
  47. at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
  48. at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
  49. at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
  50. at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1287)
  51. at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1207)
  52. at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640)
  53. ... 32 common frames omitted
  54. Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xxxSqlSessionFactory' defined in class path resource [xxx/xxx/config/WebDBConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'setSqlSessionFactory' threw exception; nested exception is org.apache.ibatis.builder.BuilderException: Error evaluating expression 'ew != null and ew.sqlFirst != null'. Cause: org.apache.ibatis.ognl.NoSuchPropertyException: java.lang.String.sqlFirst
  55. at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:656)
  56. at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:636)
  57. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338)
  58. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177)
  59. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557)
  60. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
  61. at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
  62. at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
  63. at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
  64. at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
  65. at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:330)
  66. ... 45 common frames omitted
  67. Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'setSqlSessionFactory' threw exception; nested exception is org.apache.ibatis.builder.BuilderException: Error evaluating expression 'ew != null and ew.sqlFirst != null'. Cause: org.apache.ibatis.ognl.NoSuchPropertyException: java.lang.String.sqlFirst
  68. at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
  69. at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:651)
  70. ... 55 common frames omitted
  71. Caused by: org.apache.ibatis.builder.BuilderException: Error evaluating expression 'ew != null and ew.sqlFirst != null'. Cause: org.apache.ibatis.ognl.NoSuchPropertyException: java.lang.String.sqlFirst
  72. at org.apache.ibatis.scripting.xmltags.OgnlCache.getValue(OgnlCache.java:48)
  73. at org.apache.ibatis.scripting.xmltags.ExpressionEvaluator.evaluateBoolean(ExpressionEvaluator.java:32)
  74. at org.apache.ibatis.scripting.xmltags.IfSqlNode.apply(IfSqlNode.java:34)
  75. at org.apache.ibatis.scripting.xmltags.ChooseSqlNode.apply(ChooseSqlNode.java:35)
  76. at org.apache.ibatis.scripting.xmltags.MixedSqlNode.lambda$apply$0(MixedSqlNode.java:32)
  77. at java.util.ArrayList.forEach(ArrayList.java:1257)
  78. at org.apache.ibatis.scripting.xmltags.MixedSqlNode.apply(MixedSqlNode.java:32)
  79. at org.apache.ibatis.scripting.xmltags.DynamicSqlSource.getBoundSql(DynamicSqlSource.java:39)
  80. at xxx.common.config.AbstractDBConfig.printNoIdSql(AbstractDBConfig.java:248)
  81. at xxx.common.config.AbstractDBConfig.buildSqlSessionFactory(AbstractDBConfig.java:176)
  82. at xxx.xxx.config.WebDBConfiguration.setSqlSessionFactory(WebDBConfiguration.java:27)
  83. at xxx.xxx.config.WebDBConfiguration$$EnhancerBySpringCGLIB$$68a04ddd.CGLIB$setSqlSessionFactory$0(<generated>)
  84. at xxx.xxx.config.WebDBConfiguration$$EnhancerBySpringCGLIB$$68a04ddd$$FastClassBySpringCGLIB$$6a2debe.invoke(<generated>)
  85. at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
  86. at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331)
  87. at xxx.xxx.config.WebDBConfiguration$$EnhancerBySpringCGLIB$$68a04ddd.setSqlSessionFactory(<generated>)
  88. at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  89. at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  90. at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  91. at java.lang.reflect.Method.invoke(Method.java:498)
  92. at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
  93. ... 56 common frames omitted
  94. Caused by: org.apache.ibatis.ognl.NoSuchPropertyException: java.lang.String.sqlFirst
  95. at org.apache.ibatis.ognl.ObjectPropertyAccessor.getProperty(ObjectPropertyAccessor.java:164)
  96. at org.apache.ibatis.ognl.OgnlRuntime.getProperty(OgnlRuntime.java:3338)
  97. at org.apache.ibatis.ognl.ASTProperty.getValueBody(ASTProperty.java:121)
  98. at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
  99. at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)
  100. at org.apache.ibatis.ognl.ASTChain.getValueBody(ASTChain.java:141)
  101. at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
  102. at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)
  103. at org.apache.ibatis.ognl.ASTNotEq.getValueBody(ASTNotEq.java:50)
  104. at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
  105. at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)
  106. at org.apache.ibatis.ognl.ASTAnd.getValueBody(ASTAnd.java:61)
  107. at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
  108. at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)
  109. at org.apache.ibatis.ognl.Ognl.getValue(Ognl.java:560)
  110. at org.apache.ibatis.ognl.Ognl.getValue(Ognl.java:524)
  111. at org.apache.ibatis.scripting.xmltags.OgnlCache.getValue(OgnlCache.java:46)
  112. ... 76 common frames omitted

那具体报错原因呢,就是最后这句啦:

Caused by: org.apache.ibatis.ognl.NoSuchPropertyException: java.lang.String.sqlFirst

还有一句:'ew != null and ew.sqlFirst != null'

但是一开始我感到有些奇怪,明明这个sql里都没有这些关键字,咋会报错。后面才发现,这是一个mybatis-plus的基础sql语句里才带有的。。所以,一开始想着把这类语句直接过滤掉算了,但是后来才发现,这里并不是如此。

2.3 静态sql语句与动态sql语句查询与打印

        通过断点,我们会看到,其实SqlSource对象,是有分为 RawSqlSource 静态sql对象和 DynamicSqlSource 动态sql对象这2种的。而他们在处理sql语句组装时,是不一样的。前者可以直接获取到静态的sql语句,如第一个截图里的内容。但是后者,是不能通过前面的方式 boundSql.getSql() ,直接获取到sql的。我们可以看一下2种对象的内部属性情况:

 

 除了属性不通之外,最大的区别就是,动态sql的入参,在加载之后暂时是不知道的,只有在运行调用时,才会实时传入进来,然后拼接形成完整的sql语句。源码实现就是这样:

主要会有以下几种类型的sqlNode:

         这些sqlNode负责处理不同类型的sql节点语句,这里不做具体叙述,因为后面,我们会对这些sqlNode做类似源码的实践处理。

         因为获取不到入参,所以才会出现了上述的异常报错。当然,我也尝试过模拟组装一个通用的参数类,手动传入进入,放到参数对象的里,但每个sql的入参不一样,所以这个点肯定不可行啦!!

那只能从另一个方案着手啦,就是模拟mybatis动态拼接sql语句,先来看一下每一种sqlNode的结构:

虽然断点上看,能看到每个节点下有这些内容,但源码的实际类代码,其实是这样的:

并且我们无法通过get或set来处理这些类型的对象。所以,只能通过  反射  来处理啦!!!

下面,给出我个人摸索和一步步实践得出来的实践代码吧:

  1. String sql = null;
  2. if(sqlSource instanceof DynamicSqlSource){
  3. // System.out.println("【SQL】"+id);
  4. DynamicSqlSource dynamicSqlSource = (DynamicSqlSource)sqlSource;
  5. if (dynamicSqlSource == null) continue;
  6. //反射获取 TextSqlNode 对象
  7. Field sqlNodeField = dynamicSqlSource.getClass().getDeclaredField("rootSqlNode");
  8. sqlNodeField.setAccessible(true);
  9. Object nodeObj = sqlNodeField.get(dynamicSqlSource);
  10. if(nodeObj instanceof TextSqlNode){
  11. //处理TextSqlNode类型
  12. sql = dealTextSqlNode(nodeObj);
  13. }else {
  14. MixedSqlNode rootSqlNode = (MixedSqlNode) sqlNodeField.get(dynamicSqlSource);
  15. Field cont = rootSqlNode.getClass().getDeclaredField("contents");
  16. cont.setAccessible(true);
  17. List<SqlNode> nodeList = (List)cont.get(rootSqlNode);
  18. StringBuffer sf = new StringBuffer();
  19. for (SqlNode sqlNode : nodeList) {
  20. if(sqlNode instanceof StaticTextSqlNode){
  21. //处理StaticTextSqlNode类型
  22. dealStaticTextSqlNode(sqlNode,sf);
  23. }
  24. if(sqlNode instanceof ChooseSqlNode){
  25. //处理ChooseSqlNode类型
  26. dealChooseSqlNode(sqlNode,sf);
  27. }
  28. if(sqlNode instanceof IfSqlNode){
  29. //处理IfSqlNode类型
  30. dealIfSqlNode(sqlNode,sf);
  31. }
  32. }
  33. sql = sf.toString();
  34. }
  35. }
  36. //处理TextSqlNode类型
  37. private String dealTextSqlNode(Object nodeObj) throws Exception{
  38. TextSqlNode textSqlNode = (TextSqlNode) nodeObj;
  39. Field textField = textSqlNode.getClass().getDeclaredField("text");
  40. textField.setAccessible(true);
  41. return (String) textField.get(textSqlNode);
  42. }
  43. //处理StaticTextSqlNode类型
  44. private void dealStaticTextSqlNode(SqlNode sqlNode,StringBuffer sf) throws Exception{
  45. Field t = sqlNode.getClass().getDeclaredField("text");
  46. t.setAccessible(true);
  47. String sqlText = (String) t.get(sqlNode);
  48. sf.append(sqlText);
  49. }
  50. //处理ChooseSqlNode类型
  51. private void dealChooseSqlNode(SqlNode sqlNode,StringBuffer sf) throws Exception{
  52. Field defaultField = sqlNode.getClass().getDeclaredField("defaultSqlNode");
  53. defaultField.setAccessible(true);
  54. Object sqlNodeObj = defaultField.get(sqlNode);
  55. if(Objects.nonNull(sqlNodeObj)){
  56. MixedSqlNode defaultSqlNode = (MixedSqlNode)sqlNodeObj;
  57. Field contentField = defaultSqlNode.getClass().getDeclaredField("contents");
  58. contentField.setAccessible(true);
  59. List<Object> contents = (List<Object>)contentField.get(defaultSqlNode);
  60. if(CollectionUtils.isNotEmpty(contents)){
  61. StaticTextSqlNode node = (StaticTextSqlNode)contents.get(0);
  62. Field txtField = node.getClass().getDeclaredField("text");
  63. txtField.setAccessible(true);
  64. String sqlText = (String)txtField.get(node);
  65. sf.append(sqlText);
  66. }
  67. }
  68. Field ifNodeField = null;
  69. try {
  70. ifNodeField = sqlNode.getClass().getDeclaredField("ifSqlNodes");
  71. } catch (Exception e) {
  72. e.printStackTrace();
  73. return;
  74. }
  75. ifNodeField.setAccessible(true);
  76. List<IfSqlNode> sqlNodeList =(List<IfSqlNode>) ifNodeField.get(sqlNode);
  77. if(!sqlNodeList.isEmpty()){
  78. sqlNodeList.stream().forEach(s->{
  79. try {
  80. dealIfSqlNode(s,sf);
  81. } catch (Exception e) {
  82. e.printStackTrace();
  83. }
  84. });
  85. }
  86. }
  87. //处理IfSqlNode类型
  88. private void dealIfSqlNode(SqlNode sqlNode,StringBuffer sf) throws Exception{
  89. Field nodeField = sqlNode.getClass().getDeclaredField("contents");
  90. nodeField.setAccessible(true);
  91. MixedSqlNode mixedSqlNode = (MixedSqlNode)nodeField.get(sqlNode);
  92. Field contentField = mixedSqlNode.getClass().getDeclaredField("contents");
  93. contentField.setAccessible(true);
  94. List<Object> contents = (List<Object>)contentField.get(mixedSqlNode);
  95. if(CollectionUtils.isNotEmpty(contents)){
  96. contents.stream().forEach(content->{
  97. if(content instanceof StaticTextSqlNode){
  98. StaticTextSqlNode node = (StaticTextSqlNode)content;
  99. Field txtField = null;
  100. try {
  101. txtField = node.getClass().getDeclaredField("text");
  102. txtField.setAccessible(true);
  103. String sqlText = (String)txtField.get(node);
  104. sf.append(sqlText);
  105. } catch (Exception e) {
  106. e.printStackTrace();
  107. }
  108. }
  109. });
  110. }
  111. }

最后,让我们看一下实现后的具体效果吧:

原xml里的sql语句:

 查询打印出来后的sql语句:

 虽然参数没有实际处理,但已经拿到我所想要的静态sql完整文本内容啦。是不是很酷,哈哈~~


3、总结

        以上就是本次主题的全部内容啦,希望可以帮助到感兴趣和有需求的同学们。

如果有什么大家认为不合理的地方,也欢迎大家在下方留言讨论,我会第一时间回复大家的!!!

备注:纯原创文章,禁止转载或盗链,原创不易,请大家多多支持,喜欢就一键三连吧!!

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/932373
推荐阅读
相关标签
  

闽ICP备14008679号