JAVA中操作数据库方式与设计模式的应用 <script language="javascript" type="text/javascript">document.title="JAVA中操作数据库方式与设计模式的应用 - "+document.title</script>
JAVA数据库操作的各种方式与设计模式的应用
                                                               青山不改绿水长流-EKing
1.   在业务层使用JDBC直接操作数据库-最简单,最直接的操作
紧耦合方式,黑暗中的痛苦
1)数据库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);
2)使用DBHelp类封装JDBC操作;数据库url,username,password可以放在配置文件中(如xml)。这种方法在小程序中应用较多。
2.DAO(Data Accessor Object)模式-松耦合的开始
DAO = data + accessor + domain object
例如User类-domain object (javabean)
UserDAO类-accessor ,提供的方法getUser(int id),save(User user)内包含了JDBC操作
在业务逻辑中使用这两个类来完成数据操作。
使用Factory模式可以方便不同数据库连接之间的移植。
3.数据库资源管理模式
3.1 数据库连接池技术
资源重用,避免频繁创建,释放连接引起大大量性能开销;
更快的系统响应速度;
通过实现JDBC的部分资源对象接口( Connection, Statement, ResultSet ),可以使用Decorator设计模式分别产生三种逻辑资源对象: PooledConnection, PooledStatement和 PooledResultSet。
一个最简单地数据库连接池实现:
public class ConnectionPool {
       private static Vector pools;
       private final int POOL_MAXSIZE = 25;
       /**
        * 获取数据库连接
        * 如果当前池中有可用连接,则将池中最后一个返回;若没有,则创建一个新的返回
        */
       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;
       }
       /**
        * 将使用完毕的数据库连接放回池中
        * 若池中连接已经超过阈值,则关闭该连接;否则放回池中下次再使用
        */
       public synchronized void releaseConnection(Connection conn) {
              if (pools.size() >= POOL_MAXSIZE)
                     try {
                            conn.close();
                     } catch (SQLException e) {
                            // TODO自动生成 catch 块
                            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 块
                     e.printStackTrace();
              } catch (IllegalAccessException e) {
                     // TODO自动生成 catch 块
                     e.printStackTrace();
              } catch (ClassNotFoundException e) {
                     // TODO自动生成 catch 块
                     e.printStackTrace();
              } catch (SQLException e) {
                     // TODO自动生成 catch 块
                     e.printStackTrace();
              }
              return conn;
       }
}
注意:利用getConnection()方法得到的Connection,程序员很习惯地调用conn.close()方法关闭了数据库连接,那么上述的数据库连接机制便形同虚设。   在调用conn.close()方法方法时如何调用releaseConnection()方法?这是关键。这里,我们使用Proxy模式和java反射机制。
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;
     }
    
       /* (非 Javadoc)
        * @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;
       }
}
在实际项目中,并不需要你来从头开始来设计数据库连接池机制,现在成熟的开源项目,如C3P0,dbcp,Proxool等提供了良好的实现。一般推荐使用Apache dbcp,基本使用实例:
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
普通预编译代码:
String strSQL=”select name from items where id=?”;
PreparedStatement ps=conn.prepareStatement(strSQL);
ps.setString(1, “2”);
ResultSet rs=ps.executeQuery();
但是PreparedStatement 是与特定的Connection关联的,一旦Connection关闭,则相关的PreparedStatement 也会关闭。
为了创建PreparedStatement 缓冲池,可以在invoke方法中通过sql语句判断池中还有没有可用实例。
4. 持久层设计
1) Hernate:适合对新产品的开发,进行封闭化的设计
Hibernate 2003年被Jboss接管,通过把java pojo对象映射到数据库的table中,采用了xml/javareflection技术等。3.0提供了对存储过程和手写sql的支持,本身提供了hql语言。
开发所需要的文件:
hibernate配置文件: hibernate.cfg.xml 或 hibernate.properties
hibernate 映射文件: a.hbm.xml
pojo类源文件: a.java  
导出表与表之间的关系:
a. 从java对象到hbm文件:xdoclet
b. 从hbm文件到java对象:hibernate extension
c. 从数据库到hbm文件:middlegen
d. 从hbm文件到数据库:SchemaExport
2) Iatis :适合对遗留系统的改造和对既有数据库的复用,有很强的灵活性
3) Apache OJB:优势在于对标准的全面支持
4)EJB:适合集群服务器,其性能也不象某些人所诟病的那么差劲
5) JDO (java data object)
设置一个Properties对象,从而获取一个JDO的PersistenceManagerFactory(相当于JDBC连接池中的DataSource),进而获得一个PersistenceManager对象(相当于JDBC中的Connection对象),之后,你可以用这个PersistenceManager对象来增加、更新、删除、查询对象。
JDOQL是JDO的查询语言;它有点象SQL,但却是依照Java的语法的。
 

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=579613

JAVA中操作数据库方式与设计模式的应用 --青山不改绿水长流-EKing相关推荐

  1. Java操作数据库方式(六)DataSource详解

    ##概述 在java世界里操作数据库有很多方式,在众多方式中除了JDBC外都有DataSource对象. DataSource可以看作数据源,它封装了数据库参数,连接数据库,程序中操作DataSour ...

  2. Java操作数据库方式五MyBatis使用入门

    ##概述 ##MyBatis是什么 MyBatis是一个持久层框架,作用是在java项目中操作数据库. ##MyBatis介绍 MyBatis 本是apache的一个开源项目iBatis, 2010年 ...

  3. Java操作数据库方式二DBCP使用详解

    ##概述 DBCP的全称是:DataBase connection pool,翻译是:数据库连接池. 在Java操作数据库方式一JDBC使用详解中说到直接使用JDBC非常消耗资源.为了避免频繁关闭链接 ...

  4. java可以操作扫描仪吗_在Java中操作扫描仪(使用JNI)

    在Java中操作扫描仪(使用JNI) 作者:    文章来源: 发布日期:2005年01月01日    浏览次数:1次 这是一个用java来操作扫描仪的小例子: package edu.ctgu.JT ...

  5. java对数据库的增删改查_在java中对数据库进行增删改查

    代码区域: package com.oracle.jdbc.demo1; import java.sql.Connection; import java.sql.DriverManager; impo ...

  6. Java中操作Xml使用备忘

    List item 文章目录 Java中操作Xml使用备忘 1. Hutool中XmlUtil的使用简介 2. Hutool中XmlUtil快速读取Xml字符串某个节点值 [简单取值时,推荐使用] 2 ...

  7. java中操作字符串都有哪些类,他们之间有什么区别?

    java中操作字符串的类有哪些? String StringBuffer StringBuilder 区别 我们可以先看一下这几个类的继承关系图 从类的继承关系上来开的话,String和StringB ...

  8. java 中操作字符串都有哪些类?它们之间有什么区别?

    java 中操作字符串都有哪些类?它们之间有什么区别? String.StringBuffer.StringBuilder String : final修饰,String类的方法都是返回new Str ...

  9. Java中获取数据库中两个时间的相差秒数

    场景 Java中获取数据库中结束时间与开始时间相差的秒数. 实现 Long betweenTime=0l;betweenTime =((b.getFinishTime().getTime()-b.ge ...

  10. cmd中操作数据库的那些常见命令

    在cmd中进行数据库或表的增删修改 1.cmd中直接连接数据库语法为: >mysql -uroot -p 如果不是内部命令的话就需要去把mysql中bin目录的路径复制到计算机path路径中. ...

最新文章

  1. 35 利用构造函数和原型对象实现继承
  2. CentOS-7.2部署Squid服务
  3. video.min.js php,使用flv.js与video.js做一个视频直播效果
  4. 发布Apworks应用开发框架(Alpha版本)
  5. NeurIPS 2019 开源论文 | 万能的GNN解释器
  6. 万字总结!腾讯、字节跳动面经已发
  7. 1450. 在既定时间做作业的学生人数
  8. 画米老鼠_蔡康永都在买的画你也买得起,村上隆作品收藏大全
  9. HTTP缓存解释为何页面响应的数据和服务端的不一致
  10. 博士和博士后的有什么区别?
  11. 新颖的自我介绍_有创意的自我介绍10篇
  12. 皮克定理(格点三角形求面积或求三角形里格点(整点)个数)
  13. HTML七大选择器,HTML各类选择器
  14. Gentoo Linux 快速安装记录
  15. 如何提高数据处理中的准确性
  16. php后台如何添加sitemap,织梦后台的sitemap生成及推送教程
  17. 鲜有人知道的项目,各种邀请码偷偷做几个W
  18. Metasploit工具配置使用
  19. 微型计算机主板上有哪些芯片,微机主板上装有什么
  20. 导出excel时报错

热门文章

  1. 计算机编程语言用英语怎么说,编程用英语怎么说
  2. 港科夜闻|香港科技大学(广州)(筹)校长倪明选教授在北京拜访国家教育部党组书记、部长怀进鹏...
  3. html引入阿里在线css文件夹,阿里字体css代码引入方法
  4. 谷歌学术搜索技巧,命令搜索
  5. Google 镜像站搜集[转]
  6. 新浪邮箱开通imap服务器,新浪邮箱申请
  7. idea全局搜索替换快捷键
  8. 微信开发带参数的二维码
  9. 【Debug记录】Libtorch部署YOLO时cmake报错--symbol lookup error: ./test/test: undefined symbol: _ZN2at6detail1
  10. ambari集群修改ip地址