JDBC: 最差实战-最佳实战-模板方法

发布时间:2017-1-22 18:08:25 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"JDBC: 最差实战-最佳实战-模板方法",主要涉及到JDBC: 最差实战-最佳实战-模板方法方面的内容,对于JDBC: 最差实战-最佳实战-模板方法感兴趣的同学可以参考一下。

程序 :  写一个 JDBC 程序, 要求能对数据库信息进行读取: :   一: 最差实战:  从 yuqing 数据库的 pet 表中读取两条信息.:   1. 思路: 要读去数据库的信息,我们必须让我们的程序先与数据库建立连接, 所以 (1). 创建一个Connection 对象,该对象负责去与数据库建立连接,在这里我们用的是Mysql,呢我们就查看 MySql-的JDBC Reference:  Mysql的url格式如下:   jdbc:mysql://[host][,failoverhost...][:port]/[database][?propertyName1][=propertyValue1][&propertyName2][=propertyValue2]    看的眼是不是有点花啊,呵呵,我们不需要呢么麻烦: 我们可以这样来:   Connection  conn  = DriverManager.getConnection("jdbc:mysql://127.0.0.1/yuqing","root","");  这里解释一下本人为什么把上面写成 127.0.0.1 而不写 localhost, 本人认为这样是一个不错的习惯,  因为在做 WEB 开发的时候如果你的浏览器设置了代理,一定要小心: 要用 127.0.0.1 ,而不要用 localhost ! 因为你使用localhost 的话,访问localhost 将不再是访问本机了.   (2) 取得一个连接后,我们是不是该让这个连接和我们的程序之间架一个桥了   ? :我们知道了上面有了一个 Connection 对象了,我们查看 API 中Collection 类: 它有一个这样的方法: createStatement() : 范围类型 :  Statement           Creates a Statement object for sending SQL statements to the database. 所以我们就知道这就是我们要架的桥,我们的程序靠它来给我们向数据库发送 SQL 语句了.所以:  Statement stmt = conn.createStatement();   (3).桥也架好了,接下来就要我们通过这个桥发送 SQL 语句了,查看 API 文档Statement 类: executeQuery(String sql)  返回类型:ResultSet           Executes the given SQL statement, which returns a single ResultSet object 我们知道这就是我们要的家伙了:---( 我们这里指的是查询 ) 所以: ResultSet rs= stmt.executeQuery("SELECT * FROM pet");         我们这里只是查询,所以是executeQuery(String sql),要是更新可以用executeUpdate(String sql).但是它的返回类型是 int  !   (4). 我们在上面又得到了一个结果集.当然想看看自己的查询结果吧.有什么好的方法呢?这里我们又查看 API 的 ResultSet 接口: next()           Moves the cursor down one row from its current position. 呵呵,看到了吧,可以 while( rs.next() ) 让它一直都移动我们的游标,来显示我们的结果.这里我们只选择两条记录所以: while(rt.next())               {                                 System.out.printf("%s:%s/n",rt.getString(1),rt.getString(2));               } (5). OK,搞定了 !                搞定了吗 ? 当然不是,我们在前面建立了Connection 连接,架了桥.这里当然要 close 掉啊 !所以:             rt.close();               stmt.close();               conn.close(); 这里,顺序一定不要反啊,想想如果没了连接,去哪架桥去,没了桥,通过什么查询结果去  ?   2. 思路有了,呢就开始 coding 吧 !   package cn.pqcc2000; import java.sql.*;   public class JdbcDemo {        public static void main(String args[])throws Exception        {   // Class.forName(---) 是在运行的时候加载 Driver 类,这样我们就不需要在运行的时候 //java –Djdbc.derivers = com.mysql.jdbc.Driver                Class.forName("com.mysql.jdbc.Driver");   Connection  conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1/yuqing","root","");               Statement stmt = conn.createStatement();               ResultSet rt= stmt.executeQuery("SELECT * FROM pet");                      while(rt.next())               {                                 System.out.printf("%s:%s/n",rt.getString(1),rt.getString(2));               }                             rt.close();               stmt.close();               conn.close();                      } } 哈哈,这样的程序出来是不是自己觉得比较满意啊  ? 但是想想有没有什么问题呢 ?     思考: 1.     如果将来我的程序查询的数据库变了,主机变了,用户名变了,该怎么办 ? 2.     我们的异常这样处理合适吗?如果我们呢的程序在 Statement stmt = conn.createStatement(); 的时候出现异常了,也就是说我们的桥没有架设好,呢么 Result rt == null ,如果我再 rt.close( ),  呢么就会有空指针异常,我们的程序提前退出,我们的 conn.close() 就没有调用 ..所以,我们这里要捕捉异常.并在 close()的时候判断 != null .而且无论如何我们都要 close 掉这些资源.所以应放到 finally中. 有了上面的问题,我们考虑用一个properties 文件来存放我们的资源文件: JDBC.properties 文件: jdbc.driver =com.mysql.jdbc.Driver jdbc.driverType =jdbc:mysql jdbc.host =127.0.0.1 jdbc.database =yuqing jdbc.user =root jdbc.password = jdbc.sql =SELECT * FROM pet   有了这样的一个文件我们该如何把它读取到我们的程序中呢 ? 还是查看 API   load(InputStream inStream) 无返回类型          Reads a property list (key and element pairs) from the input stream getProperty(String key) 返回类型: String           Searches for the property with the specified key in this property list.   呵呵,这个就是我们要的.   呢么我们就开始修改我们上面的程序: 我们要做的两件事情: (1).读取properties文件:要先 load(InputStream inStream),然后再逐一getProperty(--). (2) 处理我们的异常   修改我们的程序: package  cn.pqcc2000; import java.io.FileInputStream; import java.io.InputStream; import java.util.Properties; import java.sql.*; public class JdbcDemo {                   public static void main(String args[]) throws Exception        {                     String   KEY_DRIVER = "jdbc.run";          String   KEY_DRIVER_TYPE = "jdbc.driverType";          String   KEY_HOST  = "jdbc.host" ;          String   KEY_DATABASE  = "jdbc.database" ;          String   KEY_USER  = "jdbc.user" ;          String   KEY_PASSWORD  ="jdbc.password" ;      String   KEY_SQL  = "jdbc.sql" ;                  Properties prop = new Properties();              InputStream ips = new FileInputStream("a.properties");                                if(ips == null)               {                      throw new IllegalArgumentException("file not find");               }                                        prop.load(ips);               ips.close();                                       String  driverType=prop.getProperty(KEY_DRIVER_TYPE);        String  host=prop.getProperty(KEY_HOST);              String  database=prop.getProperty(KEY_DATABASE);        String  user=prop.getProperty(KEY_USER);              String  password=prop.getProperty(KEY_PASSWORD);              String  sql=prop.getProperty(KEY_SQL);              String  run =prop.getProperty(KEY_RUN);                            Connection conn = null;               Statement  stmt = null;               ResultSet  rs = null;                                            try                {                      Class.forName(run);                      conn = DriverManager.getConnection(driverType+":"+"//"+host+"/" +database,user,password);                      stmt = conn.createStatement();                      rs= stmt.executeQuery(sql);                                           while(rs.next())                      {                             System.out.printf("%s:%s/n",rs.getString(1),rs.getString(2));                      }               }               catch(Exception e)               {                      e.printStackTrace();               }                             finally               {                      if(rs != null)                                       try{rs.close();}catch(Exception ex1){ex1.printStackTrace();}                      if(stmt != null)                             try{stmt.close();}catch(Exception ex){ex2.printStackTrace();}                      if(conn != null)                                  try{conn.close();}catch(Exception ex3){ex3.printStackTrace();}                                                       }                      } }   再思考这样代码好吗 ?如果以后我们要写 JDBC 的程序都要这样在每个程序里面加上这么多的 Connection ,  finally( try , catch )  吗?想想就让人很不爽,这些重复代码我们不希望每次都重复的出现在我们的代码里面,呢么怎么办呢 ? 做网页的时候我们都知道有模板会有很大的方便,呢么我们是不是也可以尝试用模板方法呢?我们先写一个模板,然后我们需要用到同样的程序的时候,我们就继承"模板",然后我们在模板里面只需要添加一些我们 "个性"的代码就 OK 了.   修改我们的代码:( 阿门,请宽恕 !时间关系,我在这里没有使用Properties文件) 先写一个模板:它在这里给我们做一些通用的方法,具体的"个性"代码我们到它的子类里面有不同实现. package cn.pqcc2000; import java.sql.*;   abstract  class JdbcDemo_Parent {                            static Statement stmt;               ResultSet  rs  = null;              public     abstract  void doExecute(Statement stmt)throws Exception;                   public void execute(Statement stmt)        {                                 Connection conn = null;                             try               {                      Class.forName("com.mysql.jdbc.Driver");                        conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1/yuqing", "root", "");                      stmt = conn.createStatement();                                                                              doExecute(stmt);                              }                   catch(Exception e)               {                      e.printStackTrace();               }                          finally               {                      if(rs != null)                                       try{rs.close();}catch(Exception ex){}                      if(stmt != null)                             try{stmt.close();}catch(Exception ex){}                      if(conn != null)                                  try{conn.close();}catch(Exception ex){}                                        }                      }       现在编写我们的主类,这个类要继承"模板"类,并且要重写父类里面doExecute(Statement stmt).开始我们自己"个性"的代码 :   package cn.pqcc2000; import java.sql.*;   public class JdbcDemo_Child extends JdbcDemo_Parent {                                    public static void main(String args[])        {                                        JdbcDemo_Parent parent = new JdbcDemo_Child();                        parent.execute(stmt);        }                             public void doExecute(Statement stmt)throws Exception        {                                               try                             {                                                        rs = stmt.executeQuery("SELECT * FROM pet");                                                                                                                  while(rs.next())                                      {                                          System.out.print(rs.toString());                                            //System.out.printf("%s:%s/n",rs.getString(1),rs.getString(2));                                      }                                              rs.close();                                      rs = null;    // 最好加上这一句话,防止以后再对 rs 进行引用.                             }                             catch(Exception e)                                    {                                    e.printStackTrace();                             }                                    } }   看看我们的程序是怎么运做的 : 1.   首先new 一个对象,然后调用父类的 exexute( )方法,该方法去创建Connection. 2.   execute()然后调用子类的doExecute(Statement stmt).来执行"个性化"代码 3.   继续回到execute(),处理呢些通用的,异常代码吧!   OK 符合要求 !   呵呵,我们的"模板"的作用是不是显而易见的.以后我们在写 JDBC 程序,就可以这样子,继承"模板".然后只写一些类似: rs = stmt.executeQuery("SELECT * FROM pet"); 这样的语句就可以了呢  ? 呵呵 !时间关系,没有使用 properties.   不过,模板方法使用的是继承,不如将来改成策略模式,这样的话,在一定程度上减少了我们程序的耦合性!像大师说的 :"要多用组合,而不是继承" ! 呵呵! 继续努力 ing !  

上一篇:XML的简单读取与写入
下一篇:鼠标乱动原来是这个问题啊=.=

相关文章

相关评论