2017-07-27 21:33

@tuzqone 使用 jfinal 3.1 去支持中文文件名,前提是你的中文文件名在 linux 系统下本身不是乱码,如果本身就是乱码的,那在程序中也会是乱的

2017-07-27 21:19

@linuxea 挺有钻研精神,十分看好你

2017-07-27 20:58

这个是浏览器的设置问题,你换个浏览器就知道了。 在 chrom 之下可能会直接在浏览器中直接打开 pdf,在网上搜索一下如何设置就好,与 jfinal 社区代码毫无关系

2017-07-27 20:56

@linuxea 每个 ActiveRecordPlugin 对象都拥有独立的 Cache 依赖配置,所以,如果你的需求是每个数据源拥有独立的 cache,这个天然就实现了。

如果你是希望每个数据源拥有多个不同的 cache,这个需要你自己写代码去控制

2017-07-27 20:53

具体到你的场景,可以将 controller1 controller2 controller3 这三个块分别用一个简单的模板承载,例如:temp1.htm、temp2.html、temp3.html,然后在这三个模板文件中可以定义同名的模板函数,例如都定义一个 #define main() 出来

2017-07-27 20:51

再回到你的问题,模板文件只有一个入口文件,也就是 render(...) 方法中的参数所指向的那个模板文件,而一个模板文件没有太多必要搞出方法重载这类功能。所以 jfinal 模板引擎并不支持函数同名

解决方法可以是利用 #render 指令,为其传入动态的模板参数,实现模板的组合,这些个模板中定义的函数可以是同名的, #render 指令所处理的模板文件中的
#define xxx() 函数名是可以重名的,她们拥有各自的作用域

2017-07-27 20:48

你给出的结构图其实并不贴切,jfinal club 用于实现 layout 功能的方法,在本质上就是简单的函数调用:
1:#define layout() 定义 layout() 函数
2:layout() 函数中分别调用了 main() js() css() 这三个函数
3:定义 layout() 函数的模板文件通过 addSharedFunction(...) 将其置为共享函数,你可以认为是在最终的页面用 #include("__layout.html") 包含进来了而已
4:最终页面先是调用了 layout() 函数,然后 layout() 会调用 main()、js()、css(),而这三个函数在最终页面通过 #define 定义出来即可

简单来说:
1:最终页面,例如 index.html 是程序入口
2:在程序入口调用了 layout()
3:layout() 调用了定义在本页面定义的 main() js() css()

由于函数/方法几乎是所有程序语言中都有的现成的概念,所以理解起来非常符合直觉

2017-07-27 16:57

@杜福忠 这个是正解

2017-07-27 16:16

不是所有的应用场景都需要开启事务,我个人习惯于 Db.tx(...) 来做事务,看一下 FavoriteService.save() 这类方法中的 Db.tx 作法

要知道使用事务的目的是什么,是为了保持数据的一致性,有些情况下不需要开启事务也能保持一致性,就没有必要开启事务

2017-07-27 13:48

@linuxea 这么来添加拦截器,立即就能调试出来:
@Before({Tx.class, Tx.class})

也就是说,连续添加两个 Tx 拦截器

2017-07-27 13:05

@linuxea 单步去调试比光去想要高效得多,而且不易出错

2017-07-27 12:47

@Joph_csu 注意在 finally 块中进行关闭,否在出现异常时仍然会造成连接资源泄漏

2017-07-27 12:46

@linuxea RedisInterceptor 会将 redis 连接放在 ThreadLocal 之中,那么当前线程如果多次使用 redis 的话,用的是同一个连接,不用再多次获取连接。 具体细节你得仔细调试Cache 类中的 getJedis() 与 close(Jedis jedis) 这两个方法,注意 ThreadLocal 的行为

2017-07-27 11:44

@淡定007 mls 是你 new 出来的一个 ArrayList ,怎么可能是 null 呢?

2017-07-27 11:17

单步调试,观察一下 Cache.close(Jedis) 这个方法之中的细节看一下那个 if 语句是否为真,程序是否真的 close() 掉了这个连接,一切都清楚了