首页 > 技术文章 > 使用JDBC程序的问题总结

benjieqiang 2019-07-14 11:19 原文

  1. 利用navicat,导入mybatis.sql,创建两个数据表order表和user表。

    SET FOREIGN_KEY_CHECKS=0;
    
    -- ----------------------------
    -- Table structure for `orders`
    -- ----------------------------
    DROP TABLE IF EXISTS `orders`;
    CREATE TABLE `orders` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `user_id` int(11) NOT NULL COMMENT '下单用户id',
      `number` varchar(32) NOT NULL COMMENT '订单号',
      `createtime` datetime NOT NULL COMMENT '创建订单时间',
      `note` varchar(100) DEFAULT NULL COMMENT '备注',
      PRIMARY KEY (`id`),
      KEY `FK_orders_1` (`user_id`),
      CONSTRAINT `FK_orders_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
    ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of orders
    -- ----------------------------
    INSERT INTO `orders` VALUES ('3', '1', '1000010', '2015-02-04 13:22:35', null);
    INSERT INTO `orders` VALUES ('4', '1', '1000011', '2015-02-03 13:22:41', null);
    INSERT INTO `orders` VALUES ('5', '10', '1000012', '2015-02-12 16:13:23', null);
    
    -- ----------------------------
    -- Table structure for `user`
    -- ----------------------------
    DROP TABLE IF EXISTS `user`;
    CREATE TABLE `user` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `username` varchar(32) NOT NULL COMMENT '用户名称',
      `birthday` date DEFAULT NULL COMMENT '生日',
      `sex` char(1) DEFAULT NULL COMMENT '性别',
      `address` varchar(256) DEFAULT NULL COMMENT '地址',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of user
    -- ----------------------------
    INSERT INTO `user` VALUES ('1', '王五', null, '2', null);
    INSERT INTO `user` VALUES ('10', '张三', '2014-07-10', '1', '北京市');
    INSERT INTO `user` VALUES ('16', '张小明', null, '1', '河南郑州');
    INSERT INTO `user` VALUES ('22', '陈小明', null, '1', '河南郑州');
    INSERT INTO `user` VALUES ('24', '张三丰', null, '1', '河南郑州');
    INSERT INTO `user` VALUES ('25', '陈小明', null, '1', '河南郑州');
    INSERT INTO `user` VALUES ('26', '王五', null, null, null);
    
  2. idea创建工程,导入驱动包mysql-connector-java-5.1.37-bin.jar到lib文件夹

  3. 7步使用jdbc

    1. 注册驱动(从 JDBC3 开始,目前已经普遍使用的版本。可以不用注册驱动而直接使用。故7步)
    2. 获取数据库连接对象 Connection
    3. 定义sql,?表示占位符
    4. 获取预处理statement(prepareStatement)
    5. 设置sql语句中的参数(使用preparedStatement)
    6. 执行sql,接受返回结果
    7. 处理结果
    8. 释放资源

代码如下:

import java.sql.*;

/**
 * @ClassName: JdbcTest
 * @author: benjamin
 * @version: 1.0
 * @description: TODO
 * @createTime: 2019/07/12/16:27
 */

public class JdbcTest {
    public static void main(String[] args) {
        //数据库连接
        Connection connection = null;
        //预编译的Statement,使用预编译的Statement提高数据库性能
        PreparedStatement preparedStatement = null;
        //结果集
        ResultSet resultSet = null;
        try {
            String url = "jdbc:mysql://192.168.214.128:3306/mybatis?characterEncoding=utf-8";
            //1. 通过驱动管理类获取数据库链接
            connection =  DriverManager.getConnection(url, "root", "ben123");
            //2. 定义sql语句 ?表示占位符
            String sql = "select * from user where username = ?";
            //3. 获取预处理statement(prepareStatement)
            preparedStatement = connection.prepareStatement(sql);
            //4. 设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
            preparedStatement.setString(1, "王五");
            //5. 向数据库发出sql执行查询,查询出结果集
            resultSet =  preparedStatement.executeQuery();
            //6. 执行结果(遍历查询结果集)
            while(resultSet.next()){
                System.out.println(resultSet.getString("id") + "  " + resultSet.getString("username"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            //7. 释放资源
            if(resultSet!=null){
                try {
                    // 先关闭resultSet
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(preparedStatement!=null){
                try {
                    //再关闭preparedStatement
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(connection!=null){
                try {
                    // 最后关闭connection
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

结果如下:

1 王五
26 王五

问题总结

  1. 数据库连接创建、释放频繁造成系统资源浪费,从而影响系统性能。如果使用数据库连接池可解决此问题。
  2. Sql语句在代码中硬编码,造成代码不易维护,实际应用中sql变化的可能较大,sql变动需要改变java代码。
  3. 使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。
  4. 对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便。

推荐阅读