2016-10-30 00:18

@lyh061619 在业务层创建 dao 是可以的,但仍然不要去调用它的 dao.put/save/update/set 之类的方法,这个对象是共享的,不是线程安全的, java 这门语言是多线程语言,必须要考虑对象在多线程共享情况下的线程安全问题,这是极其重要的java基础知识,必须要对java 线程极其熟悉才能写出健壮的程序

2016-10-29 22:41

除非你将 static final LogService me 这一行代码去掉,那么 dao 则不是共享的,此外,还要保障在外部没有类似 static LogService 的定义, static 是有传递性的,这是 java 基础,建议多了解一下

2016-10-29 22:39

@lyh061619 去掉 final 没有意义,虽然这里不是 static 的,但是如果多线程使用的是同一个 LogService 对象,那么与使用 static 在本质上是一样的错误,总之这里的 dao 是共享变量,不能用于 set、put、save、update 等一切写数据的操作,只能使用 find 系列的方法

2016-10-29 17:37

@johnhan sql 可以采用外部配置文件管理起来,不一定要写在代码中,为此 jfinal 提供了 com.jfinal.plugin.activerecord.Sqls.java 这个工具类来管理

此外 jfinal 2.3 会提供一个功能非常强大的 sql 管理支持,不仅可以管理,而且可以方便地动态生成带参的 sql

2016-10-29 17:34

看到 dao.put(log).save() 这样的代码,就知道大错特错了,jfinal 手册有红色字体明确说明过

dao 是 static 声明的全局共享的东西,不同线程在使用它的时候,数据是共享的,那么你第一次 dao.put 进去东西,第二再使用的时候与第一次会混乱,如果是多线程并发使用,数据是乱窜

所以 jfinal 最佳实践已经明确明说了,要将 Model 中的 dao 彻底删掉,避免这样的误用

删掉以后,查询的时候可以 new Xxx().find(sql) 这样就永远没有线程安全问题了

2016-10-28 17:55

@Romeo jfinal 社区的 UI 我能保证做到简洁但美观方面,我不是学美术的,一定会有所欠缺,好在简洁的 UI 在美观方法也不会太差

2016-10-28 17:32

@andywei 还有一个办法是仿照 CaseInsensitiveContainerFactory 写一个 CamelCaseContainerFactory 在拿数据的时候来做个转换,转换的方法可以直接调用 com.jfinal.kit.Str.java 中的 toCamelCase(...)

2016-10-28 17:28

@andywei 因为这个配置就是通过字段名去取的值,所以最好的办法是将数据表字段也用驼峰命名,这样所有全部都统一了,三年前就已经采用这种方式为字段命名了,极爽

2016-10-28 16:22

这样封装以后,又将开发效率再次提升了。贴代码可以点击编辑器代码语言按钮,选择java语言,这样保存以后的代码就有语法高亮,可读性会提升几个级别。感谢分享

2016-10-28 10:52

model 采用的是 ActiveRecord 设计模式,每个 model 事先与 table 建立了关联,所以很多操作会更加便捷,例如: user.set(...).set(...).save();

而 Db + Record 是 jfinal 独创的设计模式,Record 与 table 没有关联关系,所以是在调用方法时指令的,例如: Db.save("user", new Record().set(...).set(...));

Model 也是与具体某个数据源关联的,而 Record 在使用的时候如果使用非主数据源,需要使用 Db.use(...).save(...) 这种形式来切换

此外, model 可以生成 getter、setter 符合 java bean 规范,有助于整合很多依赖于 java bean 规范的第三方

Db + Record 模式更适合于那种需要灵活查询的应用场景,例如做报表的场景,报表中的数据是跨很多 table join 起来的,这种天然就与某个特定的 table 关联不大

2016-10-27 21:30

@坚强的地瓜 这种情况是缺少 jstl 支持的 jar 包

2016-10-27 21:27

添加Oracle 方言: generator.setDialect(new OracleDialect());
如果不添加默认是 MysqlDialect

2016-10-27 21:27

还有,拦截器被声明在了哪里? 是全局?

2016-10-27 21:25

按照下面几个方式找下原因:
1:在浏览器上按一下 F12,打开浏览器调试工具,然后再地址栏请求这个 action,看浏览器发了几个请求到这个 action,因为很多页面会有这个发多次请求的行为

2:在控制台看一下请求到来时的各个参数

2016-10-27 14:56

@坚强的地瓜 升级到 jfinal 2.2 版本即可,老版本没有这个功能