能不能让JDBC也提供O/R映射呢.

dao代码中不应有事务处理存在,应在调用dao的业务方法中调用。
我使用spring的事务,用aop完成事务配置管理。

businessObject

method

transaction begin start

invoke DataAccessObject1.method
invoke DataAccessObject2.method

transaction commit


为什么不用ThreadLocal进行connection的处理呢?这样即使有多个类的方法放在一起运行,也只是使用一个connection,并且可以使用事务。

高人啊!我现在对这方面的问题也郁闷啊

为什么不用存储过程来处理,非常方便,速度又快。多看看数据库吧,你会爱上它的。什么方便用什么,会的东西越多,整体性能,架构越好。

另外你这种DAO根本不能称为DAO.
为什么让DAO的方法循环依赖,自找麻烦阿。

我整理了一下以下建议:

发表人: SportsBaby1980 发表文章: 244 / 注册时间: 2004-06
Dao只能使用资源,而不应该管理资源。

也就是说,Dao可以使用Connection,但不能维护它----生成和关闭。


发表人: SportsBaby1980 发表文章: 244 / 注册时间: 2004-06
我认为事务不要有dao来处理。
应该由业务方法处理

发表人: zdbj2ee 发表文章: 16 / 注册时间: 2003-08
dao代码中不应有事务处理存在,应在调用dao的业务方法中调用。
我使用spring的事务,用aop完成事务配置管理。

businessObject

method

transaction begin start

invoke DataAccessObject1.method
invoke DataAccessObject2.method

transaction commit

发表人: yanchaomin 发表文章: 1 / 注册时间: 2005-06
为什么不用ThreadLocal进行connection的处理呢?这样即使有多个类的方法放在一起运行,也只是使用一个connection,并且可以使用事务。

本人认为 SportsBaby1980 说的是对的。将DAO单独分出来的目的是把业务处理部分和数据库访问部分相分离。而我们应用程序中的事务,我认为属于业务逻辑的一部分。
正如 zdbj2ee 所说: "dao代码中不应有事务处理存在,应在调用dao的业务方法中调用。"
yanchaomin 的建议不错,实际上我们的项目也是这样做的(请问你是用LEO架构的吗?),解决事务问题,这是个不错的方法。
下面发个我们现在的做法给大家参考,多提意见(这种做法有好有坏,大家一起来想想如何改进)!


public class BasicDAO
{

String _driver;
String _url;
String _user;
String _password;
String _datasource;
DataSource _ds;
static ThreadLocal _session = new ThreadLocal();


public BasicDAO(String datasource)
throws Exception
{
_datasource = datasource;
Context ctx = null;
try
{
ctx = JNDIUtil.getDefaultContext();
_ds = (DataSource)ctx.lookup(datasource);
}
catch(Exception e)
{
ctx = SysConfig.getZHContext();
_ds = (DataSource)ctx.lookup(datasource);
}
}

public void begin()
throws Exception
{
TransactionContext ctx = (TransactionContext)_session.get();
if(ctx != null)
{
throw new Exception("Already in a tranction.");
} else
{
ctx = new TransactionContext();
_session.set(ctx);
return;
}
}

public void commit()
throws Exception
{
TransactionContext ctx = (TransactionContext)_session.get();
if(ctx == null)
throw new Exception("No in an transaction.");
ctx.commit();
_session.set(null);
break MISSING_BLOCK_LABEL_48;
Exception exception;
exception;
_session.set(null);
throw exception;
}

public void rollback()
throws Exception
{
TransactionContext ctx = (TransactionContext)_session.get();
if(ctx == null)
throw new Exception("No in an transaction.");
ctx.rollback();
_session.set(null);
break MISSING_BLOCK_LABEL_48;
Exception exception;
exception;
_session.set(null);
throw exception;
}

public Connection getConnection()
throws Exception
{
if(_ds != null)
{
TransactionContext ctx = (TransactionContext)_session.get();
if(ctx != null)
{
Connection conn = ctx.getConnection();
if(conn == null)
{
Connection conn1 = _ds.getConnection();
conn1.setAutoCommit(false);
conn = new ConnectionWrapper(conn1);
ctx.setConnection(conn);
}
return conn;
} else
{
return _ds.getConnection();
}
} else
{
return DriverManager.getConnection(_url, _user, _password);
}
}

public int executeUpdate(String sql)
throws Exception
{
Connection conn;
Statement stmt;
conn = null;
stmt = null;
int i;
SQLException e;
int code;
byte byte0;
try
{
conn = getConnection();
if(logger.isDebugEnabled())
logger.debug(sql);
stmt = conn.createStatement(1005, 1008);
i = stmt.executeUpdate(sql);
}
finally
{
try
{
if(stmt != null)
stmt.close();
}
catch(Exception e) { }
try
{
if(conn != null)
conn.close();
}
catch(Exception e) { }
}
return i;
e;
code = e.getErrorCode();
logger.error("SQLException", e);
if(code == 1)
ErrorHandle.throwError("999001", 0, "BasicDAO");
else
ErrorHandle.throwError("999002", 0, "BasicDAO");
byte0 = -1;
return byte0;
}



楼上有的朋友说DAO不好,其实任何设计模式都有它的适用范围,也就是说任何设计模式都是在某种特定的环境下会起到好的作用,当应用逻辑非常简单时,用DAO就显得有些拖沓,但是,当业务逻辑比较复杂且日后容易发生变化需要维护时,DAO就比较好了,DAO的好处很多朋友都已经说了很多,其实DAO还有一个好处就是根据接口编程,一个DAO只是一个接口,它可以有多种实现方式,JDBC操作是很简单方便,但是JDBC处理不了多个数据库之间的事务问题,分布式是事务必须依据两阶段提交协议处理,因此需使用JTA进行实现,所以,在有必要的情况下,一个DAO接口有时会有两个DAOImp,一个使用JDBC实现,一个使用JTA实现

除了利用DAO实现数据库访问以外,我们还可以考虑使用Hibernate,Hibernate可以为我们隐藏访问数据库的细节

--->为什么不用存储过程来处理,非常方便,速度又快

我现在的系统也是写存储过程的(不是我写),而且报表生成也是依赖存储过程的,方便是方面,但是感觉有点不对尽,但我又说不出来 ,哪里可能出现问题,我指系统维护等方面....

bangq 的用 AspectJ的实现不是很好
实际在connection 上加了互斥锁,但是考虑不全面.
如果在并发情况下,有对methodA()和methodB()同时访问,效率会很大降低.

如果系统就几张表,使用jdbc有什么不好吗

说说我的意见。
1.用threadlocal处理connection---可以。但是不好,可能会很糟
a.不好。如果存在一种情况。一个web app需要2个库的数据。你需要在设置2个threadlocal。而且(使用struts)需要重载baseaction中的execute方法,每次都要setCurrent(我当初遇到的问题是在logon时设置后,如果不每次设置,有的时候得不到。)
b.很糟。如果调用service的线程和service不是一个线程......
2.antzl->除了使用dao,可以使用hibernate。---可以。但是不好,如果您这么使用Hibernate,拿不是您在使用他,而是您在依赖他。您可能需要和他解耦了.....
我认为,dao是一种设计思想。hibernate我更情愿认为他只是一种实现手段而已(甚至,如果使用他,我只是拿他当作daoImp的一种方式。虽然hibernate自己可以进行事务管理等等DAOManager的功能)。
3.使用存储过程--可以。但是不太好。如果简单的系统。表不超过5个。我宁愿使用存储过程。原因很简单--开发快!但是如果项目大,谁来天天清醒的维护那些存储过程呢(当然还有开发人员需要清醒的知道那些sp是给他用的)?

我的解决办法(由于水平问题。我还没深入的学习什么是ioc和aop):
类似于antzl 前面指出的“我一般用IOC解决类似问题,请大家讨论优缺点”的方法。有daomanager来管理transaction。

我不太喜欢用hibernate。因为他的效率不是很好。我们现在的项目,一个transaction需要batch操作大概5000记录。如果用hibernate我就需要等好久啊。所以我更喜欢用jdbc一些

以上只是小弟的一点想法。由于经验和水平的限制。还请各位大哥大姐多多指点。

DAO的目的和功能到底是什么啊?antzl说的很精辟,我觉得只有尽可能的分离,才能降低系统中的耦合度!另外,对于事务的处理本身在HIBERNATE中就是依赖于其他的事务管理,在配置中你可以选用,并且即使你要自己实现,也应该将它放在业务处理方法里

如果不用spring那方面的框架的话,管理事务的方法,还是将connection的生成关闭,交给业务对象好过了,虽然有点耦合,但是问题不大.