关于Model中Find方法

幻影浪子 发布于 2012/08/04 22:33
阅读 808
收藏 0

@JFinal 你好,想跟你请教个问题:

Model中有这样一个方法, 是不是考虑开放?

	/**
	 * Find model.
	 */
	private List<M> find(Connection conn, String sql, Object... paras) throws Exception {
		Class<? extends Model> modelClass = getClass();
		if (DbKit.devMode)
			checkTableName(modelClass, sql);
		
		PreparedStatement pst = conn.prepareStatement(sql);
		for (int i=0; i<paras.length; i++) {
			pst.setObject(i + 1, paras[i]);
		}
		
		ResultSet rs = pst.executeQuery();
		List<M> result = ModelBuilder.build(rs, modelClass);
		DbKit.closeQuietly(rs, pst);
		
		return result;
	}

因为我在使用每次查询之前可能都需要执行“set names latin1”来进行编码转换, 而执行这个语句和执行查询的语句,要求使用同一个数据库连接。看了下,貌似只能通过这个方法来进行。

这个方法开放之后,我就可以自己通过Dbkit来获取数据库连接,做我想做的事, 然后再用同一个连接,做其他事。

Db.execute(new ICallback() {
				
				@Override
				public void run(Connection connection) throws SQLException {
					Statement statement = connection.createStatement();
					statement.execute("set names latin1;");
					
					List<Abc> abcList = Abc.dao.find(connection, sql, params);
				}
			});

Connection connection = DbKit.getConnection();
			Statement statement = connection.createStatement();
			statement.execute("set names latin1;");
			List<Abc> abcList = Abc.dao.find(connection, sql, params);

 

 

加载中
2
逝水fox
逝水fox

因为ActiveRecordPlugin需要的只是一个DataSource对象,可以自己实现一个,在构造函数的地方把真正的DataSource传入,只需要在两个getConnection()方法实现的地方执行完set names latin1再返回。其他方法全部直接用封装在内部的DataSource处理。

这样就可以既不破坏作者原有的想法,也不用在每个数据库操作之前都要重复写set names latin1的代码。

幻影浪子
幻影浪子
"在两个getConnection()方法实现的地方执行完set names latin1再返回" 什么意思?
0
幻影浪子
幻影浪子
我觉得可以改为public的
0
幻影浪子
幻影浪子
顺便说一下,“set names latin1” 跟 “characterEncoding=latin1”这两者是有区别的,后者无法代替前者。这边有一篇文章  http://chenjianjx.iteye.com/blog/1395743 。
0
幻影浪子
幻影浪子
Connection connection = DbKit.getConnection();
			Statement statement = connection.createStatement();
			statement.execute("set names latin1;");
			statement.close();
			DbKit.setThreadLocalConnection(connection);

这样做,似乎也可以做到使用同一个连接, 为什么不行呢?奇怪
0
JFinal
JFinal

引用来自“幻影浪子”的答案

我觉得可以改为public的

    JFinal 设计原则之一:尽可能让类、方法、属性的可见性达到最小,这样做的好处有很多,例如,private可见性在未来无需考虑兼容性,JFinal框架在不断完善中修改或删除 private 方法、default 类、private 属性时不会影响到开发者的项目代码。

    @幻影浪子 提的这个需求,如果要改成 public , 我还需要权衡考虑 :)

0
JFinal
JFinal

引用来自“逝水fox”的答案

因为ActiveRecordPlugin需要的只是一个DataSource对象,可以自己实现一个,在构造函数的地方把真正的DataSource传入,只需要在两个getConnection()方法实现的地方执行完set names latin1再返回。其他方法全部直接用封装在内部的DataSource处理。

这样就可以既不破坏作者原有的想法,也不用在每个数据库操作之前都要重复写set names latin1的代码。

    ActiveRecrodPlugin 有一个构造方法可以直接传入DataSource, 如果有第三方的DataSource可以拿来即用,无需实现一个 DataSource。

    另外如果想整合第三方数据源,可以实现 com.jfinal.activerecord 包下的 IDataSourceProvicder,JFinal 自带的 C3p0Plugin 就是实现的这个接口,只有一个方法需要实现即: public DataSource getDataSource()。

幻影浪子
幻影浪子
这种方式很棒!
0
JFinal
JFinal

引用来自“幻影浪子”的答案

Connection connection = DbKit.getConnection();
			Statement statement = connection.createStatement();
			statement.execute("set names latin1;");
			statement.close();
			DbKit.setThreadLocalConnection(connection);

这样做,似乎也可以做到使用同一个连接, 为什么不行呢?奇怪
把 DbKit.setThreadLocalConnectoin(connectoin)放在第二行试试,如果你在程序中 DbKit.getConnection() 注意要自己去关闭 connection, 以防连接未释放,在生产环境下,很容易造成系统无响应 :)
幻影浪子
幻影浪子
放第二行,跟放第五行的效果,我认为是一样的。 另外,我这边就是为了跟find用同一个链接, 此处不能关闭, 在find方法中会关闭的。
返回顶部
顶部