赞
踩
最近有一个需求,需要梳理出系统中所用到的全部sql语句,并对sql语句进行校验处理。而我们的ORM框架用的是mybatis,所以此处需要通过mybatis的部分组件,才能得以实现。
一开始有了思路之后,就打算百度搜索一份现成的工具类之类的代码复制用用,后来找了一阵,发现并没有实际能满足我需求的资料。就算是那个很多人传出的SqlHelper.java这个工具类,也只能根据指定路径或mapper,打印指定的sql信息,不能够打印出我所需要的所有sql语句。所以,只能自己研究之后再开发啦。。。
因为mybatis会把所有静态或动态的sql静态资源,加载到架构的组件之中,我正是希望通过这一思路,将加载的所有sql全部查询出来即可完成需求的第一步啦。
思路虽然有了,但是实践起来,还得找到着手点。通过mybatis的核心组件的功能,可以定位到sql的组装信息基本都在MappedStatement这个对象中,而这个对象又在另一个组件Configuration中。所以,我们顺藤摸瓜,从起始组件,一个个往后捋,基本就可以得到想要的信息啦。
通过以下代码,获取加载到容器的所有MappedStatement对象的集合:
- Reader reader = Resources.getResourceAsReader("mybatis.xml");
- SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
- Configuration c = sqlSessionFactory.getConfiguration();
- List<MappedStatement> mappedStatements = new ArrayList<>(c.getMappedStatements());
首先,需要了解一下MappedStatement这个对象的结构,才能知道从哪里获取到对应的信息。这里,我们不看源代码的类,直接简单粗暴的断点来看,里面究竟有些啥:
从截图中,可以发现,我们要的sql语句貌似就在sqlSource这个对象的sql字段中,那我们直接取出来看看,通过以下代码:
- for (int i = 0; i < mappedStatements.size(); i++) {
- MappedStatement r = mappedStatements.get(i);
- String id = r.getId();
- SqlSource sqlSource = r.getSqlSource();
- BoundSql boundSql = sqlSource.getBoundSql(id);
- String sql = boundSql.getSql();
- System.out.println(sql);
- }
运行起来只有,发现确实可以打印出有些sql语句了。一开始是不是觉得so easy,但实际这才只是开始的一小部分。
因为开始有报错啦,报错信息如下:
- 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
- at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:643)
- at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:130)
- at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)
- at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1422)
- at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
- at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
- at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
- at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
- at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
- at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
- at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:879)
- at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)
- at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
- at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
- at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)
- at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
- at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
- at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
- at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215)
- at xxx.xxx.xxxCofApplication.main(xxxCofApplication.java:20)
- 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
- at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:643)
- at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:130)
- at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)
- at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1422)
- at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
- at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
- at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
- at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
- at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
- at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
- at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
- at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1287)
- at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1207)
- at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640)
- ... 19 common frames omitted
- 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
- at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:342)
- at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:113)
- at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1699)
- at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1444)
- at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
- at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
- at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
- at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
- at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
- at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
- at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
- at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1287)
- at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1207)
- at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640)
- ... 32 common frames omitted
- 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
- at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:656)
- at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:636)
- at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338)
- at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177)
- at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557)
- at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
- at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
- at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
- at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
- at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
- at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:330)
- ... 45 common frames omitted
- 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
- at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
- at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:651)
- ... 55 common frames omitted
- 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
- at org.apache.ibatis.scripting.xmltags.OgnlCache.getValue(OgnlCache.java:48)
- at org.apache.ibatis.scripting.xmltags.ExpressionEvaluator.evaluateBoolean(ExpressionEvaluator.java:32)
- at org.apache.ibatis.scripting.xmltags.IfSqlNode.apply(IfSqlNode.java:34)
- at org.apache.ibatis.scripting.xmltags.ChooseSqlNode.apply(ChooseSqlNode.java:35)
- at org.apache.ibatis.scripting.xmltags.MixedSqlNode.lambda$apply$0(MixedSqlNode.java:32)
- at java.util.ArrayList.forEach(ArrayList.java:1257)
- at org.apache.ibatis.scripting.xmltags.MixedSqlNode.apply(MixedSqlNode.java:32)
- at org.apache.ibatis.scripting.xmltags.DynamicSqlSource.getBoundSql(DynamicSqlSource.java:39)
- at xxx.common.config.AbstractDBConfig.printNoIdSql(AbstractDBConfig.java:248)
- at xxx.common.config.AbstractDBConfig.buildSqlSessionFactory(AbstractDBConfig.java:176)
- at xxx.xxx.config.WebDBConfiguration.setSqlSessionFactory(WebDBConfiguration.java:27)
- at xxx.xxx.config.WebDBConfiguration$$EnhancerBySpringCGLIB$$68a04ddd.CGLIB$setSqlSessionFactory$0(<generated>)
- at xxx.xxx.config.WebDBConfiguration$$EnhancerBySpringCGLIB$$68a04ddd$$FastClassBySpringCGLIB$$6a2debe.invoke(<generated>)
- at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
- at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331)
- at xxx.xxx.config.WebDBConfiguration$$EnhancerBySpringCGLIB$$68a04ddd.setSqlSessionFactory(<generated>)
- at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
- at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
- at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
- at java.lang.reflect.Method.invoke(Method.java:498)
- at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
- ... 56 common frames omitted
- Caused by: org.apache.ibatis.ognl.NoSuchPropertyException: java.lang.String.sqlFirst
- at org.apache.ibatis.ognl.ObjectPropertyAccessor.getProperty(ObjectPropertyAccessor.java:164)
- at org.apache.ibatis.ognl.OgnlRuntime.getProperty(OgnlRuntime.java:3338)
- at org.apache.ibatis.ognl.ASTProperty.getValueBody(ASTProperty.java:121)
- at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
- at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)
- at org.apache.ibatis.ognl.ASTChain.getValueBody(ASTChain.java:141)
- at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
- at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)
- at org.apache.ibatis.ognl.ASTNotEq.getValueBody(ASTNotEq.java:50)
- at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
- at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)
- at org.apache.ibatis.ognl.ASTAnd.getValueBody(ASTAnd.java:61)
- at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
- at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)
- at org.apache.ibatis.ognl.Ognl.getValue(Ognl.java:560)
- at org.apache.ibatis.ognl.Ognl.getValue(Ognl.java:524)
- at org.apache.ibatis.scripting.xmltags.OgnlCache.getValue(OgnlCache.java:46)
- ... 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语句里才带有的。。所以,一开始想着把这类语句直接过滤掉算了,但是后来才发现,这里并不是如此。
通过断点,我们会看到,其实SqlSource对象,是有分为 RawSqlSource 静态sql对象和 DynamicSqlSource 动态sql对象这2种的。而他们在处理sql语句组装时,是不一样的。前者可以直接获取到静态的sql语句,如第一个截图里的内容。但是后者,是不能通过前面的方式 boundSql.getSql() ,直接获取到sql的。我们可以看一下2种对象的内部属性情况:
除了属性不通之外,最大的区别就是,动态sql的入参,在加载之后暂时是不知道的,只有在运行调用时,才会实时传入进来,然后拼接形成完整的sql语句。源码实现就是这样:
主要会有以下几种类型的sqlNode:
这些sqlNode负责处理不同类型的sql节点语句,这里不做具体叙述,因为后面,我们会对这些sqlNode做类似源码的实践处理。
因为获取不到入参,所以才会出现了上述的异常报错。当然,我也尝试过模拟组装一个通用的参数类,手动传入进入,放到参数对象的里,但每个sql的入参不一样,所以这个点肯定不可行啦!!
那只能从另一个方案着手啦,就是模拟mybatis动态拼接sql语句,先来看一下每一种sqlNode的结构:
虽然断点上看,能看到每个节点下有这些内容,但源码的实际类代码,其实是这样的:
并且我们无法通过get或set来处理这些类型的对象。所以,只能通过 反射 来处理啦!!!
下面,给出我个人摸索和一步步实践得出来的实践代码吧:
- String sql = null;
- if(sqlSource instanceof DynamicSqlSource){
- // System.out.println("【SQL】"+id);
- DynamicSqlSource dynamicSqlSource = (DynamicSqlSource)sqlSource;
- if (dynamicSqlSource == null) continue;
-
- //反射获取 TextSqlNode 对象
- Field sqlNodeField = dynamicSqlSource.getClass().getDeclaredField("rootSqlNode");
-
- sqlNodeField.setAccessible(true);
- Object nodeObj = sqlNodeField.get(dynamicSqlSource);
- if(nodeObj instanceof TextSqlNode){
- //处理TextSqlNode类型
- sql = dealTextSqlNode(nodeObj);
- }else {
-
- MixedSqlNode rootSqlNode = (MixedSqlNode) sqlNodeField.get(dynamicSqlSource);
- Field cont = rootSqlNode.getClass().getDeclaredField("contents");
- cont.setAccessible(true);
- List<SqlNode> nodeList = (List)cont.get(rootSqlNode);
-
- StringBuffer sf = new StringBuffer();
- for (SqlNode sqlNode : nodeList) {
- if(sqlNode instanceof StaticTextSqlNode){
- //处理StaticTextSqlNode类型
- dealStaticTextSqlNode(sqlNode,sf);
- }
-
- if(sqlNode instanceof ChooseSqlNode){
- //处理ChooseSqlNode类型
- dealChooseSqlNode(sqlNode,sf);
-
- }
-
- if(sqlNode instanceof IfSqlNode){
- //处理IfSqlNode类型
- dealIfSqlNode(sqlNode,sf);
- }
-
- }
-
- sql = sf.toString();
- }
- }
-
-
- //处理TextSqlNode类型
- private String dealTextSqlNode(Object nodeObj) throws Exception{
- TextSqlNode textSqlNode = (TextSqlNode) nodeObj;
- Field textField = textSqlNode.getClass().getDeclaredField("text");
- textField.setAccessible(true);
- return (String) textField.get(textSqlNode);
- }
-
- //处理StaticTextSqlNode类型
- private void dealStaticTextSqlNode(SqlNode sqlNode,StringBuffer sf) throws Exception{
- Field t = sqlNode.getClass().getDeclaredField("text");
- t.setAccessible(true);
- String sqlText = (String) t.get(sqlNode);
- sf.append(sqlText);
- }
-
- //处理ChooseSqlNode类型
- private void dealChooseSqlNode(SqlNode sqlNode,StringBuffer sf) throws Exception{
- Field defaultField = sqlNode.getClass().getDeclaredField("defaultSqlNode");
- defaultField.setAccessible(true);
- Object sqlNodeObj = defaultField.get(sqlNode);
- if(Objects.nonNull(sqlNodeObj)){
- MixedSqlNode defaultSqlNode = (MixedSqlNode)sqlNodeObj;
- Field contentField = defaultSqlNode.getClass().getDeclaredField("contents");
- contentField.setAccessible(true);
- List<Object> contents = (List<Object>)contentField.get(defaultSqlNode);
- if(CollectionUtils.isNotEmpty(contents)){
- StaticTextSqlNode node = (StaticTextSqlNode)contents.get(0);
- Field txtField = node.getClass().getDeclaredField("text");
- txtField.setAccessible(true);
- String sqlText = (String)txtField.get(node);
- sf.append(sqlText);
- }
- }
-
-
- Field ifNodeField = null;
- try {
- ifNodeField = sqlNode.getClass().getDeclaredField("ifSqlNodes");
- } catch (Exception e) {
- e.printStackTrace();
- return;
- }
- ifNodeField.setAccessible(true);
- List<IfSqlNode> sqlNodeList =(List<IfSqlNode>) ifNodeField.get(sqlNode);
- if(!sqlNodeList.isEmpty()){
- sqlNodeList.stream().forEach(s->{
- try {
- dealIfSqlNode(s,sf);
- } catch (Exception e) {
- e.printStackTrace();
- }
- });
- }
- }
-
- //处理IfSqlNode类型
- private void dealIfSqlNode(SqlNode sqlNode,StringBuffer sf) throws Exception{
- Field nodeField = sqlNode.getClass().getDeclaredField("contents");
- nodeField.setAccessible(true);
- MixedSqlNode mixedSqlNode = (MixedSqlNode)nodeField.get(sqlNode);
- Field contentField = mixedSqlNode.getClass().getDeclaredField("contents");
- contentField.setAccessible(true);
- List<Object> contents = (List<Object>)contentField.get(mixedSqlNode);
- if(CollectionUtils.isNotEmpty(contents)){
- contents.stream().forEach(content->{
- if(content instanceof StaticTextSqlNode){
- StaticTextSqlNode node = (StaticTextSqlNode)content;
- Field txtField = null;
- try {
- txtField = node.getClass().getDeclaredField("text");
- txtField.setAccessible(true);
- String sqlText = (String)txtField.get(node);
- sf.append(sqlText);
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- }
- });
- }
- }
-
-
最后,让我们看一下实现后的具体效果吧:
原xml里的sql语句:
查询打印出来后的sql语句:
虽然参数没有实际处理,但已经拿到我所想要的静态sql完整文本内容啦。是不是很酷,哈哈~~
以上就是本次主题的全部内容啦,希望可以帮助到感兴趣和有需求的同学们。
如果有什么大家认为不合理的地方,也欢迎大家在下方留言讨论,我会第一时间回复大家的!!!
备注:纯原创文章,禁止转载或盗链,原创不易,请大家多多支持,喜欢就一键三连吧!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。