1. 在业务层使用JDBC直接操作数据库-最单,最直接的操?/FONT>
1Q数据库url,username,password写死在代码中
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
String url="jdbc:oracle:thin:@localhost:1521:orcl";
String user="scott";
String password="tiger";
Connection conn= DriverManager.getConnection(url,user,password);
Statement stmt=conn.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
String sql="select * from test";
ResultSet rs=stmt.executeQuery(sql);
2Q采用Facade和Command模式Q用DBUtilcd装JDBC操作Q?/FONT>
数据库url,username,password可以攑֜配置文g中(如xml,properties,ini{)?/FONT>
q种Ҏ在小E序中应用较多?/FONT>
2.DAO(Data Accessor Object)模式Q松耦合的开?/FONT>
DAO = data + accessor + domain object
例如Userc-domain object (javabean)
UserDAOc-accessor Q提供的ҎgetUser(int id)Qsave(User user)内包含了JDBC操作
在业务逻辑中用这两个cL完成数据操作?/FONT>
使用Factory模式可以方便不同数据库连接之间的UL?/FONT>
3.数据库资源管理模?/FONT>
3.1 数据库连接池技?/FONT>
资源重用Q避免频J创建,释放q接引v大大量性能开销Q?/FONT>
更快的系l响应速度Q?/FONT>
通过实现JDBC的部分资源对象接? Connection, Statement, ResultSet )Q可以用Decorator设计模式分别产生三种逻辑资源对象: PooledConnection, PooledStatement?PooledResultSet?/FONT>
一个最单地数据库连接池实现Q?/FONT>
public class ConnectionPool {
private static Vector pools;
private final int POOL_MAXSIZE = 25;
/**
* 获取数据库连?/SPAN>
* 如果当前池中有可用连接,则将池中最后一个返回;若没有,则创Z个新的返?/SPAN>
*/
public synchronized Connection getConnection() {
Connection conn = null;
if (pools == null) {
pools = new Vector();
}
if (pools.isEmpty()) {
conn = createConnection();
} else {
int last_idx = pools.size() - 1;
conn = (Connection) pools.get(last_idx);
pools.remove(last_idx);
}
return conn;
}
/**
* 用完毕的数据库连接放回池?/SPAN>
* 若池中连接已l超q阈|则关闭该q接Q否则放回池中下ơ再使用
*/
public synchronized void releaseConnection(Connection conn) {
if (pools.size() >= POOL_MAXSIZE)
try {
conn.close();
} catch (SQLException e) {
// TODO自动生成 catch ?/SPAN>
e.printStackTrace();
} else
pools.add(conn);
}
public static Connection createConnection() {
Connection conn = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
String url = "jdbc:oracle:thin:@localhost:1521:orcl";
String user = "scott";
String password = "tiger";
conn = DriverManager.getConnection(url, user, password);
} catch (InstantiationException e) {
// TODO自动生成 catch ?/SPAN>
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO自动生成 catch ?/SPAN>
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO自动生成 catch ?/SPAN>
e.printStackTrace();
} catch (SQLException e) {
// TODO自动生成 catch ?/SPAN>
e.printStackTrace();
}
return conn;
}
}
注意Q利用getConnection()Ҏ得到的ConnectionQ程序员很习惯地调用conn.close()Ҏ关闭了数据库q接Q那么上q的数据库连接机制便形同虚设?SPAN style="BACKGROUND-COLOR: #ffffff">在调用conn.close()ҎҎ时如何调用releaseConnection()ҎQ这是关键。这里,我们使用Proxy模式和java反射机制?/SPAN>
public synchronized Connection getConnection() {
Connection conn = null;
if (pools == null) {
pools = new Vector();
}
if (pools.isEmpty()) {
conn = createConnection();
} else {
int last_idx = pools.size() - 1;
conn = (Connection) pools.get(last_idx);
pools.remove(last_idx);
}
ConnectionHandler handler=new ConnectionHandler(this);
return handler.bind(con);
}
public class ConnectionHandler implements InvocationHandler {
private Connection conn;
private ConnectionPool pool;
public ConnectionHandler(ConnectionPool pool){
this.pool=pool;
}
/**
* 动态代理绑定到指定Connection
* @param conn
* @return
*/
public Connection bind(Connection conn){
this.conn=conn;
Connection proxyConn=(Connection)Proxy.newProxyInstance(
conn.getClass().getClassLoader(), conn.getClass().getInterfaces(),this);
return proxyConn;
}
/* Q非 JavadocQ?/SPAN>
* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO自动生成Ҏ存根
Object obj=null;
if("close".equals(method.getName())){
this.pool.releaseConnection(this.conn);
}
else{
obj=method.invoke(this.conn, args);
}
return obj;
}
}
在实际项目中Qƈ不需要你来从头开始来设计数据库连接池机制Q现在成熟的开源项目,如C3P0,dbcp,Proxool{提供了良好的实现。一般推荐用Apache dbcpQ基本用实例:
DataSource ds = null;
try{
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
ds = (DataSource)envCtx.lookup("jdbc/myoracle");
if(ds!=null){
out.println("Connection is OK!");
Connection cn=ds.getConnection();
if(cn!=null){
out.println("cn is Ok!");
Statement stmt = cn.createStatement();
ResultSet rst = stmt.executeQuery("select * from BOOK");
out.println("<p>rst is Ok!" + rst.next());
while(rst.next()){
out.println("<P>BOOK_CODE:" + rst.getString(1));
}
cn.close();
}else{
out.println("rst Fail!");
}
}
else
out.println("Fail!");
}catch(Exception ne){ out.println(ne);
}
3.2 Statement Pool
普通预~译代码Q?/FONT>
String strSQL=”select name from items where id=??
PreparedStatement ps=conn.prepareStatement(strSQL);
ps.setString(1, ??;
ResultSet rs=ps.executeQuery();
但是PreparedStatement 是与特定的Connection兌的,一旦Connection关闭Q则相关的PreparedStatement 也会关闭?/FONT>
Z创徏PreparedStatement ~冲池,可以在invokeҎ中通过sql语句判断池中q有没有可用实例?/FONT>
4. 持久层设计与O/R mapping 技?/FONT>
1Q?nbsp;HernateQ适合Ҏ产品的开发,q行闭?SPAN style="BACKGROUND-COLOR: #ffffff">的设?
Hibernate 2003q被Jboss接管Q?SPAN style="FONT-SIZE: 10pt">通过?/SPAN>java pojo对象映射到数据库?/SPAN>table中,采用?/SPAN>xml/javareflection技术等?/SPAN>3.0提供了对存储q程和手?/SPAN>sql的支持,本n提供?/SPAN>hql语言?/SPAN>
开发所需要的文gQ?/FONT>
hibernate配置文gQ?/SPAN> hibernate.cfg.xml ?/SPAN> hibernate.properties
hibernate 映射文gQ?/SPAN> a.hbm.xml
pojocL文gQ?/SPAN> a.java
导出表与表之间的关系Q?/FONT>
a. ?/SPAN>java对象?/SPAN>hbm文gQ?/SPAN>xdoclet
b. ?/SPAN>hbm文g?/SPAN>java对象Q?/SPAN>hibernate extension
c. 从数据库?/SPAN>hbm文gQ?/SPAN>middlegen
d. ?/SPAN>hbm文g到数据库Q?/SPAN>SchemaExport
2Q?SPAN style="BACKGROUND-COLOR: #ffffff">Iatis Q适合寚w留系l的攚w和Ҏ有数据库的复用,有很强的灉|?3Q?Apache OJBQ优势在于对标准的全面支?4QEJBQ适合集群服务器,其性能也不象某些h所诟病的那么差?5Q?JDO (java data object)
讄一个Properties对象Q从而获取一个JDO的PersistenceManagerFactoryQ相当于JDBCq接池中的DataSourceQ,q而获得一个PersistenceManager对象Q相当于JDBC中的Connection对象Q,之后Q你可以用这个PersistenceManager对象来增加、更新、删除、查询对象?/FONT>
JDOQL是JDO的查询语aQ它有点象SQLQ但却是依照Java的语法的?/FONT>
5. Z开源框架的Struts+Spring+Hibernate实现Ҏ
CZQ这是一?/SPAN>3层架构的web E序Q通过一?/SPAN>Action 来调用业务代理,再通过它来回调 DAOcR下面的程图表CZMyUsers是如何工作的。数字表明了程的先后顺序,?/SPAN>web?/SPAN>(UserAction)C间层(UserManager)Q再到数据层(UserDAO)Q然后返回?/SPAN>
Spring?/SPAN>AOP, UserManager?/SPAN>UserDAO都是接口.
1) web?/SPAN>(UserAction) Q调用中间层的接口方法,?/SPAN>UserManager作ؓ属性注入?/SPAN>
采用行的Struts框架Q虽然有很多Z屑一,但是q项技术在业界用的比较普遍Q能满基本的功能,可以减少培训学习成本?/FONT>
2) 中间?/SPAN>(UserManager)Q将UserDAO作ؓ属性注入,其实C要是调用数据层接口的一些方法;它处于事务控制中?/SPAN>
采用Spring框架实现QIOC与AOP是它的代名词Q功能齐全,非常的一个架构?/FONT>
3) 数据?/SPAN>(UserDAO)Q实现类l承HibernateDaoSupportc,在该cM可以调用getHibernateTemplate()的一些方法执行具体的数据操作?/SPAN>
采用Hibernate做O/R mappingQ从U种q象可以看出QHibernate是EJB3.0的beta版?/FONT>

]]>