通过Java访问数据库---JDBC

一、JDBC概述

JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成,是Java访问数据库的标准规范,具体的实现由各大数据库厂商来实现。即真正怎么操作数据库还需要具体的实现类,也就是数据库驱动。每个数据库厂商根据自家数据库的通信格式编写好自己数据库的驱动。所以我们只需要会调用 JDBC 接口中的方法即可,数据库驱动由数据库厂商提供

我使用的是mysql的驱动mysql-connector-java-5.1.37-bin.jar

链接:https://pan.baidu.com/s/1HDQFZIL7MGfjOFdqZBIQ0A 
提取码:ab4d

导入jar包过程:

使用 JDBC 的好处:

  1. 程序员如果要开发访问数据库的程序,只需要会调用 JDBC 接口中的方法即可,不用关注类是如何实现的。

    2.  使用同一套 Java 代码,进行少量的修改就可以访问其他 JDBC 支持的数据库。

使用JDBC开发时可能使用的包:

会使用到的包 说明

java.sql

所有与 JDBC 访问数据库相关的接口和类

javax.sql

数据库扩展包,提供数据库额外的功能。如:连接池

数据库的驱动

由各大数据库厂商提供,需要额外去下载,是对 JDBC 接口实现的类

即mysql-connector-java-5.1.37-bin.jar

JDBC 的核心 API

接口或类 作用

DriverManager

  1. 管理和注册数据库驱动
  2. 得到数据库连接对象

Connection 接口

一个连接对象,可用于创建 Statement 和 PreparedStatement 对象

Statement 接口

一个 SQL 语句对象,用于将 SQL 语句发送给数据库服务器。

PreparedStatement 接口

一个 SQL 语句对象,是 Statement 的子接口

ResultSet 接口

用于封装数据库查询的结果集,返回给客户端 Java 程序

二、JDBC实现

JDBC 访问数据库的步骤:

  1. 注册和加载驱动(可以省略)
  2. 获取连接DriverManager.getConnection(url,user,password)
  3. Connection 获取 Statement 对象connection.createStatement()/perpareStatement()
  4. 使用 Statement / perparedStatement 对象执行 SQL 语句
  5. 返回结果集
  6. 释放资源(关闭ResultSet结果集、connection连接和statement语句)
  7. 释放原则:先开的后关,后开的先关。ResultSet-->Statement-->Connection
  8. 放在哪个代码块中:finally 块

1. 导入驱动jar包:

https://blog.csdn.net/krismile__qh/article/details/89305380*

*2. 加载和注册驱动:(注:从 JDBC3 开始,目前已经普遍使用的版本。可以不用注册驱动而直接使用。Class.forName 这句话可以省略。)

加载和注册驱动的方法 描述

Class.forName(数据库驱动实现类)

加载和注册数据库驱动,数据库驱动由 mysql 厂商提供

"com.mysql.jdbc.Driver"说明是com.mysql.jdbc包下的Driver接口

Driver 接口,所有数据库厂商必须实现的接口,表示这是一个驱动类

public class Demo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        //抛出类找不到的异常,注册数据库驱动
        Class.forName("com.mysql.jdbc.Driver");
        //固定写法
    }
}

3. 获得连接:DriverManager类

(作用:管理和注册驱动、创建数据库的连接)

1. DriverManager类中的方法:

DriverManager 类中的静态方法 描述

Connection getConnection (String url, String user, String password)

通过连接字符串,用户名,密码来得到数据

库的连接对象

Connection getConnection (String url, Properties info)

通过连接字符串,属性对象来得到连接对象

2. 通过用户名、密码、URL得到连接对象

代码:Connection con = DriverManager.getConnection(“jdbc:mysql://localhost:3306/mydb”,”root”,”root”);

其中三个参数分别表示:url 需要连接数据库的位置(网址) user用户名  password 密码

url比较复杂,例如mysql的url:jdbc:mysql://localhost:3306/mydb

 

JDBC规定url的格式由三部分组成,每个部分中间使用冒号分隔。

1.第一部分是jdbc,这是固定的;

2.第二部分是数据库名称,那么连接mysql数据库,第二部分当然是mysql了;

3.第三部分是由数据库厂商规定的,我们需要了解每个数据库厂商的要求,mysql的第三部分分别由数据库服务器的IP地址(localhost)、端口号(3306),以及DATABASE名称(mydb)组成。

3. 使用属性文件和 url 得到连接对象

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

4. 获得语句执行平台:Connection 接口

(具体的实现类由数据库的厂商实现,代表一个连接对象)

1. Connection接口下的方法:

Statement接口:

(代表一条语句对象,用于发送 SQL 语句给服务器,用于执行静态 SQL 语句并返回它所执行成结果的对象。)

String sql = "某SQL语句";

获取Statement语句执行平台:Statement stmt = connection.createStatement();

常用方法:

  1. int executeUpdate(String sql); --执行insert update delete语句.
  2. ResultSet executeQuery(String sql); --执行select语句.
  3. boolean execute(String sql); --执行select查询出结果集返回true 执行其他的语句返回false.

处理结果集:ResultSet接口

(封装数据库查询的结果集,对结果集进行遍历,取出每一条记录)

常用方法:

ResultSet 接口中的方法 描述

boolean next()

  1. 游标向下移动 1 行
  2. 返回 boolean 类型,如果还有下一条记录,返回 true,否则返回 false

数据类型 getXxx()

  1. 通过字段名,参数是 String 类型。返回不同的类型
  2. 通过列号,参数是整数,从 1 开始。返回不同的类型

常用数据类型转换表:

SQL 类型 Jdbc 对应方法 返回类型

BIT(1) bit(n)

getBoolean()

boolean

TINYINT

getByte()

byte

SMALLINT

getShort()

short

INT

getInt()

int

BIGINT

getLong()

long

CHAR,VARCHAR

getString()

String

Text(Clob) Blob

getClob getBlob()

Clob Blob

DATE

getDate()

java.sql.Date 只代表日期

TIME

getTime()

java.sql.Time 只表示时间

TIMESTAMP

getTimestamp()

java.sql.Timestamp 同时有日期和时间

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

SQL注入问题:

示例:

   · 当我们输入以下密码,我们发现我们账号和密码都不对竟然登录成功了

请输入用户名:
newboy
请输入密码:
'a' or '1' = '1'
登录成功,欢迎您:newboy

   · 问题分析:

select * from user where name='newboy' and password='a' or '1'='1' 
(name='newboy' and password='a') 为假
('1'='1') 真
相当于
select * from user where true; 查询了所有记录

我们让用户输入的密码和 SQL 语句进行字符串拼接。用户输入的内容作为了 SQL 语句语法的一部分,改变了原有 SQL 真正的意义,以上问题称为 SQL 注入。要解决 SQL 注入就不能让用户输入的密码和我们的 SQL 语句进行简单的字符串拼接。

PreparedStatemrnt接口:

PreparedStatement 是 Statement 接口的子接口,继承于父接口中所有的方法。它是一个预编译的 SQL 语句。

PerparedStatement的执行原理:

  1. 因为有预先编译的功能,提高 SQL 的执行效率。
  2. 可以有效的防止 SQL 注入的问题,安全性更高。

PreparedStatement 接口中的方法:

PreparedStatement 接口中的方法 描述

int executeUpdate()

执行 DML,增删改的操作,返回影响的行数。

ResultSet executeQuery()

执行 DQL,查询的操作,返回结果集

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 的步骤:

  1. 编写 SQL 语句,未知内容使用?占位:"SELECT * FROM user WHERE name=? AND password=?";
  2. 获得 PreparedStatement 对象(传参数sql)
  3. 设置实际参数:setXxx(占位符的位置, 真实的值)
  4. 执行参数化 SQL 语句
  5. 关闭资源

三、JDBC事务的处理

1. 什么是事务

在实际的开发过程中,一个业务操作如:转账,往往是要多次访问数据库才能完成的。转账是一个用户扣钱,另一个用户加钱。如果其中有一条 SQL 语句出现异常,这条 SQL 就可能执行失败。

事务执行是一个整体,所有的 SQL 语句都必须执行成功。如果其中有 1 条SQL 语句出现异常,则所有的SQL 语句都要回滚,整个业务执行失败。

2. API介绍

Connection 接口中与事务有关的方法 说明

void setAutoCommit(boolean autoCommit)

参数是 true 或 false

如果设置为 false,表示关闭自动提交,相当于开启事务

start transaction;开启事务

void commit()

提交事务

void rollback()

回滚事务,会回退到开启事务时的状态

自动提交事务:

MySQL 默认每一条 DML(增删改)语句都是一个单独的事务,每条语句都会自动开启一个事务,语句执行完毕自动提交事务,MySQL 默认开始自动提交事务

 

 

手动提交事务:

MYSQL 中可以有两种方式进行事务的操作:

  1. 手动提交事务
  2. 自动提交事务

手动提交事务使用过程:

  1. 执行成功的情况: 开启事务-->执行多条 SQL 语句-->成功提交事务
  2. 执行失败的情况: 开启事务-->执行多条 SQL 语句-->事务的回滚

3. 银行转账Java代码案例:

package com.qf;
import com.qf.utils.JdbcUtils; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.SQLException;

public class Demo12Transaction {

    //没有异常,提交事务,出现异常回滚事务
    public static void main(String[] args) {
        //1) 注册驱动
        Connection connection = null; 
        PreparedStatement ps = null;
        try {
         //2) 获取连接
            connection = JdbcUtils.getConnection();
         //3) 开启事务
            connection.setAutoCommit(false);
         //4) 获取到 PreparedStatement
            //从 jack 扣钱
            ps = connection.prepareStatement("update account set balance = balance -            ? where name=?");
            ps.setInt(1, 500); 
            ps.setString(2,"Jack"); 
            ps.executeUpdate();
            //出现异常
            System.out.println(100 / 0);

            //给 rose 加钱
            ps = connection.prepareStatement("update account set balance = balance      + ?where ps.setInt(1, 500); ps.setString(2,"Rose"); 
            ps.executeUpdate();
            //提交事务
            connection.commit();
            System.out.println("转账成功");
    
        } catch (Exception e) { 
            e.printStackTrace(); 
            try {
                //事务的回滚
                connection.rollback();
            } catch (SQLException e1) { 
                e1.printStackTrace();
            }
            System.out.println("转账失败");
        }finally {
            //7) 关闭资源
            JdbcUtils.close(connection,ps);
        }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用Java的Socket类来实现验证远程设备是否可以连接。以下是一个示例代码: ``` import java.net.Socket; public class RemoteDeviceValidator { private String hostname; private int port; private String username; private String password; public RemoteDeviceValidator(String hostname, int port, String username, String password) { this.hostname = hostname; this.port = port; this.username = username; this.password = password; } public boolean validate() { try { // 创建一个Socket对象 Socket socket = new Socket(hostname, port); // 发送验证信息 String message = "username=" + username + "&password=" + password; socket.getOutputStream().write(message.getBytes()); // 等待响应 byte[] response = new byte[1024]; int length = socket.getInputStream().read(response); // 关闭连接 socket.close(); // 解析响应 String result = new String(response, 0, length); return result.equals("success"); } catch (Exception e) { // 连接失败 return false; } } } ``` 在上面的代码中,我们创建了一个RemoteDeviceValidator类,它接受远程设备的主机名、端口号、用户名密码作为参数。它的validate()方法会尝试连接远程设备,并发送用户名密码进行验证。如果验证成功,它会返回true,否则返回false。 请注意,上面的代码仅提供了一种验证远程设备的方法,实际上,您可能需要根据具体的情况进行修改。例如,如果远程设备使用SSH协议进行连接,则可以使用JSch类库来实现验证。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值