﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-大浪搏舟-随笔分类-网友文章</title><link>http://www.blogjava.net/surffish/category/5821.html</link><description>非学无以广才，非志无以成学！</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 11:40:57 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 11:40:57 GMT</pubDate><ttl>60</ttl><item><title>JAVA操作数据库方式与设计模式应用 </title><link>http://www.blogjava.net/surffish/archive/2006/04/18/41603.html</link><dc:creator>surffish</dc:creator><author>surffish</author><pubDate>Tue, 18 Apr 2006 03:05:00 GMT</pubDate><guid>http://www.blogjava.net/surffish/archive/2006/04/18/41603.html</guid><wfw:comment>http://www.blogjava.net/surffish/comments/41603.html</wfw:comment><comments>http://www.blogjava.net/surffish/archive/2006/04/18/41603.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/surffish/comments/commentRss/41603.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/surffish/services/trackbacks/41603.html</trackback:ping><description><![CDATA[1. 在业务层使用JDBC直接操作数据库－最简单，最直接的操作<br /><br />1）数据库url,username,password写死在代码中<br />Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); <br />String url="jdbc:oracle:thin:@localhost:1521:orcl"; <br />String user="scott"; <br />String password="tiger"; <br />Connection conn= DriverManager.getConnection(url,user,password); <br />Statement stmt=conn.createStatement(<br />ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); <br />String sql="select * from test"; <br />ResultSet rs=stmt.executeQuery(sql); <br /><br />2）采用Facade和Command模式，使用DBUtil类封装JDBC操作；<br />数据库url,username,password可以放在配置文件中（如xml,properties,ini等）。<br />这种方法在小程序中应用较多。<br /><br />2.DAO(Data Accessor Object)模式－松耦合的开始<br />DAO = data + accessor + domain object<br /><br />例如User类－domain object (javabean)<br />UserDAO类－accessor ，提供的方法getUser(int id)，save(User user)内包含了JDBC操作<br />在业务逻辑中使用这两个类来完成数据操作。<br /><br />使用Factory模式可以方便不同数据库连接之间的移植。<br /><br />3.数据库资源管理模式<br />3.1 数据库连接池技术<br />资源重用，避免频繁创建，释放连接引起大大量性能开销；<br />更快的系统响应速度；<br /><br />通过实现JDBC的部分资源对象接口( Connection, Statement, ResultSet )，可以使用Decorator设计模式分别产生三种逻辑资源对象: PooledConnection, PooledStatement和 PooledResultSet。<br /><br /><br />一个最简单地数据库连接池实现：<br />public class ConnectionPool {<br /><br />private static Vector pools;<br />private final int POOL_MAXSIZE = 25;<br />/**<br />* 获取数据库连接<br />* 如果当前池中有可用连接，则将池中最后一个返回；若没有，则创建一个新的返回<br />*/<br />public synchronized Connection getConnection() {<br />Connection conn = null;<br />if (pools == null) {<br />pools = new Vector();<br />}<br /><br />if (pools.isEmpty()) {<br />conn = createConnection();<br />} else {<br />int last_idx = pools.size() - 1;<br />conn = (Connection) pools.get(last_idx);<br />pools.remove(last_idx);<br />}<br /><br />return conn;<br />}<br /><br />/**<br />* 将使用完毕的数据库连接放回池中<br />* 若池中连接已经超过阈值，则关闭该连接；否则放回池中下次再使用<br />*/<br />public synchronized void releaseConnection(Connection conn) {<br />if (pools.size() &gt;= POOL_MAXSIZE)<br />try {<br />conn.close();<br />} catch (SQLException e) {<br />// TODO自动生成 catch 块<br />e.printStackTrace();<br />} else<br />pools.add(conn);<br />}<br /><br />public static Connection createConnection() {<br />Connection conn = null;<br />try {<br />Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();<br />String url = "jdbc:oracle:thin:@localhost:1521:orcl";<br />String user = "scott";<br />String password = "tiger";<br />conn = DriverManager.getConnection(url, user, password);<br />} catch (InstantiationException e) {<br />// TODO自动生成 catch 块<br />e.printStackTrace();<br />} catch (IllegalAccessException e) {<br />// TODO自动生成 catch 块<br />e.printStackTrace();<br />} catch (ClassNotFoundException e) {<br />// TODO自动生成 catch 块<br />e.printStackTrace();<br />} catch (SQLException e) {<br />// TODO自动生成 catch 块<br />e.printStackTrace();<br />}<br />return conn;<br />}<br />}<br /><br />注意：利用getConnection()方法得到的Connection，程序员很习惯地调用conn.close()方法关闭了数据库连接，那么上述的数据库连接机制便形同虚设。在调用conn.close()方法方法时如何调用releaseConnection()方法？这是关键。这里，我们使用Proxy模式和java反射机制。 <br /><br />public synchronized Connection getConnection() {<br />Connection conn = null;<br />if (pools == null) {<br />pools = new Vector();<br />}<br /><br />if (pools.isEmpty()) {<br />conn = createConnection();<br />} else {<br />int last_idx = pools.size() - 1;<br />conn = (Connection) pools.get(last_idx);<br />pools.remove(last_idx);<br />}<br /><br />ConnectionHandler handler=new ConnectionHandler(this);<br />return handler.bind(con);<br />}<br /><br />public class ConnectionHandler implements InvocationHandler {<br />private Connection conn;<br />private ConnectionPool pool;<br /><br />public ConnectionHandler(ConnectionPool pool){<br />this.pool=pool;<br />}<br /><br />/**<br />* 将动态代理绑定到指定Connection<br />* @param conn<br />* @return<br />*/<br />public Connection bind(Connection conn){<br />this.conn=conn;<br />Connection proxyConn=(Connection)Proxy.newProxyInstance(<br />conn.getClass().getClassLoader(), conn.getClass().getInterfaces(),this);<br />return proxyConn;<br />}<br /><br />/* （非 Javadoc）<br />* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])<br />*/<br />public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {<br />// TODO自动生成方法存根<br />Object obj=null;<br />if("close".equals(method.getName())){<br />this.pool.releaseConnection(this.conn);<br />}<br />else{<br />obj=method.invoke(this.conn, args);<br />}<br /><br />return obj;<br />}<br />}<br /><br />在实际项目中，并不需要你来从头开始来设计数据库连接池机制，现在成熟的开源项目，如C3P0,dbcp,Proxool等提供了良好的实现。一般推荐使用Apache dbcp，基本使用实例：<br />DataSource ds = null;<br />try{<br />Context initCtx = new InitialContext();<br />Context envCtx = (Context) initCtx.lookup("java:comp/env");<br />ds = (DataSource)envCtx.lookup("jdbc/myoracle");<br />if(ds!=null){<br />out.println("Connection is OK!");<br />Connection cn=ds.getConnection();<br />if(cn!=null){<br />out.println("cn is Ok!");<br />Statement stmt = cn.createStatement();<br />ResultSet rst = stmt.executeQuery("select * from BOOK");<br />out.println(" 
<p>rst is Ok!" + rst.next());<br />while(rst.next()){<br />out.println(" </p><p>BOOK_CODE:" + rst.getString(1));<br />}<br />cn.close();<br />}else{<br />out.println("rst Fail!");<br />}<br />}<br />else <br />out.println("Fail!");<br />}catch(Exception ne){ out.println(ne);<br />}<br /><br /><br />3.2 Statement Pool<br />普通预编译代码：<br />String strSQL=”select name from items where id=?”;<br />PreparedStatement ps=conn.prepareStatement(strSQL);<br />ps.setString(1, “2”);<br />ResultSet rs=ps.executeQuery();<br /><br />但是PreparedStatement 是与特定的Connection关联的，一旦Connection关闭，则相关的PreparedStatement 也会关闭。<br />为了创建PreparedStatement 缓冲池，可以在invoke方法中通过sql语句判断池中还有没有可用实例。<br /><br />4. 持久层设计与O/R mapping 技术<br />1） Hernate：适合对新产品的开发，进行封闭化的设计 <br />Hibernate 2003年被Jboss接管，通过把java pojo对象映射到数据库的table中，采用了xml/javareflection技术等。3.0提供了对存储过程和手写sql的支持，本身提供了hql语言。<br />开发所需要的文件：<br />hibernate配置文件： hibernate.cfg.xml 或 hibernate.properties<br />hibernate 映射文件： a.hbm.xml<br />pojo类源文件： a.java　　<br /><br />导出表与表之间的关系：<br />a. 从java对象到hbm文件：xdoclet <br />b. 从hbm文件到java对象：hibernate extension <br />c. 从数据库到hbm文件：middlegen <br />d. 从hbm文件到数据库：SchemaExport<br /><br />2）Iatis ：适合对遗留系统的改造和对既有数据库的复用，有很强的灵活性 3） Apache OJB：优势在于对标准的全面支持 4）EJB：适合集群服务器，其性能也不象某些人所诟病的那么差劲 5） JDO (java data object) <br />设置一个Properties对象，从而获取一个JDO的PersistenceManagerFactory（相当于JDBC连接池中的DataSource），进而获得一个PersistenceManager对象（相当于JDBC中的Connection对象），之后，你可以用这个PersistenceManager对象来增加、更新、删除、查询对象。<br />JDOQL是JDO的查询语言；它有点象SQL，但却是依照Java的语法的。<br /><br />5. 基于开源框架的Struts+Spring+Hibernate实现方案<br />示例：这是一个3层架构的web 程序，通过一个Action 来调用业务代理，再通过它来回调 DAO类。下面的流程图表示了MyUsers是如何工作的。数字表明了流程的先后顺序，从web层(UserAction)到中间层(UserManager)，再到数据层(UserDAO)，然后返回。<br />Spring是AOP, UserManager和UserDAO都是接口.<br />1) web层(UserAction) ：调用中间层的接口方法，将UserManager作为属性注入。<br />采用流行的Struts框架，虽然有很多人不屑一顾，但是这项技术在业界用的比较普遍，能满足基本的功能，可以减少培训学习成本。<br />2) 中间层(UserManager)：将UserDAO作为属性注入，其实现主要是调用数据层接口的一些方法；它处于事务控制中。<br />采用Spring框架实现，IOC与AOP是它的代名词，功能齐全，非常棒的一个架构。<br />3) 数据层(UserDAO)：实现类继承HibernateDaoSupport类，在该类中可以调用getHibernateTemplate()的一些方法执行具体的数据操作。<br />采用Hibernate做O/R mapping，从种种迹象可以看出，Hibernate就是EJB3.0的beta版。 (转载文章请保留出处：<a href="http://www.javajia.com/">Java家(www.javajia.com)</a>)</p><img src ="http://www.blogjava.net/surffish/aggbug/41603.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/surffish/" target="_blank">surffish</a> 2006-04-18 11:05 <a href="http://www.blogjava.net/surffish/archive/2006/04/18/41603.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>