创建 DbSourse 遇到的问题


public class DbSource implements ISource{
	private StringBuilder sqlBuilder=null;
	public DbSource(Record api) {
		String id=api.get("id")+"";
		String sqlstr=api.getStr("sqlstr");
		sqlBuilder=new StringBuilder();
		sqlBuilder.append("#sql(\"api_"+id+"\")");
		sqlBuilder.append(" \n");
		sqlBuilder.append(sqlstr);
		sqlBuilder.append(" \n");
		sqlBuilder.append("#end");
		System.out.println(sqlBuilder);
	}
	
	@Override
	public boolean isModified() {
		System.out.println("isModified");
		return false;
	}

	@Override
	public String getKey() {
		System.out.println("getKey");
		return null;
	}

	@Override
	public StringBuilder getContent() {
		System.out.println("getContent");
		if(sqlBuilder==null){
			throw new RuntimeException("Sql not found !");
		}
		return sqlBuilder;
	}

	@Override
	public String getEncoding() {
		System.out.println("getEncoding");
		return EngineConfig.DEFAULT_ENCODING;
	}

image.png

因为 我的api里面保存的只是一个sql语句,每次都需要addSqlTemplate,但是不知道为什么,只有第一次add 的sql 可以使用,后面再add就报错了,如下:

com.jfinal.plugin.activerecord.ActiveRecordException: java.sql.SQLException: sql is null
	at com.jfinal.plugin.activerecord.DbPro.find(DbPro.java:345)
	at com.jfinal.plugin.activerecord.DbPro.find(DbPro.java:356)
	at com.service.impl.IndexServiceImpl.getDataByApiAndParams(IndexServiceImpl.java:63)
	at com.controller.SqlController.getSelList(SqlController.java:41)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at com.jfinal.aop.Invocation.invoke(Invocation.java:73)
	at com.jfinal.core.ActionHandler.handle(ActionHandler.java:91)
	at com.jfinal.ext.handler.ContextPathHandler.handle(ContextPathHandler.java:48)
	at com.jfinal.core.JFinalFilter.doFilter(JFinalFilter.java:73)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at com.thetransactioncompany.cors.CORSFilter.doFilter(CORSFilter.java:209)
	at com.thetransactioncompany.cors.CORSFilter.doFilter(CORSFilter.java:244)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:442)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1082)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:623)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:722)
Caused by: java.sql.SQLException: sql is null
	at com.alibaba.druid.pool.DruidPooledPreparedStatement$PreparedStatementKey.<init>(DruidPooledPreparedStatement.java:955)
	at com.alibaba.druid.pool.DruidPooledPreparedStatement$PreparedStatementKey.<init>(DruidPooledPreparedStatement.java:923)
	at com.alibaba.druid.pool.DruidPooledConnection.prepareStatement(DruidPooledConnection.java:336)
	at com.jfinal.plugin.activerecord.DbPro.find(DbPro.java:328)
	at com.jfinal.plugin.activerecord.DbPro.find(DbPro.java:343)
	... 32 more

不能添加多个吗。求解

评论区

188085240

2018-02-07 14:34

不是呀,我写的报错是sql not found 报的是java.sql.SQLException: sql is null

188085240

2018-02-07 14:40

问题是
#sql("api_sql_1517985390850")
select * from T_CD_JUECEFUWU
#end
我第一次addSqlTemplate( new DbSourse(sqlStr) ) 这样的sql信息 缓存下来了,可以查询,第二次再addSqlTemplate( new DbSourse(sqlStr) )就不行了

JFinal

2018-02-07 14:42

@188085240 刚看错了,你在构造方法中初始化了 sqlBuilder,所以前面那个异常不会抛出来

代码看上去是没问题的,从异常上看是你在使用 DbPro.find(sql) 这个方法的 sql 为 null ,单步调试秒秒钟解决问题,不要靠猜

这个问题与是否添加多个 addSqlTemplate 没有关系,添加多个才是正常的姿势

JFinal

2018-02-07 14:43

@188085240 异常已经很清楚,不是在 addSqlTemplate 的时候出异常,而是在使用 find(sql) 方法时出现 sql 为 null,这种问题通过单步调试极度容易解决

188085240

2018-02-07 14:49

System.out.println("api_"+id);
String sqlStr = Db.use("oracle_" + d_id).getSql("api_"+id);
System.out.println(sqlStr);
list = Db.use("oracle_" + d_id).find(sqlStr);
输出:

#sql("api_sql_1517985849549")
select * from T_CD_JUECEFUWU
#end

api_sql_1517985849549
null
说明这个key 根本没有获取到sql ,但是我的DbSourse,也添加了,所以我就想的是add哪里的问题

JFinal

2018-02-07 15:03

@188085240 获取 sql 之前切换了数据源,表明你是多数据源情况

所以在 addSqlTemplate 也要相应的使用对应的数据源:
arp1.addSqlTemplate(...);
arp2.addSqlTemplate(...);
arp3.addSqlTemplate(...);

上面的 arp1 arp2 arp3 分别对应了各自的数据源: ds1 ds2 ds3,在使用的时候:
Db.use("ds1").getSql(key) 即可

JFinal

2018-02-07 15:06

这种设计方式,可以让不同的数据源,使用相同的 sql key 值,互相之间不干扰,所以,你的 "api_" + key 的方式或许不再需要,使用同名的 key 值,只需要切换数据源就要以取到对应数据源的 sql:
Db.use(ds1).getSql(同名key);
Db.use(ds2).getSqlPara(同名key);

热门反馈

扫码入社