Java康复性训练-JDBC

2016/7/16 posted in  Java  

什么是JDBC

JDBC(Java Data Base Connectivity,Java数据库链接)是一种用于执行SQL语句的Java API。可以为多种关系数据库提供统一的访问,它由一组Java语言编写的类和接口组成。JDBC提供了一种标准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。

JDBC原理

JDBC原理:JDBC是以前SUN公司定义的一套访问数据库的接口(没有具体实现),具体实现是由各大数据库厂商自己实现的。每个数据库厂商都有自己的JDBC实现,也被称为JDBC驱动实现类。Java应用程序连接指定数据库,需要使用厂家提供的JDBC驱动才能连接。

JDBC链接数据库步骤

  1. 加载驱动
  2. 链接数据库
  3. 使用语句操作数据库
  4. 关闭数据库,释放资源

在项目中配置数据库驱动(Eclipse)

右击项目->Build Path->Configure Build Path-> Add External JARS

加载JDBC驱动

MySQL JDBC 驱动名称:com.mysql.jdbc.Driver
加载方式:Class.forName("驱动名");

连接及关闭数据库

  1. DriverManager 驱动管理类,主要负责一个数据的连接。static Connection getConnection(String url, String user, String password)试图建立到给定数据库 URL 的连接。

  2. Mysql 数据的连接地址格式:

    • jdbc:mysql://127.0.0.1:3306/DataBaseName
    • jdbc协议:JDBC URL 中的协议总是jdbc
    • 子协议: 驱动程序名称或数据库连接机制(这种驱动可由一个或多个驱动程序支持)的名称如:mysql
    • 子名称:一种标示数据库的方法。必须遵循//主机名:端口/数据库的标准URL命名约定,如://localhost:3306/test
  3. Connection接口:与特定的数据库的连接(也称为会话)。

    • void close()立即释放此Connection对象的数据库和JDBC资源,而不是等待自动释放

Demo Code

封装一个用于获取和关闭连接的工具类DBTool。

package com.swu.JDBC;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DBTool {
    public static Connection getConnection(){
        String dbURL = "jdbc:mysql://localhost:3306/test";
        String username = "root";
        String password = "";
        Connection conn = null;
        try {
            //注册驱动类
            Class.forName("com.mysql.jdbc.Driver");
            //获取连接
            conn = DriverManager.getConnection(dbURL,username,password);
            
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            System.out.println("加载驱动失败");
            e.printStackTrace();
        } catch (SQLException e) {
            System.out.println("连接失败");
            e.printStackTrace();
        }
        return conn;
    }
    public static void closeConnection(Connection conn){
        try {
            conn.close();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            System.out.println("关闭失败");
            e.printStackTrace();
        }
    }
}

使用Statement接口实现数据的增、删、改、查

Statement接口

  • 作用:用于执行静态SQL语句并返回它所产生的结果的对象。
  • int executeUpdate(String sql) 执行给定SQL语句。该语句可能为INSERT,UPDATE,DELETE语句或者不返回人格内容的SQL语句。
  • void close() 立即释放此Statement对象的数据库和JDBC资源,而不是等待对象自动关闭时发生此操作。

Statement接口实现添加数据操作

demo如下:

public void addUser(String username,String password){
        Connection conn = DBTool.getConnection();
        String sql = "insert into user(username,password) values('"+username+"','"+password+"')";
        Statement stmt = null;
        try {
            //通过Connection获取Statement
            stmt = conn.createStatement();
            int result = stmt.executeUpdate(sql);
            System.out.println(result);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            try {
                stmt.close();
                DBTool.closeConnection(conn);
            } catch (SQLException e) {
                e.printStackTrace();
            }
            
        }
    }

Statement接口实现修改数据操作

demo如下:

    public void updateUser(int id,String username,String password){
        Connection conn = DBTool.getConnection();
        String sql = "update user set username='"+username+"',password='"+password+"' where id="+id;
        Statement stmt = null;
        try {
            //通过Connection获取Statement
            stmt = conn.createStatement();
            int result = stmt.executeUpdate(sql);
            System.out.println(result);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            try {
                stmt.close();
                DBTool.closeConnection(conn);
            } catch (SQLException e) {              e.printStackTrace();
            }
            
        }
    }

Statement接口实现删除数据操作

demo如下:

    public void deleteUser(int id){
        Connection conn = DBTool.getConnection();
        String sql = "delete from user where id="+id;
        Statement stmt = null;
        try {
            //通过Connection获取Statement
            stmt = conn.createStatement();
            int result = stmt.executeUpdate(sql);
            System.out.println(result);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            try {
                stmt.close();
                DBTool.closeConnection(conn);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

Statment接口实现数据查询

demo如下(里面的ResultSet后面详细介绍):

public void getAllUser(){
        Connection conn = DBTool.getConnection();
        String sql = "select * from user";
        Statement stmt = null;
        //保存查询返回结果
        ResultSet rs = null;
        try {
            stmt = conn.createStatement();
            rs = stmt.executeQuery(sql);
            while(rs.next()){
                System.out.println(rs.getInt(1)+"\t"+rs.getString(2)+"\t"+rs.getString(3));
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            try {
                rs.close();
                stmt.close();
                conn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
}

PreparedStatement接口

PreparedStatement是Statement的子接口,是一个SQL语句预处理Statement。与直接Statement不同的是PreparedStatement在操作时,是先在数据表中准备好了一条SQL语句,但是此SQL语句的内容暂时不设置,而是之后再进行设置。实际开发过程中建议使用PreparedStatement,可以避免一定的SQL注入问题

PreparedStatement接口实现数据添加

demo如下:

    public void addUser(String username,String password) throws Exception{
        //预处理SQL语句
        String sql = "insert into user(username,password) values(?,?)";
        Connection conn = DBTool.getConnection();
        //获得PreparedStatement对象
        PreparedStatement stmt = conn.prepareStatement(sql);
        //设置预处理占位符的实际值
        stmt.setString(1, username);
        stmt.setString(2, password);
        //执行添加
        stmt.executeUpdate();
        
        DBTool.closeConnection(stmt, conn);
    }

PreparedStatement接口实现数据修改

demo如下:

    public void updateUser(int id,String username,String password) throws SQLException{
        String sql = "update user set username=?,password=? where id=?";
        Connection conn = DBTool.getConnection();
        PreparedStatement stmt = conn.prepareStatement(sql);
        
        stmt.setString(1, username);
        stmt.setString(2, password);
        stmt.setInt(3, id);
        
        stmt.executeUpdate();
        
        DBTool.closeConnection(stmt, conn);
        
    }

PreparedStatement接口实现数据删除

demo如下:

    public void deleteUser(int id) throws SQLException{
        String sql = "delete from user where id = ?";
        Connection conn = DBTool.getConnection();
        PreparedStatement stmt = conn.prepareStatement(sql);
        
        stmt.setInt(1, id);
    
        stmt.executeUpdate();
        
        DBTool.closeConnection(stmt, conn);
    }

PreparedStatement接口实现数据查询

demo如下:

    public void getUserByUsername(String username) throws SQLException{
        String sql = "select * from user where username=?";
        Connection conn = DBTool.getConnection();
        PreparedStatement stmt = conn.prepareStatement(sql);
        
        stmt.setString(1, username);
    
        ResultSet rs = stmt.executeQuery();
        
        while(rs.next()){
            System.out.println(rs.getInt(1)+"\t"+rs.getString(2)+"\t"+rs.getString(3));
        }
        
        DBTool.closeConnection(stmt, conn);
    }

ResultSet结果集

当我们对数据库的数据进行查询的时候,返回的是一个二维的结果集。我们这个时候需要使用ResultSet来遍历结果集,获取每一行的数据。

获取数据

  • boolean next()将光标从当前位置向前移动一行
  • String getString(int columnIndex)以String的形式获取此ResultSet对象的当前行中指定列的值。
  • String getString(String columnLabel)以String的形式获取此ResultSet对象的当前行中指定列的值。

使用例子

见上方实现的数据查询。

处理大数据对象

大数据对象处理主要有CLOB(character large object)和BLOB(binary large object)两种类型的字段。在CLOB中可以存储大字符数据对象,比如长篇小说;在BLOB中可以存放二进制大数据对象,比如图片、电影、音乐

处理CLOB数据

  • 使用PreparedStatement插入数据。statement.setAsciiStream(parameterIndex, x, length);
  • 使用ResultSet读取数据。resultSet.getClob(String columnLabel);获得一个Clob对象,然后可以转为字符串对象。

处理BLOB数据

  • 使用PreparedStatement插入数据。statement.setBinaryStream(parameterIndex, x, length);
  • 使用ResultSet读取数据。resultSet.getBlob(String columnLabel);获得一个Blob对象,然后可以转为目标对象。

使用CallableStatement接口调用存储过程

CallableStatement 主要是调用数据库中的存储过程,CallableStatement 也是 Statement 接口的子接口。在使用 CallableStatement 时可以接收存储过程的返回值。

使用DatabaseMetaData分析数据库

DatabaseMetaData可以得到数据库的一些基本信息,包括数据库的名称、版本,以及得到表的信息。

  • String getDatabaseProductName() 获取此数据库产品的名称。
  • int getDriverMajorVersion()获取此 JDBC 驱动程序的主版本号。
  • int getDriverMinorVersion() 获取此 JDBC 驱动程序的次版本号。

使用 ResultSetMetaData 获取 ResultSet 对象中的信息

ResultSetMetaData 可获取关于 ResultSet 对象中列的基本信息;

  • int getColumnCount() 返回此 ResultSet 对象中的列数。
  • String getColumnName(int column) 获取指定列的名称。