Java开发系列--JDBC


经过对前面代码的分析,会发现如下几个问题:java

Url、User、Password直接在代码中定义,若是数据库服务器稍做变更,怎么办?mysql

一个项目基本针对一个底层数据库,难道每次操做数据库,都要注册一次驱动程序嘛?是否能够只注册一次?sql

获取数据库链接时,每次都须要Url、User、Password,一旦改动其中一个数据,意味着要修改全部此处的代码。数据库

释放资源,每次数据库操做后,都须要释放资源,难道每次操做后都要写三次try close catch代码嘛?缓存


若是要解决上面的几个问题,那么就要对刚才的代码实现封装,而且把数据库的配置放到配置文件(Properties)中,具体作法以下:服务器

新建jdbc.properties,ide



内容以下:性能

[plain] view plain copyurl

  1. #数据库链接配置  spa

  2. driverClassName=com.mysql.jdbc.Driver  

  3. url=jdbc:mysql://127.0.0.1:3306/lcma?characterEncoding=utf-8  

  4. user=root  

  5. password=iflytek  


新建一个JdbcUtil类,实现代码以下:

[java] view plain copy

  1. import java.io.InputStream;  

  2. import java.sql.Connection;  

  3. import java.sql.DriverManager;  

  4. import java.sql.ResultSet;  

  5. import java.sql.SQLException;  

  6. import java.sql.Statement;  

  7. import java.util.Properties;  

  8.   

  9. public class JdbcUtil {  

  10.   

  11.     private static String url;  

  12.     private static String user;  

  13.     private static String password;  

  14.       

  15.     static{  

  16.         //使用properties加载属性文件  

  17.         Properties prop = new Properties();  

  18.         try {  

  19.             InputStream is = JdbcUtil.class.getClassLoader().getResourceAsStream("com/iflytek/jdbc.properties");  

  20.             prop.load(is);  

  21.             //注册驱动(获取属性文件中的数据)  

  22.             String driverClassName = prop.getProperty("driverClassName");  

  23.             Class.forName(driverClassName);  

  24.             //获取属性文件中的url,username,password  

  25.             url = prop.getProperty("url");  

  26.             user = prop.getProperty("user");  

  27.             password = prop.getProperty("password");  

  28.         } catch (Exception e) {  

  29.             e.printStackTrace();  

  30.         }  

  31.     }  

  32.       

  33.     //获取数据库链接  

  34.     public static Connection getConnection(){  

  35.         Connection conn = null;  

  36.         try {  

  37.             conn = DriverManager.getConnection(url, user, password);  

  38.         } catch (SQLException e) {  

  39.             e.printStackTrace();  

  40.         }  

  41.         return conn;  

  42.     }  

  43.       

  44.     //释放资源  

  45.     public static void close(Connection conn, Statement stat, ResultSet rs){  

  46.          if(conn != null){  

  47.              try {conn.close();} catch (SQLException e) {e.printStackTrace();}  

  48.          }  

  49.          if(stat != null){  

  50.              try {stat.close();} catch (SQLException e) {e.printStackTrace();}  

  51.          }  

  52.          if(rs != null){  

  53.              try {rs.close();} catch (SQLException e) {e.printStackTrace();}  

  54.          }  

  55.     }  

  56. }  


在加载配置文件的时候使用了静态代码块,代表类一加载,配置文件就会立马加载,属性被保存在静态变量中(url,user,password)。

获取数据库链接和释放资源都采用了静态方法,经过类直接调用改方法,实现了公用代码的封装,下降的代码的耦合性。

这时候咱们再来看JDBC获取数据库数据代码:

[java] view plain copy

  1. Connection conn = null;  

  2. Statement stat = null;  

  3. ResultSet rs = null;  

  4. try{  

  5.     //经过JdbcUtil获取数据库连接  

  6.     conn = JdbcUtil.getConnection();  

  7.     stat = conn.createStatement();  

  8.     rs = stat.executeQuery("select * from student");  

  9.     while(rs.next()){  

  10.          System.out.println(rs.getString("name"));  

  11.     }  

  12. }catch(Exception e){  

  13.     e.printStackTrace();  

  14. }finally {  

  15.     //经过JdbcUtil关闭资源  

  16.     JdbcUtil.close(conn, stat, rs);  

  17. }  

经过如今的代码能够看出,代码简介了不少,没有出现容易出错的配置,获取链接,加载配置文件,关闭资源咱们也不须要关心,大大下降了代码的耦合性,提升了代码重用性。

封装事后的代码仍是有些问题,就是采用了Statement对数据库操做,若是如今SQL语句须要传入变量,只有采用拼接的方式,这样作有不少缺点,例如拼接容易出错或容易产生SQL注入等。

经过PreparedStatement对数据库操做能够解决Statement带来的缺点,PreparedStatement和Statement区别以下:

Statement的缺点:

一样的SQL语句,每次都要发送,不能进行有效的缓存。

拼接SQL字符串很是容易出现错误。

不能防止恶意数据,易产生SQL注入。

升级后的新接口PreparedStatement(推荐):

预编译SQL语句,并进行有效的缓存,性能更好。

容许使用问号占位符参数,而且该参数必须得到值后才能够执行。

无需拼接SQL语句。

问号占位符参数:INSERTINTO User(id,name,age,birthday)VALUES(?,?,?,?); 

来看一下经过PreparedStatement对数据库操做的代码:

[java] view plain copy

  1. Connection conn = null;  

  2. PreparedStatement stat = null;  

  3. ResultSet rs = null;  

  4. try{  

  5.         //经过JdbcUtil获取数据库连接  

  6.     conn = JdbcUtil.getConnection();  

  7.     stat = conn.prepareStatement("select * from student where name like ? and age = ? ");  

  8.     stat.setString(1"%小%");  

  9.     stat.setInt(222);  

  10.     rs = stat.executeQuery();  

  11.     while(rs.next()){  

  12.            System.out.println(rs.getString("name"));  

  13.     }  

  14.     }catch(Exception e){  

  15.            e.printStackTrace();  

  16.     }finally {  

  17.         //经过JdbcUtil关闭资源  

  18.         JdbcUtil.close(conn, stat, rs);  

  19.     }  

  20. }  


注意如下两点:


1.问号占位符不能加引号。

2.占位符参数设置值从下标从1开始。


转载url:http://blog.csdn.net/mlc1218559742/article/details/52216895

相关文章
相关标签/搜索