• 厚积薄发系列之JDBC详解


    创建一个以JDBC链接数据库的程序,包含七个步骤

    1.加载JDBC驱动

      • 加载要连接的数据库的驱动到JVM
      • 如何加载?forName(数据库驱动)
      • MySQL:Class.forName("com.mysql.jdbc.Driver");
      • Oracle10g:Class.forName("oracle.jdbc.driver.OracleDriver");
      • SQLServer2005:Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
      • 1         //1.加载驱动程序 mysql为例子
        2         try {
        3             Class.forName("com.mysql.jdbc.Driver");
        4         } catch (ClassNotFoundException e) {
        5             // TODO Auto-generated catch block
        6             e.printStackTrace();
        7             System.out.println("加载驱动失败");
        8         }

    2.提供JDBC连接的URL

      • 连接URL定义了连接数据库时的协议,子协议,数据源标识
      • 根据不同的数据库产品不同连接的URL不同
        • Oracle10g:jdbc:oracle:thin:@主机名:端口:数据库SID
        • MySQL5:jdbc:mysql://主机名:端口/数据库名
        • SQLServer2005:jdbc:sqlserver://主机名:端口:DatabaseName=库名
      • 1     /**
        2      * 访问数据库的地址
        3      */
        4     private final String URL = "jdbc:mysql://localhost:3306/test";

    3.创建数据库的链接

      • 连接数据库就要向java.sqlDriverManager请求过的Connection对象,一个Connection就代表一个数据库连接
      • 在连接的时候需要传入数据库的账户和密码
      • 1 Connection connection =
        DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");

    4.创建一个Statement

      • 获得数据库连接后,要想执行sql语句,必须获得java.sql.Statement实例,Statement实例分为三种
        • 执行静态的sql语句.通过Statement实例实现
        • 执行动态的sql语句.通过PreparedStatement实例实现
        • 执行数据库存储过程.通常通过CallableStatement实例实现
      • 1             //执行静态的sql
        2             Statement statement = connection.createStatement();
        3             ResultSet resultSet = statement.executeQuery("select * from sys_user");
        4             System.out.println(resultSet.toString());
        5             
        6             //执行动态的sql  采用预加载的方式 可防止sql注入
        7             PreparedStatement prepareStatement = connection.prepareStatement("select * from sys_user");

    5.执行sql语句

    • Statement提供了三种执行查询
      • ResultSet executeQuery(String sql);   执行查询数据库的sql语句,返回一个结果集(ResultSet)对象
      • int executeUpdate(String sql);  执行INSERT,UPDATE或者DELETE语句以及SQL DDL语句,返回受影响行数
      • execute(String sql); 用于返回多个结果集,多个更新计数或者二者组合的语句
      • 1             //执行查询
        2             ResultSet resultSet = statement.executeQuery("select * from sys_user");
        3             //执行insert update delete 
        4             statement.executeUpdate("INSERT INTO sys_user VALUES(5,'lisi','123','李四');");

    6.处理结果

    • 处理结果有两种情况
      • 返回本次操作的记录数 在执行executeUpdate();方法的时候会返回受影响的行数
      • 返回ResultSet对象  在执行executeQuery();方法的时候会返回对象 
    • ResultSet对象中包含SQL查询中出的所有行,通过get方法可以获取每行的数据
    • 1             //执行查询
      2             ResultSet resultSet = statement.executeQuery("select * from sys_user");
      3             while(resultSet.next()) {
      4                 System.out.println(resultSet.getInt("uid"));
      5                 System.out.println(resultSet.getString("username"));
      6                 System.out.println(resultSet.getString("password"));
      7                 System.out.println(resultSet.getString("nickname"));
      8             }

    7.关闭JDBC对象

    • 在使用完毕后需要关闭三个对象,关闭结果集(resultSet),关闭声明(Statement),关闭数据库连接(Connection)
    • 1             if (resultSet != null) { // 关闭记录集
      2                 resultSet.close();
      3             }
      4             if (statement != null) { // 关闭声明
      5                 statement.close();
      6             }
      7             if (connection != null) { // 关闭连接对象
      8                 connection.close();
      9             }

    我们可以把经常使用的方法封装成一个工具类,我们一般成为jdbcUtils,下面代码时从CSDNhttp://blog.csdn.net/harryweasley/article/details/45689023获取,大家可以自己借鉴修改,我就不再重复打出来了

      1 package com.jdbc.dbutils;  
      2   
      3 import java.sql.Connection;  
      4 import java.sql.DriverManager;  
      5 import java.sql.PreparedStatement;  
      6 import java.sql.ResultSet;  
      7 import java.sql.ResultSetMetaData;  
      8 import java.sql.SQLException;  
      9 import java.util.ArrayList;  
     10 import java.util.HashMap;  
     11 import java.util.List;  
     12 import java.util.Map;  
     13   
     14 public class JdbcUtils {  
     15     /** 
     16      * 数据库的用户名 
     17      */  
     18     private final String USER = "root";  
     19     /** 
     20      * 数据库的密码 
     21      */  
     22     private final String PASSWORD = "123456";  
     23     /** 
     24      * 数据库的驱动信息 
     25      */  
     26     private final String DRIVER = "com.mysql.jdbc.Driver";  
     27     /** 
     28      * 访问数据库的地址 
     29      */  
     30     private final String URL = "jdbc:mysql://localhost:3306/test";  
     31     /** 
     32      * 数据库的连接 
     33      */  
     34     Connection connection;  
     35     /** 
     36      * sql语句的执行对象 
     37      */  
     38     PreparedStatement preparedStatement;  
     39     /** 
     40      * 查询返回的结果集合 
     41      */  
     42     ResultSet resultSet;  
     43   
     44     public JdbcUtils() {  
     45         try {  
     46             Class.forName(DRIVER);  
     47             System.out.println("注册驱动成功");  
     48         } catch (ClassNotFoundException e) {  
     49             e.printStackTrace();  
     50         }  
     51     }  
     52   
     53     /** 
     54      * 连接数据库 
     55      *  
     56      * @return 数据库的连接对象 
     57      */  
     58     public Connection getConnection() {  
     59         try {  
     60             connection = DriverManager.getConnection(URL, USER, PASSWORD);  
     61         } catch (SQLException e) {  
     62             e.printStackTrace();  
     63         }  
     64         return connection;  
     65     }  
     66   
     67     /** 
     68      * 完成对数据库的表的添加删除和修改的操作 
     69      *  
     70      * @param sql 
     71      * @param params 
     72      * @return 
     73      * @throws SQLException 
     74      */  
     75     public boolean updateByPrepareStatement(String sql, List<Object> params)  
     76             throws SQLException {  
     77         boolean flag = false;  
     78         int result = -1;// 表示当用户执行添加删除和修改的时候所影响数据库的行数  
     79         // 创建一个 PreparedStatement 对象来将参数化的 sql 语句发送到数据库。  
     80         preparedStatement = connection.prepareStatement(sql);  
     81         int index = 1;  
     82         if (params != null && !params.isEmpty()) {  
     83             for (Object object : params) {  
     84                 // 使用给定对象设置指定参数的值。index从1开始  
     85                 preparedStatement.setObject(index++, object);  
     86             }  
     87         }  
     88         // 在此 PreparedStatement 对象中执行 SQL 语句,该语句必须是一个 SQL 数据操作语言语句,比如  
     89         // INSERT、UPDATE 或 DELETE 语句  
     90         result = preparedStatement.executeUpdate();  
     91         flag = result > 0 ? true : false;  
     92         return flag;  
     93   
     94     }  
     95   
     96     /** 
     97      * 查询返回单条记录 
     98      *  
     99      * @param sql 
    100      * @param params 
    101      * @return 
    102      * @throws SQLException 
    103      */  
    104     public Map<String, Object> findSimpleResult(String sql, List<Object> params)  
    105             throws SQLException {  
    106         Map<String, Object> map = new HashMap<String, Object>();  
    107         int index = 1;  
    108         // 创建一个 PreparedStatement 对象来将参数化的 sql 语句发送到数据库。  
    109         preparedStatement = connection.prepareStatement(sql);  
    110         if (params != null && !params.isEmpty()) {  
    111             for (Object object : params) {  
    112                 // 使用给定对象设置指定参数的值。index从1开始  
    113                 preparedStatement.setObject(index++, object);  
    114             }  
    115         }  
    116         // 在此 PreparedStatement 对象中执行 SQL 查询,并返回该查询生成的 ResultSet 对象。  
    117         resultSet = preparedStatement.executeQuery();  
    118         // 获取此 ResultSet 对象的列的编号、类型和属性。  
    119         ResultSetMetaData metaData = resultSet.getMetaData();  
    120         int col_len = metaData.getColumnCount();  
    121         while (resultSet.next()) {  
    122             for (int i = 0; i < col_len; i++) {  
    123                 // sql数据库列的下标是从1开始的  
    124                 String col_name = metaData.getColumnName(i + 1);  
    125                 Object col_value = resultSet.getObject(col_name);  
    126                 if (col_value == null) {  
    127                     col_value = "";  
    128                 }  
    129                 map.put(col_name, col_value);  
    130             }  
    131         }  
    132   
    133         return map;  
    134     }  
    135   
    136     public List<Map<String, Object>> findMoreResult(String sql,  
    137             List<Object> params) throws SQLException {  
    138         List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();  
    139         int index = 1;  
    140         // 创建一个 PreparedStatement 对象来将参数化的 sql 语句发送到数据库。  
    141         preparedStatement = connection.prepareStatement(sql);  
    142         if (params != null && !params.isEmpty()) {  
    143             for (Object object : params) {  
    144                 // 使用给定对象设置指定参数的值。index从1开始  
    145                 preparedStatement.setObject(index++, object);  
    146             }  
    147         }  
    148         // 在此 PreparedStatement 对象中执行 SQL 查询,并返回该查询生成的 ResultSet 对象。  
    149         resultSet = preparedStatement.executeQuery();  
    150         // 获取此 ResultSet 对象的列的编号、类型和属性。  
    151         ResultSetMetaData metaData = resultSet.getMetaData();  
    152         int col_len = metaData.getColumnCount();  
    153         while (resultSet.next()) {  
    154             Map<String, Object> map = new HashMap<String, Object>();  
    155             for (int i = 0; i < col_len; i++) {  
    156                 // sql数据库列的下标是从1开始的  
    157                 String col_name = metaData.getColumnName(i + 1);  
    158                 Object col_value = resultSet.getObject(col_name);  
    159                 if (col_value == null) {  
    160                     col_value = "";  
    161                 }  
    162                 map.put(col_name, col_value);  
    163             }  
    164             list.add(map);  
    165         }  
    166         return list;  
    167     }  
    168   
    169     /** 
    170      * 关闭数据库 
    171      *  
    172      * @throws SQLException 
    173      */  
    174     public void releaseConn() throws SQLException {  
    175         if (resultSet != null) {  
    176             resultSet.close();  
    177         }  
    178   
    179         if (preparedStatement != null) {  
    180             preparedStatement.close();  
    181         }  
    182         if (connection != null) {  
    183             connection.close();  
    184         }  
    185     }  
    186   
    187     static JdbcUtils jdbcUtils;  
    188   
    189     public static void main(String[] args) throws SQLException {  
    190         jdbcUtils = new JdbcUtils();  
    191         jdbcUtils.getConnection();  
    192         // insert();  
    193         // update();  
    194         // query();  
    195         Morequery();  
    196     }  
    197   
    198     private static void query() throws SQLException {  
    199         String sql = "select * from userinfo where pwd = ? ";  
    200         List<Object> params = new ArrayList<Object>();  
    201         params.add("123");  
    202         Map<String, Object> map = jdbcUtils.findSimpleResult(sql, params);  
    203         System.out.println(map);  
    204     }  
    205   
    206     private static void Morequery() throws SQLException {  
    207         String sql = "select * from userinfo  ";  
    208         List<Map<String, Object>> map = jdbcUtils.findMoreResult(sql, null);  
    209         System.out.println(map);  
    210     }  
    211   
    212     /** 
    213      * 更新数据库内容 
    214      *  
    215      * @throws SQLException 
    216      */  
    217     private static void update() throws SQLException {  
    218         String sql = "update userinfo set username =? where id=2";  
    219         List<Object> params = new ArrayList<Object>();  
    220         params.add("liumr");  
    221         jdbcUtils.updateByPrepareStatement(sql, params);  
    222     }  
    223   
    224     /** 
    225      * 增加数据 
    226      *  
    227      * @throws SQLException 
    228      */  
    229     private static void insert() throws SQLException {  
    230         String sql = "insert userinfo (username,pwd) values (?,?)";  
    231         List<Object> params = new ArrayList<Object>();  
    232         params.add("liugx");  
    233         params.add("456");  
    234         jdbcUtils.updateByPrepareStatement(sql, params);  
    235   
    236     }  
    237   
    238 }  
    View Code

    数据库连接池技术

    • 由于我们要对数据库频繁地进行操作,每进行一次连接操作就要获取一个conntection连接,每次使用完毕后要全部关闭资源,这样的话我们可以使用数据库连接池技术
    • 优点:
      • 资源重用:避免重复创建,释放连接,大量节约性能开销
      • 更快的响应:在连接池初始化的过程中,往往已经创建了若干数据库连接置于连接池中备用。此时连接的初始化工作均已完成。对于业务请求处理而言,直接利用现有可用连接,避免了数据库连接初始化和释放过程的时间开销,从而减少了系统的响应时间。
      • 新的资源分配手段: 对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接池的配置,实现某一应用最大可用数据库连接数的限制,避免某一应用独占所有的数据库资源
      • 统一的连接管理,避免数据库连接泄露:  在较为完善的数据库连接池实现中,可根据预先的占用超时设定,强制回收被占用连接,从而避免了常规数据库连接操作中可能出现的资源泄露。
    • 创建的数据库连接池
      • DBCP:由于性能问题,已经很少使用了
      • C3P0:目前在很多项目中都在使用
      • Druid(阿里巴巴):阿里巴巴开源的一个数据库连接池
    •  下面我们示范常用的C3p0的使用
      • 导入jar包c3p0-0.9.1.2.jar
      • 在项目src目录下新建c3p0.properties
        • 文件内容(当然还有很多其他配置,下面最简单配置)
        • c3p0.driverClass=com.mysql.jdbc.Driver
          c3p0.jdbcUrl=jdbc:mysql://localhost:3306/test
          c3p0.user=root
          c3p0.password=root
      • 在与数据库交互时
      • 1 //创建一个数据库连接池ComboPooledDataSource ds = new ComboPooledDataSource();
        2 //创建QueryRunner接口
        3 QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
        4 //通过接口可以执行查询或者更新,修改操作
        5   qr.update(sql); //返回受影响的行数
        6   qr.query(sql, null); //返回各种类型
      •  关于QueryRunner的query方法其实功能是很强大的,可以根据查询的内容自动封装各种类型
        • 封装入一个javaBean中
        • 1 public Category getById(String cid) throws Exception {
          2         QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
          3         String sql = "select * from category where cid = ?";
          4         return qr.query(sql, new BeanHandler<>(Category.class), cid);
          5     }
        • 封装成一个可以指定类型的list集合
        • 1 public List<Category> findAll() throws Exception {
          2         QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
          3         String sql = "select * from category";
          4         List<Category> list = qr.query(sql, new BeanListHandler<>(Category.class));
          5         return list;
          6     }
        • 返回单条数据
        •  1     /**
           2      * 查询数据总条数
           3      */
           4     @Override
           5     public Integer getTotalSize() throws Exception {
           6         // 创建查询接口
           7         QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
           8         String sql = "select count(*) from links";
           9         return ((Long) qr.query(sql, new ScalarHandler())).intValue();
          10     }
      • C3p0是在项目中是很详细的,详细的学习该请大家参考正式的文档
    杂家不如专家,精益求精
  • 相关阅读:
    jq 字符串去除空格
    wpf 加载资源文件
    wpf 寻找TreeView的子元素,并对其进行操作
    IIS发布MVC ASP.NET网站
    wpf Binding 小记录
    asp.net mvc表单异步提交
    把路径设置为全局变量
    MVC将服务器端的物理路径转换为服务器路径
    silverlight控件阴影效果示例
    NLP的12条前提假设
  • 原文地址:https://www.cnblogs.com/jimisun/p/7812756.html
Copyright © 2020-2023  润新知