Java 学习笔记(十)JDBC数据库编程基础

5 篇文章 1 订阅

JDBC数据库编程


JDBC简介

JDBC(Java DataBase Connectivity)是访问数据库的标准规范,真正怎么操作数据库还需要具体的实现类,也就是数据库驱动,能够执行SQL语句。

使用 JDBC 开发使用到的包:

会使用到的包说明
java.sql所有与 JDBC 访问数据库相关的接口和类
javax.sql数据库扩展包,提供数据库额外的功能。如:连接池
数据库的驱动由各大数据库厂商提供,需要额外去下载,是对 JDBC 接口实现的类

JDBC 的核心 API

接口或类作用
DriverManager 1) 管理和注册数据库驱动2) 得到数据库连接对象
Connection 接口一个连接对象,可用于创建 Statement 和 PreparedStatement 以及CallableStatement对象
Statement 接口一个 SQL 语句对象,用于将 SQL 语句发送给数据库服务器。
PreparedStatemen 接口一个 SQL 语句对象,是 Statement 的子接口
ResultSet 接口

加载和注册驱动

加载和注册驱动的方法描述
Class.forName(数据库驱动实现类)加载和注册数据库驱动,数据库驱动由 mysql 厂商 "com.mysql.jdbc.Driver"
try {
        Class.forName("com.mysql.jdbc.Driver");		
        } catch (ClassNotFoundException e) { 				
            e.printStackTrace();
        }

注;Class.forName是把这个类加载到JVM中,加载的时候,就会执行其中的静态初始化块,完成驱动的初始化的相关工作

DriverManager类

DriverManager 作用:

  1. 管理和注册驱动;
  2. 创建数据库的连接;

DriverManager类中的方法:

DriverManager 类中的静态方法描述
Connection getConnection (String url, String user, String password)通过连接字符串,用户名,密码来得到数据 库的连接对象
Connection getConnection (String url, Properties info)通过连接字符串,属性对象来得到连接对象

使用 JDBC 连接数据库的四个参数:

JDBC 连接数据库的四个参数说明
用户名登录的用户名
密码登录的密码
连接字符串 URL不同的数据库 URL 是不同的,mysql 的写法jdbc:mysql://localhost:3306/数据库[?参数名=参数值]
驱动类的字符串名com.mysql.jdbc.Driver

连接数据库的 URL 地址格式:

协议名:子协议: //服务器名或 IP 地址:端口号/数据库名?参数=参数值

MySQL 中可以简写:

前提:必须是本地服务器,端口号是 3306

jdbc:mysql:///数据库名

乱码的处理

如果数据库出现乱码,可以指定参数: ?characterEncoding=utf8,表示让数据库以 UTF-8 编码来处理数据。

jdbc:mysql://localhost:3306/数据库?characterEncoding=utf8
jdbc:mysql://localhost:3306/pms?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false

案例:得到 MySQL 的数据库连接对象

  1. 使用用户名、密码、URL 得到连接对象

    package com.lqg;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    /**
    * 得到连接对象
    */
    public class Demo2 {
    public static void main(String[] args) throws SQLException {
    String url = "jdbc:mysql://localhost:3306/day24";
    //1) 使用用户名、密码、URL 得到连接对象
    Connection connection = DriverManager.getConnection(url, "root", "root");
    //com.mysql.jdbc.JDBC4Connection@68de145
    System.out.println(connection);
        }
    }
    
  2. 使用属性文件和 url 得到连接对象

    package com.lqg;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.util.Properties;
    public class Demo3 {
    public static void main(String[] args) throws SQLException {
    //url 连接字符串
    String url = "jdbc:mysql://localhost:3306/day24";
    //属性对象
    Properties info = new Properties();
    //把用户名和密码放在 info 对象中
    5 / 21info.setProperty("user","root");
    info.setProperty("password","root");
    Connection connection = DriverManager.getConnection(url, info);
    //com.mysql.jdbc.JDBC4Connection@68de145
    System.out.println(connection);
        }
    }
    

Conection接口

  1. Connection 作用:

    1. Connection 接口,具体的实现类由数据库的厂商实现,代表与特定数据库的连接。
  2. Connection 接口提供的方法

    Connection 接口中的方法描述
    createStatement()创建并返回一个Statement实例,通常执行无参的 SQL 语句对象
    prepareStatement()创建并返回一个PreparedStatement实例,通常执行有参的 SQL 语句对象
    prepareCall()创建并返回一个CallableStatement实例,通常执行有参的 SQL 语句对象

Statement接口

在数据库中JDBC访问数据库注常用的就是Statement接口来实现数据库访问;下面复习一下:

  1. JDBC访问数据库
    1)对象:
    ​ Driver接口
    ​ DriverManager类
    ​ Connection接口
    ​ Statement接口
    ​ PreparedStatement接口
    ​ CallableStatement接口
    ​ ResultSet接口
    2)JDBC访问数据库步骤:
    a.加载驱动
    ​ Class.forName("…");
    b.创建连接
    ​ DriverManager.getConnection(url,username,password);
    c.创建执行器,执行SQL语句
    ​ createStatement()
    ​ prepareStatement()
    ​ prepareCall()
    ​ executeQuery(),executeUpdate()
    d.返回结果集
    ​ ResultSet
    e.关闭连接
    ​ close()

  2. Statement 作用:

    1. 代表一条语句对象,用于发送 SQL 语句给服务器,用于执行静态 SQL 语句并返回它所生成结果的对象。
  3. Statement 接口提供的常用方法:

    Statement 接口中的方法描述
    int executeUpdate(String sql)用于发送 DML 语句,增删改的操作,insert、update delete参数:SQL 语句返回值:返回对数据库影响的行数
    ResultSet executeQuery(String sql)用于发送 DQL 语句,执行查询的操作。select参数:SQL 语句返回值:查询的结果集
  4. 释放资源

    1. 需要释放的对象:ResultSet 结果集,Statement 语句,Connection 连接
    2. 释放原则:先开的后关,后开的先关。ResultSet  Statement  Connection
    3. 放在哪个代码块中:finally 块

ResultSet 接口:

  1. 作用:封装数据库查询的结果集,对结果集进行遍历,取出每一条记录。

  2. 接口中的方法:

    ResultSet 接口中的方法描述
    boolean next()1) 游标向下移动 1 行2) 返回 boolean 类型,如果还有下一条记录,返回 true,否则返回 false
    数据类型 getXxx()1) 通过字段名,参数是 String 类型。返回不同的类型2) 通过列号,参数是整数,从 1 开始。返回不同的类型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3IpTj5VG-1600260710311)(E:\学习资料\实习实训\天津_软通培训\后端\java\图片\ResultSet.png)]

  1. 常用数据类型转换表

    SQL 类型Jdbc 对应方法返回类型
    BIT(1) bit(n)getBoolean()boolean
    TINYINTgetByte()byte
    SMALLINTgetShort()short
    INTgetInt()int
    BIGINTgetLong()long
    CHAR,VARCHARgetString()String
    Text(Clob) BlobgetClob getBlob()Clob Blob
    DATEgetDate()java.sql.Date 只代表日期
    TIMEgetTime()java.sql.Time 只表示时间
    TIMESTAMPgetTimestamp()java.sql.Timestamp 同时有日期和时间

    java.sql.Date、Time、Timestamp(时间戳),三个共同父类是:java.util.Date

代码:

db_mysql.properties文件内容

url=jdbc:mysql://localhost:3306/shuai
username=root //用户名
password=xiaoanshuai  //用户密码
package jdbc;

import java.io.File;
import java.io.FileInputStream;
import java.sql.*;
import java.util.Properties;

public class MyJDBCDemo {
    private static String url;
    private static String username;
    private static String password;

    public static void getParam(String filename) {
//        把数据库连接需要的URL username  password 放在一个文件中;
//        创建数据库连接需要的文件对象
        Properties properties = new Properties();
//       创建File文件
        File file = new File(filename);
//        读取文件内容
        FileInputStream fis = null;
        try {
//            读取文件内容
            fis = new FileInputStream(file);
//            加载获取文件内容
            properties.load(fis);
            url = properties.getProperty("url");
            username = properties.getProperty("username");
            password = properties.getProperty("password");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void getUser() {
        Connection con = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
//          1. 使用用户名、密码、URL 得到连接对象
            con = DriverManager.getConnection(url, username, password);

//          2. 通过连接对象得到语句对象
            stmt = con.createStatement();

//          3. 通过语句对象发送 SQL 语句给服务器
//          4. 执行 SQL
            rs = stmt.executeQuery("select * from table1");

//            获取数据库查询的内容;并输出在控制台;
            while (rs.next()) {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String password = rs.getString("password");
                System.out.println("id:  " + id + "  name:  " + name + "  password:  " + password);
            }
            rs.close();
            ;
            stmt.close();
            con.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static boolean login(int id, String password1) {
        boolean flag = false;
        Connection con = null;
        Statement stmt = null;
        ResultSet rs = null;

//          1. 使用用户名、密码、URL 得到连接对象
        try {
            con = DriverManager.getConnection(url, username, password);

//          2. 通过连接对象得到语句对象
            stmt = con.createStatement();
            String sql = "select * from user where id="+id+" and password="+password1;
            System.out.println("--------------------------");
            System.out.println(sql);
//          3. 通过语句对象发送 SQL 语句给服务器
//          4. 执行 SQL
            rs = stmt.executeQuery(sql);
            if (rs.next()) {
                flag = true;
                System.out.println(rs.getString("name"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }
    public static void main(String[] args) {
        // 参数  文件路径
        getParam("src/lib/db_mysql.properties");
        getUser();
        boolean flag=login(1,"123456");
        System.out.println(flag?"登录成功":"登录失败");
    }
}

结果:

id:  1  name:  admin  password:  123456
id:  2  name:  text  password:  123456
id:  3  name:  admin  password:  123456
id:  4  name:  text  password:  texe
--------------------------
select * from user where id=1 and password=123456
admin
登录成功

关于 ResultSet 接口中的注意事项:

  1. 如果光标在第一行之前,使用 rs.getXX()获取列值,报错:Before start of result set;
  2. 如果光标在最后一行之后,使用 rs.getXX()获取列值,报错:After end of result set;
  3. 使用完毕以后要关闭结果集 ResultSet,再关闭 Statement,再关闭 Connection

PreparedStatement接口

  1. PreparedStatement 是 Statement 接口的子接口,继承于父接口中所有的方法。它是一个预编译的 SQL 语句
  2. 因为有预先编译的功能,提高 SQL 的执行效率。
  3. 可以有效的防止 SQL 注入的问题,安全性更高。

Connection 创建 PreparedStatement 对象

Connection 接口中的方法描述
PreparedStatement prepareStatement(String sql)指定预编译的 SQL 语句,SQL 语句中使用占位符?创建一个语句对象

PreparedStatement 接口中的方法:

PreparedStatement 接口中的方法描述
int executeUpdate()执行 DML,增删改的操作,返回影响的行数。
ResultSet executeQuery()执行 DQL,查询的操作,返回结果集

PreparedSatement 的好处

  1. prepareStatement()会先将 SQL 语句发送给数据库预编译。PreparedStatement 会引用着预编译后的结果。可以多次传入不同的参数给 PreparedStatement 对象并执行。减少 SQL 编译次数,提高效率。
  2. 安全性更高,没有 SQL 注入的隐患。
  3. 提高了程序的可读性

使用 PreparedStatement 的步骤:

  1. 编写 SQL 语句,未知内容使用?占位:“SELECT * FROM user WHERE name=? AND password=?”;

  2. 获得 PreparedStatement 对象;

  3. 设置实际参数:setXxx(占位符的位置, 真实的值)

  4. 执行参数化 SQL 语句;

  5. 关闭资源

    PreparedStatement 中设置参数的方法描述
    void setDouble(int parameterIndex, double x)将指定参数设置为给定 Java double 值。
    void setFloat(int parameterIndex, float x)将指定参数设置为给定 Java REAL 值。
    void setInt(int parameterIndex, int x)将指定参数设置为给定 Java int 值。
    void setLong(int parameterIndex, long x)将指定参数设置为给定 Java long 值。
    void setObject(int parameterIndex, Object x)使用给定对象设置指定参数的值。
    void setString(int parameterIndex, String x)将指定参数设置为给定 Java String 值。
PreparedStatement ps=con.prepareStatement("select * from user where id>? and (name=? or password=?)") ;
ps.setInt(1,6);
ps.setString(2,"xiao");
ps.setObject(3,"shuai");
ResultSet rs=.executeQuery();

Statement 接口和PreparedStatement 接口的区别

  1. PreparedStatement 接口继承并扩展了Statement 接口;
  2. Statement 接口用来执行静态的SQL语句,PreparedStatement 接口用来执行动态的SQL语句;
  3. PreparedStatement 接口有效的防止 SQL 注入的问题,安全性更高;
  4. PreparedStatement 接口的实例在执行动态SQL语句时会进行预编译;

JDBCUtils 工具类

package jdbc;

import java.sql.*;
//创建一个数据库连接的工具类;
public class JDBCUtils {
    //    把数据库的URL、用户名、密码、驱动类 这几个字符串定义为常量;
    private static String url = "jdbc:mysql://localhost:3306/shuai";
    private static String username = "root";    //数据库用户名;
    private static String password = "xiaoanshuai"; //数据库密码;
    private static String driver = "com.mysql.jdbc.Driver"; //驱动

    //    注册驱动;
    static {//静态代码块,资源加载,只执行一次;
        try {
            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    //    创建数据库连接;
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url, username, password);
    }

    //    关闭打开的所有资源;
    public static void close(Connection con) {
        if (con != null) {
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
//  重载
    //    关闭打开的所有资源;
    public static void close(Connection con, Statement stm) {
        if (stm != null) {
            try {
                stm.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            if (con != null) {
                try {
                    con.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //  重载
    //关闭所有打开的资源(使用ResultSet接口)
    public static void close(Connection con, Statement stm, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (stm != null) {
            try {
                stm.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (con != null) {
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

API 介绍

Connection 接口中与事务有关的方法说明
void setAutoCommit(boolean autoCommit)参数是 true 或 false
如果设置为 false,表示关闭自动提交,相当于开启事务
void commit()提交事务
void rollback()回滚事务

批处理

package jdbc;

import oop.Demo1.Student;

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

//批处理;插入
public class JDBCInsert1 {
    public static void exerBatch() {
        String sql = "insert into account(name,money) values(?,?)";
        Connection con = null;
        PreparedStatement ps = null;
        try {
//            连接数据库
            con = JDBCUtils.getConnection();
//            创建一个数组长度为2;
            Student[] students = new Student[2];
//            声明一个对象 实例化对象;
            Student student1 = new Student("xiao", 400);
            Student student2 = new Student("shuai", 5000);
//           给数组赋值;
            students[0] = student1;
            students[1] = student2;
//            获取sql语句;
            ps = con.prepareStatement(sql);
//            清除Batch中的所有SQL语句;
            ps.clearBatch();
//            执行SQL语句,循环加入
            for (int i = 0; i < students.length; i++) {
                ps.setString(1, students[i].name);
                ps.setInt(2, students[i].age);
//                将指定的SQL命令添加到Batch中;
                ps.addBatch();
            }
//            执行Batch中的所有SQL命令,如果成功则返回有更新计数组成的数组;
            ps.executeBatch();
//            关闭资源
            ps.close();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(con);
        }
    }

    public static void main(String[] args) {
        JDBCInsert1.exerBatch();

    }
}

实例:使用事务管理模拟银行转账;

步骤:

  1. 得到对象连接
  2. 创建修改对象;
  3. 创建测试类

(1)得到对象连接

使用创建好的JDBCUtils 工具类

(2)创建修改对象;

package jdbc;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCUpdate1 {
    public static boolean updete1(String sql){
        Connection con=null;
        Statement stmt=null;
        try {
//            连接数据库
            con=JDBCUtils.getConnection();
//          通过连接对象得到语句对象
            stmt=con.createStatement();
//            通过语句对象发送 SQL 语句给服务器
//            执行 SQL
            int num=stmt.executeUpdate(sql);
            return num>0?true:false;
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }finally {
            JDBCUtils.close(con,stmt);
        }
    }

}

(3)创建测试类

package jdbc;

import org.junit.Test;
import java.sql.Connection;
import java.sql.SQLException;
public class AccountService {
    @Test
    public void transfer(){
        Connection con=null;
        try {
            con=JDBCUtils.getConnection();
            con.setAutoCommit(false);//开启事务;
            String sql="update account set money=money-100 where name='xiao'";
            JDBCUpdate1.updete1(sql);
            String sql2="update account set money=money+100 where name='an'";
            JDBCUpdate1.updete1(sql2);
            con.commit();//提交事务;
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.close(con);
        }
    }
}

参考博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

&芒果冰沙&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值