生成的Model里带有dao(),后Model通过use使用多数据库配置报错!

@JFinal

通过生成器生成的Model里这么写的:

1.png

然后查询这么写,就报错:

2副本.png

把生成的Model里的写法写成这个样:

3.png

就正常了。请问是什么问题啊

评论区

JFinal

2019-05-19 12:03

注意观察 TaskNote dao 这个变量,前方是有 static 修饰的,意味着这个变量是全局共享的,所有线程都可以用它

那么,这个 dao 对象就 “不是” 线程安全的,所以在 new TaskNote() 的时候,后面追加一个 dao() 方法,可以让这个对象变成线程安全的,可以全局共享

但是变成线程安全就必须限制对 dao 对象的写操作,否则就不会线程安全

综上,你去掉了 dao() 方法,必然导致极多的问题,如果你一定要使用 use 方法,这么来用才可保证线程安全:
new TaskNote().use(...).find(...)

也就是说临时 new 出来对象,再 use(...)

zzutligang

2019-05-19 16:54

@JFinal
感谢回复,也就是说,Mode要想实现通过use切换不同的数据源,只能自己New一个Model实例然后调用use方法才可以是吧。不能通过在Model里用static创建一个dao对象来实现是吧。我看Model源码里,dao方法里这么写
public M dao() {
attrs = DaoContainerFactory.daoMap;
modifyFlag = DaoContainerFactory.daoSet;
return (M)this;
}
而use方法里又这么写:
public M use(String configName) {
if (attrs == DaoContainerFactory.daoMap) {
throw new RuntimeException("dao 只允许调用查询方法");
}

this.configName = configName;
return (M)this;
}
另外,如果Model那个静态dao对象不调用dao方法,只是用来查询,是不是会在并发量大的时候,导致甲查询的数据被返回给了乙呢?或则可能存在最大风险是什么?
只能这么回避吗?Db为什么可以通过use就可以线程安全了呢?波总有没有打算这里改进一下?

JFinal

2019-05-19 17:11

@zzutligang 这个问题是 java 有关线程安全的基础问题,大致就是:只要对象可能被多线程使用,这个对象就必须保障是线程安全的

zzutligang

2019-05-21 13:48

@JFinal,感谢波总。目前暂时只能通过new一个Model实例的形式再调用use方法实现多数据源了。虽然看起来没有之前的那种静态dao方法看起来那么优雅。不过还是期望波总能在这个地方在下个版本里给个更好的解决方案。再次感谢!

JFinal

2019-05-21 14:39

@zzutligang 如果每个数据源都有自己的 table 以及 model,那么映射的时候各自都是对应上的,多数据源是自动化完成的,无需自己调用 model.use(...) 方法

这个才是标准的用法

zzutligang

2019-05-22 01:02

@Jfinal 第一种场景是多个数据库连接都有几个相同的表名。第二种场景是一个系统有多个单位使用,每个单位创建一个自己的数据库。根据单位ID提前建立好数据库连接,但程序就只有一套。这两种场景都无法避免使用use这种方法。做规模稍微大点的系统,这两种场景基本上很难回避过去。

热门反馈

扫码入社