创建一个以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中的对象和原型(一)(转载)

    面向对象的语言(如Java)中有类的概念,而通过类可以创建任意多个具有相同属性和方法的对象.但是,JavaScript 没有类的概念,因此它的对象也与基于类的语言中的对象有所不同. 要了解面向对象,首 ...

  2. ognl概念和原理详解

    一.问题的提出   在mvc中,数据是在各个层次之间进行流转是一个不争的事实.而这种流转,也就会面临一些困境,这些困境,是由于数据在不同世界中的表现形式不同而造成的: 1. 数据在页面上是一个扁平的, ...

  3. 每日英语:Air Pollution From Coal Use Cuts Lifespans in China, Study Shows

    Air pollution from coal combustion likely cut life expectancy in parts of China by more than five ye ...

  4. CSS学习笔记(7)--html页面的CSS、DIV命名规则

    html页面的CSS.DIV命名规则 CSS命名规则 头:header 内容:content/containe 尾:footer 导航:nav 侧栏:sidebar 栏目:column 页面外围控制整 ...

  5. 编写自己的代码库(javascript常用实例的实现与封装)

    https://segmentfault.com/a/1190000010225928

  6. saveFileDialog对话框

    private void button1_Click(object sender, EventArgs e) { saveFileDialog1.Filter = "*.txt|*.txt| ...

  7. Android——问题解决之adb not responding;adb不是内部或外部命令;path变量的默认值为多少

    adb not responding 恩,这是出现的问题.我们开始来解决它吧! 出现这种问题大多是因为adb端口被占用导致这个问题,所以只要找到占用端口号程序,结束即可!就是这么简单(adb运行端口号 ...

  8. oozie常见错误问题

    1.  Error: HTTP error code: 404 : Not Found 原因: 在环境变量中配置的OOZIE_URL有问题配置成了 export OOZIE_URL=http://dw ...

  9. 科技巨头们以 "A" 取名的时尚潮流

    科技巨头们以 "A" 取名的时尚潮流 from 公众号  WebHub  世界上有许多巨头公司喜欢以字母 a 打头作公司起名.改名,这主要是因为电话薄是以字母排序的(外国人习惯家里 ...

  10. 解决异常:Package should contain a content type part [M1.13]

    http://blog.csdn.net/llwan/article/details/8890190 ————————————————————————————————————————————————— ...