创建一个以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.加载驱动程序 mysql为例子
      try {
      Class.forName("com.mysql.jdbc.Driver");
      } catch (ClassNotFoundException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      System.out.println("加载驱动失败");
      }

2.提供JDBC连接的URL

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

3.创建数据库的链接

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

4.创建一个Statement

    • 获得数据库连接后,要想执行sql语句,必须获得java.sql.Statement实例,Statement实例分为三种

      • 执行静态的sql语句.通过Statement实例实现
      • 执行动态的sql语句.通过PreparedStatement实例实现
      • 执行数据库存储过程.通常通过CallableStatement实例实现
    •              //执行静态的sql
      Statement statement = connection.createStatement();
      ResultSet resultSet = statement.executeQuery("select * from sys_user");
      System.out.println(resultSet.toString()); //执行动态的sql 采用预加载的方式 可防止sql注入
      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); 用于返回多个结果集,多个更新计数或者二者组合的语句
    •              //执行查询
      ResultSet resultSet = statement.executeQuery("select * from sys_user");
      //执行insert update delete
      statement.executeUpdate("INSERT INTO sys_user VALUES(5,'lisi','123','李四');");

6.处理结果

  • 处理结果有两种情况

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

7.关闭JDBC对象

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

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

 package com.jdbc.dbutils;  

 import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class JdbcUtils {
/**
* 数据库的用户名
*/
private final String USER = "root";
/**
* 数据库的密码
*/
private final String PASSWORD = "123456";
/**
* 数据库的驱动信息
*/
private final String DRIVER = "com.mysql.jdbc.Driver";
/**
* 访问数据库的地址
*/
private final String URL = "jdbc:mysql://localhost:3306/test";
/**
* 数据库的连接
*/
Connection connection;
/**
* sql语句的执行对象
*/
PreparedStatement preparedStatement;
/**
* 查询返回的结果集合
*/
ResultSet resultSet; public JdbcUtils() {
try {
Class.forName(DRIVER);
System.out.println("注册驱动成功");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} /**
* 连接数据库
*
* @return 数据库的连接对象
*/
public Connection getConnection() {
try {
connection = DriverManager.getConnection(URL, USER, PASSWORD);
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
} /**
* 完成对数据库的表的添加删除和修改的操作
*
* @param sql
* @param params
* @return
* @throws SQLException
*/
public boolean updateByPrepareStatement(String sql, List<Object> params)
throws SQLException {
boolean flag = false;
int result = -1;// 表示当用户执行添加删除和修改的时候所影响数据库的行数
// 创建一个 PreparedStatement 对象来将参数化的 sql 语句发送到数据库。
preparedStatement = connection.prepareStatement(sql);
int index = 1;
if (params != null && !params.isEmpty()) {
for (Object object : params) {
// 使用给定对象设置指定参数的值。index从1开始
preparedStatement.setObject(index++, object);
}
}
// 在此 PreparedStatement 对象中执行 SQL 语句,该语句必须是一个 SQL 数据操作语言语句,比如
// INSERT、UPDATE 或 DELETE 语句
result = preparedStatement.executeUpdate();
flag = result > 0 ? true : false;
return flag; } /**
* 查询返回单条记录
*
* @param sql
* @param params
* @return
* @throws SQLException
*/
public Map<String, Object> findSimpleResult(String sql, List<Object> params)
throws SQLException {
Map<String, Object> map = new HashMap<String, Object>();
int index = 1;
// 创建一个 PreparedStatement 对象来将参数化的 sql 语句发送到数据库。
preparedStatement = connection.prepareStatement(sql);
if (params != null && !params.isEmpty()) {
for (Object object : params) {
// 使用给定对象设置指定参数的值。index从1开始
preparedStatement.setObject(index++, object);
}
}
// 在此 PreparedStatement 对象中执行 SQL 查询,并返回该查询生成的 ResultSet 对象。
resultSet = preparedStatement.executeQuery();
// 获取此 ResultSet 对象的列的编号、类型和属性。
ResultSetMetaData metaData = resultSet.getMetaData();
int col_len = metaData.getColumnCount();
while (resultSet.next()) {
for (int i = 0; i < col_len; i++) {
// sql数据库列的下标是从1开始的
String col_name = metaData.getColumnName(i + 1);
Object col_value = resultSet.getObject(col_name);
if (col_value == null) {
col_value = "";
}
map.put(col_name, col_value);
}
} return map;
} public List<Map<String, Object>> findMoreResult(String sql,
List<Object> params) throws SQLException {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
int index = 1;
// 创建一个 PreparedStatement 对象来将参数化的 sql 语句发送到数据库。
preparedStatement = connection.prepareStatement(sql);
if (params != null && !params.isEmpty()) {
for (Object object : params) {
// 使用给定对象设置指定参数的值。index从1开始
preparedStatement.setObject(index++, object);
}
}
// 在此 PreparedStatement 对象中执行 SQL 查询,并返回该查询生成的 ResultSet 对象。
resultSet = preparedStatement.executeQuery();
// 获取此 ResultSet 对象的列的编号、类型和属性。
ResultSetMetaData metaData = resultSet.getMetaData();
int col_len = metaData.getColumnCount();
while (resultSet.next()) {
Map<String, Object> map = new HashMap<String, Object>();
for (int i = 0; i < col_len; i++) {
// sql数据库列的下标是从1开始的
String col_name = metaData.getColumnName(i + 1);
Object col_value = resultSet.getObject(col_name);
if (col_value == null) {
col_value = "";
}
map.put(col_name, col_value);
}
list.add(map);
}
return list;
} /**
* 关闭数据库
*
* @throws SQLException
*/
public void releaseConn() throws SQLException {
if (resultSet != null) {
resultSet.close();
} if (preparedStatement != null) {
preparedStatement.close();
}
if (connection != null) {
connection.close();
}
} static JdbcUtils jdbcUtils; public static void main(String[] args) throws SQLException {
jdbcUtils = new JdbcUtils();
jdbcUtils.getConnection();
// insert();
// update();
// query();
Morequery();
} private static void query() throws SQLException {
String sql = "select * from userinfo where pwd = ? ";
List<Object> params = new ArrayList<Object>();
params.add("123");
Map<String, Object> map = jdbcUtils.findSimpleResult(sql, params);
System.out.println(map);
} private static void Morequery() throws SQLException {
String sql = "select * from userinfo ";
List<Map<String, Object>> map = jdbcUtils.findMoreResult(sql, null);
System.out.println(map);
} /**
* 更新数据库内容
*
* @throws SQLException
*/
private static void update() throws SQLException {
String sql = "update userinfo set username =? where id=2";
List<Object> params = new ArrayList<Object>();
params.add("liumr");
jdbcUtils.updateByPrepareStatement(sql, params);
} /**
* 增加数据
*
* @throws SQLException
*/
private static void insert() throws SQLException {
String sql = "insert userinfo (username,pwd) values (?,?)";
List<Object> params = new ArrayList<Object>();
params.add("liugx");
params.add("456");
jdbcUtils.updateByPrepareStatement(sql, params); } }

数据库连接池技术

  • 由于我们要对数据库频繁地进行操作,每进行一次连接操作就要获取一个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
    • 在与数据库交互时
    •  //创建一个数据库连接池ComboPooledDataSource ds = new ComboPooledDataSource();
      //创建QueryRunner接口
      QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
      //通过接口可以执行查询或者更新,修改操作
        qr.update(sql); //返回受影响的行数
        qr.query(sql, null); //返回各种类型
    • 关于QueryRunner的query方法其实功能是很强大的,可以根据查询的内容自动封装各种类型

      • 封装入一个javaBean中
      •  public Category getById(String cid) throws Exception {
        QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "select * from category where cid = ?";
        return qr.query(sql, new BeanHandler<>(Category.class), cid);
        }
      • 封装成一个可以指定类型的list集合
      •  public List<Category> findAll() throws Exception {
        QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "select * from category";
        List<Category> list = qr.query(sql, new BeanListHandler<>(Category.class));
        return list;
        }
      • 返回单条数据
      •      /**
        * 查询数据总条数
        */
        @Override
        public Integer getTotalSize() throws Exception {
        // 创建查询接口
        QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "select count(*) from links";
        return ((Long) qr.query(sql, new ScalarHandler())).intValue();
        }
    • C3p0是在项目中是很详细的,详细的学习该请大家参考正式的文档

厚积薄发系列之JDBC详解的更多相关文章

  1. JDBC详解系列(二)之加载驱动

    ---[来自我的CSDN博客](http://blog.csdn.net/weixin_37139197/article/details/78838091)---   在JDBC详解系列(一)之流程中 ...

  2. JDBC详解系列(三)之建立连接(DriverManager.getConnection)

      在JDBC详解系列(一)之流程中,我将数据库的连接分解成了六个步骤. JDBC流程: 第一步:加载Driver类,注册数据库驱动: 第二步:通过DriverManager,使用url,用户名和密码 ...

  3. JDBC详解1

    JDBC详解1 JDBC整体思维导图 JDBC入门 导jar包:驱动! 加载驱动类:Class.forName("类名"); 给出url.username.password,其中u ...

  4. Spring4 JDBC详解

    Spring4 JDBC详解 在之前的Spring4 IOC详解 的文章中,并没有介绍使用外部属性的知识点.现在利用配置c3p0连接池的契机来一起学习.本章内容主要有两个部分:配置c3p0(重点)和 ...

  5. JDBC详解(一)

    一.相关概念介绍 1.1.数据库驱动 这里驱动的概念和平时听到的那种驱动的概念是一样的,比如平时购买的声卡,网卡直接插到计算机上面是不能用的,必须要安装相应的驱动程序之后才能够使用声卡和网卡,同样道理 ...

  6. Java基础-面向接口编程-JDBC详解

    Java基础-面向接口编程-JDBC详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.JDBC概念和数据库驱动程序 JDBC(Java Data Base Connectiv ...

  7. nginx高性能WEB服务器系列之四配置文件详解

    nginx系列友情链接:nginx高性能WEB服务器系列之一简介及安装https://www.cnblogs.com/maxtgood/p/9597596.htmlnginx高性能WEB服务器系列之二 ...

  8. mongo 3.4分片集群系列之六:详解配置数据库

    这个系列大致想跟大家分享以下篇章: 1.mongo 3.4分片集群系列之一:浅谈分片集群 2.mongo 3.4分片集群系列之二:搭建分片集群--哈希分片 3.mongo 3.4分片集群系列之三:搭建 ...

  9. mongo 3.4分片集群系列之五:详解平衡器

    这个系列大致想跟大家分享以下篇章: 1.mongo 3.4分片集群系列之一:浅谈分片集群 2.mongo 3.4分片集群系列之二:搭建分片集群--哈希分片 3.mongo 3.4分片集群系列之三:搭建 ...

随机推荐

  1. Javascript中的对象和原型(三)(转载)

    在Javascript中的对象和原型(二)中我们提到,用构造函数创建的对象里面,每个对象之间都是独立的,这样就会降低系统资源的利用率,解决这样问题,我们就要用到下面提到的原型对象. 一 原型对象 原型 ...

  2. chrome 浏览器插件开发

    一.chrome 浏览器插件开发是什么: 1 从技术上说插件只是一个存在于本地的一个网站.所以呢在插件开发的过程中用到的技术无非是 javascript .html .css . 二.把当前活动页面的 ...

  3. Nginx 使用中文URL,中文目录路径

    Nginx 使用中文URL,中文目录路径 分类: linux2012-05-03 11:04 2672人阅读 评论(0) 收藏 举报 nginxurl服务器translationcentosserve ...

  4. ISTQB测试人员认证 初级(基础级)大纲

    ISTQB测试人员认证 初级(基础级)大纲 ---中文修订版本1(2015年5月6日) 2015-06-22 大纲pdf下载  ISTQB资料中心 在课程大纲中,每个章节都会提供相应的认知水平要求: ...

  5. ssm开发系的统架构图

  6. 结构体内重载小于号< 及构造函数

    struct Node { int d, e; bool operator < (const Node x) const { return x.d < d; } Node(int d, i ...

  7. CSS学习笔记(10)--nth-child和nth-of-type

    CSS3 :nth-child() 选择器 规定属于其父元素的第二个子元素的每个 p 的背景色: p:nth-child(2) CSS3 :nth-of-type() 选择器 规定属于其父元素的第二个 ...

  8. Git中保存用户名和密码

    每次操作都需要输入用户名和密码感觉很繁琐,解决方法,在本地的工程文件夹的.git下打开config文件添加: [credential]     helper = store 再输入一次用户名密码后就可 ...

  9. scala Wordcount

    package my.bigdata.scala08 import scala.collection.mutableimport scala.collection.mutable.ArrayBuffe ...

  10. 使用jsonp处理跨域问题

    调用web接口,get请求,发现提示:No 'Access-Control-Allow-Origin' header is present on the requested resource. 这个和 ...