Java入门系列-26-JDBC

认识 JDBC

JDBC (Java DataBase Connectivity) 是 Java 数据库链接技术的简称,用于链接经常使用数据库。java

Sun 公司提供了 JDBC API ,供程序员调用接口和类,集成在 java.sqljavax.sql 包中。mysql

Sun 公司还提供了 DriverManager 类用来管理各类不一样的JDBC驱动。程序员

不一样数据库厂商提供各自的JDBC驱动,因此咱们想要链接数据库除了要了解 JDBC API 还须要下载各数据库厂商的驱动 jar 包。sql

JDBC API

JDBC API主要用于与数据库创建链接、执行SQL语句、处理结果,其中核心类和接口以下:数据库

  • DriverManager:依据数据库的不一样,管理JDBC驱动
  • Connection:负责链接数据库并担任传送数据的任务
  • Statement:由 Connection 产生、负责执行SQL语句
  • ResultSet:负责保存 Statement 执行后所产生的查询结果

JDBC 编码模板

一、与数据库创建链接并获取链接api

Connection connection=DriverManager.getConnection(URL,数据库用户名,密码);

二、发送SQL语句,获得执行结果编码

Statement stmt=connection.createStatement();
ResultSet rs=stmt.executeQuery(SQL语句);

三、处理返回结果url

while(rs.next()){
    int a=rs.getInt("a");
    String b=rs.getString("b");
    Date d=rs.getDate("d");
    ……
}

四、释放资源code

rs.close();
stmt.close();
connection.close();

使用 JDBC 链接到 MySQL 数据库

本例适合已经会使用 MySQL 数据库的同窗,首先咱们下载 JDBC 的驱动 jar 包。这个网址提供了 MySQL 各类语言链接数据库的驱动 https://www.mysql.com/products/connector/,MySQL Connector / J 8.0与从MySQL 5.5开始的全部MySQL版本兼容。
8.0下载地址
下载完成后解压,后将jar添加依赖到项目中。server

链接到MySQL数据库

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

public class DemoConnectMySQL {
    public static void main(String[] args) {
        //链接MySQL的URL
        String url="jdbc:mysql://localhost:3306/mysql?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false";
        //MySQL数据库用户名
        String user="root";
        //MySQL数据库的密码
        String password="1234";
        Connection connection=null;
        try {
            connection=DriverManager.getConnection(url, user, password);
            System.out.println("链接成功");
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            try {
                connection.close();
                System.out.println("链接关闭");
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

url指定数据库的链接字符串,格式为:
jdbc:数据库://ip或域名:端口号?参数&参数……
这里的参数 useUnicode=true 使用Unicode字符,characterEncoding=utf8 设置编码防止中文乱码,serverTimezone=UTC 设置时区,useSSL=false 不使用SSL

jdbc4.0不须要加载驱动

PreparedStatement 增删改

PreparedStatement 继承了 Statement 接口,表示预编译的 SQL 语句对象,SQL 语句被预编译并存储在 PreparedStatement 对象中,可使用此对象屡次高效地执行该语句。(还避免了 SQL 注入的隐患)

先准备好数据库 books

表 book

字段 类型 属性
id 整数 主键,自增
bName 字符串 非空
price 小数 非空

脚本也准备好了

#建立数据库
CREATE DATABASE books;
USE books;
#建立表
CREATE TABLE book ( 
    id INT primary key  auto_increment, 
    bName VARCHAR ( 255 ) NOT NULL, 
    price FLOAT NOT NULL 
);

PreparedStatement添加数据

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

public class TestInsert {

    public static void main(String[] args) {
        Connection connection=null;
        PreparedStatement pstmt=null;
        String url="jdbc:mysql://localhost:3306/books?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false";
        String user="root";
        String password="1234";
        try {
            connection=DriverManager.getConnection(url,user,password);
            //sql语句
            String sql="insert into book(bName,price) values (?,?)";
            pstmt=connection.prepareStatement(sql);
            //传入参数
            pstmt.setString(1, "《java入门到改行》");
            pstmt.setFloat(2, 11.11f);
            int result=pstmt.executeUpdate();
            System.out.println("受影响行数:"+result);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            if (pstmt!=null) {
                try {
                    pstmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (connection!=null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

说明:

一、链接字符串要修改数据库名字为 books

String url="jdbc:mysql://localhost:3306/books?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false";

二、插入数据库的数据不能拼接而是要用 ? 代替

String sql="insert into book(bName,price) values (?,?)";

三、? 代替的参数要经过 set类型(位置,值) 传入

pstmt.setString(1, "《java入门到改行》");
pstmt.setFloat(2, 11.11f);

pstmt.setXxx()的位置从 1 开始!

四、增删改的SQL语句都使用这个方法,返回受影响行数

int result=pstmt.executeUpdate();

删除数据

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

public class TestDelete {

    public static void main(String[] args) {
        Connection connection=null;
        PreparedStatement pstmt=null;
        String url="jdbc:mysql://localhost:3306/books?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false";
        String user="root";
        String password="1234";
        try {
            connection=DriverManager.getConnection(url,user,password);
            //sql语句
            String sql="delete from book where id=?";
            pstmt=connection.prepareStatement(sql);
            //传入参数 要删除id
            pstmt.setInt(1, 1);
            int result=pstmt.executeUpdate();
            System.out.println("受影响行数:"+result);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            if (pstmt!=null) {
                try {
                    pstmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (connection!=null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

修改数据

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

public class TestUpdate {

    public static void main(String[] args) {
        Connection connection=null;
        PreparedStatement pstmt=null;
        String url="jdbc:mysql://localhost:3306/books?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false";
        String user="root";
        String password="1234";
        try {
            connection=DriverManager.getConnection(url,user,password);
            //sql语句
            String sql="update book set bName=?,price=? where id=?";
            pstmt=connection.prepareStatement(sql);
            //传入参数 要删除id
            pstmt.setString(1, "《MySQL从删库到跑路》");
            pstmt.setFloat(2, 16.66f);
            pstmt.setInt(3, 2);
            int result=pstmt.executeUpdate();
            System.out.println("受影响行数:"+result);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            if (pstmt!=null) {
                try {
                    pstmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (connection!=null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

增、删、改操做的写法都同样,都调用 executeUpdate() 方法返回一个受影响行数,惟一不一样的 SQL语句。

PreparedStatement 查询数据

查询数据须要用到 ResultSet 类保存返回的结果集,咱们获取数据要操做 ResultSet 获取。

ResultSet 经常使用方法

方法名 说明
boolean next() 将游标从当前位置向下移动一行
void close() 关闭 ResultSet 对象
int getInt(int colIndex) 以int形式获取结果集当前行指定列号值
int getInt(String colLabel) 以int形式获取结果集当前行指定列名值
float getFloat(String colLabel) 以float形式获取结果集当前行指定列名值
String getString(String colLabel) 以 String 形式获取结果集当前行指定列名值
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class TestSelect {

    public static void main(String[] args) {
        Connection connection=null;
        PreparedStatement pstmt=null;
        ResultSet rs=null;
        String url="jdbc:mysql://localhost:3306/books?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false";
        String user="root";
        String password="1234";
        try {
            connection=DriverManager.getConnection(url,user,password);
            //sql语句
            String sql="select bName,price,id from book where id=?";
            pstmt=connection.prepareStatement(sql);
            //传入查询条件
            pstmt.setInt(1, 2);
            rs=pstmt.executeQuery();
            while(rs.next()) {
                //经过列名获取列的值
                int id=rs.getInt("id");
                //经过位置获取列的值
                String bName=rs.getString(1);
                float price=rs.getFloat("price");
                System.out.println(id+" "+bName+" "+price);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            if(rs!=null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (pstmt!=null) {
                try {
                    pstmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (connection!=null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

关闭对象时注意关闭的顺序,后使用的先关闭:rs.close()->pstmt.close()->connection.close()

ResultSet 对象存在一个光标,光标所指行为当前行。想要获取列的数据须要先指向一行,因此要先指定 next() 方法用于指向一行,若是没有数据next()方法返回false,有数据返回true。

使用 getXxx() 方法获取列的数据时建议写列名,这样好识别

相关文章
相关标签/搜索