【JDBC教科书】阶段式JDBC数据库连接神操作总结

文章目录

      • 一、引言
        • 1.1 如何操作数据
        • 1.2 实际开发中,会采用客户端操作数据库吗?
      • 二、JDBC(Java DataBase Connectivity)
        • 2.1 什么是JDBC?
        • 2.2 JDBC核心思想
          • 2.2.1 MySQL数据库驱动
          • 2.2.2 JDBC API
        • 2.3 环境搭建
      • 三、JDBC开发步骤【`重点`】
        • 3.1 注册驱动
        • 3.2 连接数据库
        • 3.3 获取发送SQL的对象
        • 3.4 执行SQL语句
        • 3.5 处理结果
        • 3.6 释放资源
        • 3.7 综合案例
      • 四、 ResultSet(结果集)
        • 4.1 接收结果集
        • 4.2 遍历ResultSet中的数据
          • 4.2.1 遍历方法
        • 4.3 综合案例
          • 4.3.1 根据列的名称获取
          • 4.3.2 根据列的下标获取
      • 五、常见错误
      • 六、综合案例【登录】
        • 6.1 创建表
        • 6.2 实现登录
      • 七、SQL注入问题
        • 7.1 什么是SQL注入
        • 7.2如何避免SQL注入
      • 八、 PreparedStatement【`重点`】
        • 8.1 PreparedStatement的应用
          • 8.1.1 参数标记
          • 8.1.2 动态参数绑定
          • 8.1.3 解决7.1遗留下来的SQL注入问题
      • 九、综合练习
        • 9.1创建数据库、表
        • 9.2 创建项目通过JDBC实现功能
      • 十、封装工具类
        • 10.1 重用性方案
          • 10.1.1 工具实现
        • 10.2 跨平台方案
          • 10.2.1 实现
      • 十一、ORM
        • 11.1 ORM 实体类(entity):零散数据的载体
          • 11.1.1 ORM应用
      • 十二、DAO(Data Access Object)
      • 十三、日期类型
        • 13.1 日期格式化工具
        • 13.2 日期工具类 DateUtils
          • 13.2.1 转换流程、测试
      • 十四、连接池
        • 14.1 自定义连接池
        • 14.2 Druid(德鲁伊)
          • 14.2.1 Druid配置
          • 14.2.2 database.properties 文件配置
          • 14.2.3 连接池工具类
          • 14.2.4 测试连接池
      • 十五、Service(Biz/Business)
        • 15.1 业务
        • 15.2 业务层的实现
        • 15.3 复用
        • 15.4 转账案例
        • 15.5 解决转账事务问题
      • 十六、ThreadLocal
        • 16.1 ThreadLocal
        • 16.2 ThreadLocal事务控制优化
          • 16.2.1 DBUtils封装事务控制
          • 16.1.1 数据库完整版工具类(封装了以前所有的优化,详细解析看注释)
      • 十七、三层架构设计
          • 17.1 三层架构设计思想
          • 17.2 三层架构设计的好处与建议
      • 十八、工具类型的封装及普适性泛型工具
        • 18.1 封装DML方法
        • 18.2 封装DQL方法
        • 18.3 最终版Account项目(包含所有工具、功能以及优化)
            • 项目分层
            • Properties配置文件
            • entity
            • DateUtils
            • DBUtils
            • DaoUtils
            • AccountDao
            • AccountDaoImpl
            • AccountService
            • AccountServiceImpl
            • RowMapper
            • AccountRowMapper
            • TestDemo
      • 十九、Apache的DbUtils使用
        • 19.1 DbUtils简介
          • 19.1.1 DbUtils主要包含
        • 19.2 DbUtils的使用步骤
          • 19.2.1 代码实现
          • DBUtils工具类
          • UserDaoImpl 数据访问对象
      • 二十、大结局

注意: 如果转载文章请在文章明显处表明作者,以及原文链接,谢谢!

原文链接: https://blog.csdn.net/weixin_44170221/article/details/105285457

在这里插入图片描述

整个JDBC体系思维导图参考此文章:JDBC知识树

一、引言


1.1 如何操作数据

使用客户端工具访问数据库,需要手工建立链接,输入用户名和密码登录,编写SQL语句,点击执行,查看操作结果(结果集或受影响行数)。

1.2 实际开发中,会采用客户端操作数据库吗?

在实际开发过程中,当用户的数据发生改变时,不可能通过客户端操作执行SQL语句,因为操作量过大!无法保证效率和正确性

二、JDBC(Java DataBase Connectivity)


2.1 什么是JDBC?

JDBC(Java DataBase Connectivity) Java连接数据库,可以使用Java语言连接数据库完成CRUD操作

2.2 JDBC核心思想

Java中定义了访问数据库的接口,可以为多种关系型数据库提供统一的访问方式。

由数据库厂商提供驱动实现类(Driver数据库驱动)

【JDBC教科书】阶段式JDBC数据库连接神操作总结_第1张图片

2.2.1 MySQL数据库驱动
  • mysql-connector-java-5.1.X 适用于5.X版本
  • mysql-connector-java-8.0.X 适用于8.X版本
2.2.2 JDBC API

JDBC 是由多个接口和类进行功能实现

类型 全限定名 简介
class java.sql.DriverManager 管理多个数据库驱动类,提供了获取数据库连接的方法
interface java.sql.Connection 代表一个数据库连接(当Connection不是NULL时,表示已连接一个数据库)
interface java.sql.Statement 发送SQL语句到数据库的工具
interface java.sql.ResultSet 保存SQL查询语句的结果数据(结果集)
class java.sql.SQLException 处理数据库应用程序时所发生的异常
2.3 环境搭建
  1. 在项目下新建 lib 文件夹,用于存放 jar 文件
  2. 将MySQL驱动文件mysql-connector-java-5.1.25-bin.jar 复制到项目的lib文件夹中
  3. 选中lib文件夹 右键选择 add as library,点击OK

三、JDBC开发步骤【重点

3.1 注册驱动

使用Class.forName(“com.mysql.jdbc.Driver”); 手动加载字节码文件到JVM中

Class.forName("com.mysql.jdbc.Driver");
3.2 连接数据库
  • 通过DriverManager.getConnection(url,user,password);获得数据库连接对象
    • URL:jdbc:mysql://localhost:3306/database
    • user:root
    • password:1234
  • 注意:如果设置字符编码集需要在数据库后加?useUnicode=true&characterEncoding=utf8
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/database?useUnicode=true&characterEncoding=utf8","root","123456");
  • URL(Uniform Resource Locator)统一资源定位符:由jdbc协议、mysql协议、IP、端口、SID(程序实例名称)组成
3.3 获取发送SQL的对象

通过Connection对象获得Statement对象,用于对数据库进行通用访问的

Statement statement = connection.createStatement();
3.4 执行SQL语句

编写SQL语句,并执行,接收执行后的结果

int result = statement.executeUpdate("update stu set student_name='Ziph',sex='男' where student_id = 'class1'");
  • 注意:在编写DML语句时,一定要注意字符串参数的符号是单引号 ‘值’
  • DML语句:增、删、改时,执行的结果是受影响行数(int类型)。
  • DQL语句:查询时,返回的是数据结果集(ResultSet结果集)
3.5 处理结果

接收并处理操作结果

if(result > 0){
   
	System.out.println("执行成功!");
} else {
   
    System.out.println("执行失败!");
}
  • 受影响行数:逻辑判断,方法返回
  • 查询结果集:迭代、依次获取
3.6 释放资源

遵循的是先开后关的原则,释放过程中用到的所有资源对象

statement.close();
connection.close();
3.7 综合案例

综合核心六步,实现增删改

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

public class TestInsert {
   
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
   
        //1.加载驱动,将驱动字节码文件加载到JVM中
        Class.forName("com.mysql.jdbc.Driver");
        //2.连接数据库
        String url = "jdbc:mysql://localhost:3306/companydb?useUnicode=true&characterEncoding=utf8";//数据库连接地址
        String user = "root";//用户名
        String password = "123456";//密码
        Connection connection = DriverManager.getConnection(url, user, password);
        //3.获取发送SQL语句的对象
        Statement statement = connection.createStatement();
        //4.编写SQL语句,并执行SQL语句
        String sql = "insert into user (userName, password, address, phone) values ('Ziph', '123456', '河北', '11111111111')";
        int result = statement.executeUpdate(sql);
        //5.处理结果
        if (result > 0) {
   
            System.out.println("添加成功!");
        } else {
   
            System.out.println("添加失败!");
        }
        //6.释放资源,先开后关
        statement.close();
        connection.close();
    }
}

四、 ResultSet(结果集)


在执行查询SQL后,存放查询到的结果集数据

4.1 接收结果集

ResultSet resultSet = statement.executeQuery(sql)

ResultSet resultSet = statement.executeQuery("SELECT * FROM user");
4.2 遍历ResultSet中的数据

ResultSet以表(Table)结构进行临时结果的存储,需要通过JDBC API将其中的数据进行依次获取

  • 数据行指针(resultSet.next()):初始位置在第一行数据前,每调用一次boolean返回值类型的next()方法,ResultSet中指针向下移动一行,结果为true,表示当前行有数据
  • resultSet.getXxx(“列名”); 根据列名获得数据
  • resultSet.getXxx(整数下标); 代表根据列的编号顺序获得!从1开始
boolean next() throws SQLException;//判断resultSet结果集中下一行是否有数据(注意:返回值boolean类型)
4.2.1 遍历方法
int getInt(int columnIndex) throws SQLException;//获得当前行的第N列的int值
int getInt(String columnLabel) throws SQLException;//获得当前行columnLabel列的int值
  • 注意:列的编号从1开始
4.3 综合案例

对user表所有的数据进行遍历

4.3.1 根据列的名称获取
import java.sql.*;

public class TestSelect {
   
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
   
        //1.加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2.获取连接对象
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/companydb?useUnicode=true&characterEncoding=utf8", "root", "Mylifes1110");
        //3.获取执行SQL的对象
        Statement statement = connection.createStatement();
        //4.编写SQL语句并执行SQL语句
        String sql = "select userId, userName, password, address, phone from user";
        ResultSet resultSet = statement.executeQuery(sql);
        //5.处理结果(结果集)
        while (resultSet.next()) {
   //判断结果集中是否有下一行
            //根据列名获取当前行每一列的数据
            int userId = resultSet.getInt("userId");
            String userName = resultSet.getString("userName");
            String password = resultSet.getString("password");
            String address = resultSet.getString("address");
            String phone = resultSet.getString("phone");
            System.out.println(userId + "\t" + userName + "\t" + password + "\t" + address + "\t" + phone);
        }
        //6.释放资源
        resultSet.close();
        statement.close();
        connection.close();
    }
}
4.3.2 根据列的下标获取
		//5.处理结果(结果集)
        while (resultSet.next()) {
   //判断结果集中是否有下一行
            //根据列的编号获取当前行每一列的数据
            int userId = resultSet.getInt(1);
            String userName = resultSet.getString(2);
            String password = resultSet.getString(3);
            String address = resultSet.getString(4);
            String phone = resultSet.getString(5);
            System.out.println(userId + "\t" + userName + "\t" + password + "\t" + address + "\t" + phone);
        }

五、常见错误

  • java.lang.ClassNotFoundException 找不到类(类名书写错误、没有导入jar包)
  • com.mysql.jdbc.exceptions.jdbc.MySQLSyntaxErrorException 与SQL语句相关的错误(表名列名书写错误、约束错误、插入的值是String类型,但是没有加单引号)建议:在客户端工具中测试sql语句后,再粘贴到代码中来
  • com.mysql.jdbc.exceptions.jdbc.MySQLIntegrityConstraintViolationException: Duplicate entry ‘1’ for key ‘PRIMARY’ 原因:主键值已存在!更改要插入的主键值
  • com.mysql.jdbc.exceptions.jdbc.MySQLSyntaxErrorException:Unknown column ‘password’ in
    • 可能输入的值的类型不对,确定插入元素时,对应的值的类型是否争取

六、综合案例【登录】


6.1 创建表
  • 创建一张用户表 User
    • id 主键、自动增长
    • username 字符串类型 非空
    • password 字符串类型 非空
    • phone 字符串类型
  • 插入2条测试语句
#创建数据库
CREATE DATABASE temp CHARACTER SET utf8;
#使用该数据库
USE temp;
#创建用户表
CREATE TABLE user (
	id INT PRIMARY KEY auto_increment,
	username CHARACTER(20) NOT NULL,
	password CHARACTER(20) NOT NULL,
	phone CHARACTER(11)
) charset = utf8;
#初始化(插入)表中数据
INSERT INTO user (username, password, phone) VALUES ('ziph', '123456', '16688889999');
INSERT INTO user (username, password, phone) VALUES ('zhangsan', '123456', '16644445555');
6.2 实现登录
  • 通过控制台,用户输入用户名和密码
  • 用户输入的用户名和密码作为参数,编写查询SQL语句。
  • 如果查询到用户,则用户存在,提示登录成功,反之,提示失败!
import java.sql.*;
import java.util.Scanner;

public class TestLogin {
   
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
   
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入用户名:");
        String userName = scanner.nextLine();
        System.out.print("请输入密码:");
        String password = scanner.nextLine();

        //1.加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2.获取连接对象,连接数据库
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/temp?useUnicode=true&characterEncoding=utf8", "root", "123456");
        //3.创建执行SQL语句的对象
        Statement statement = connection.createStatement();
        //4.编写SQL语句,并执行SQL语句
        String sql = "select * from user where username = '" + userName + "' and password = '" + password + "'";
        ResultSet resultSet = statement.executeQuery(sql);
        //5.处理结果
        if (resultSet.next()) {
   //通过参数,查到一行数据,就提示用户的登陆成功!
            System.out.println("登录成功!");
        } else {
   
            System.out.println("登录失败!");
        }
        //6.释放资源
        resultSet.close();
        statement.close();
        connection.close();
    }
}

七、SQL注入问题


7.1 什么是SQL注入

当用户输入的数据中有SQL关键字或语法时,并且参与了SQL语句的编译,导致SQL语句编译后条件结果为true,一直得到正确的结果。称为SQL注入

在这里插入图片描述

继续使用6.2实现登录案例,用户名、密码(用户名数据库里没有,密码随便录入的)我在控制台输入的图上内容,却出现了登录成功!这是怎么回事呢?那我们再来看一下,看下图吧!

在这里插入图片描述

看一下高亮显示的部分,这一部分是SQL执行的语句,而userName、password是我们控制台录入的信息(也参与SQL语句的执行)。但是当你输入lalala字符串是没问题的,但是当你再入’ 的时候,SQL执行的时候会认为’ 是userName的结束。随之,录入了or后面内容1=1参与SQL执行代替了录入的密码。这里我解释一下,因为1=1,默认为true,所以该密码就被越过了!; 被认为SQL语句的结束标志,随后一个#注释了password等后面的所有内容。当resultSet.next()判断时,因为它的结果返回的就是boolean类型,上述SQL注入自然而然的返回了一个true成功的越过了账号和密码的界限,登录成功!这就是SQL注入!大家可以理解了吧!那么我们继续看以下语句吧!该语句就是在SQL注入后,被SQL执行的语句:

sql = "select * from user where username='xxx' or 1=1;#'and password ='123456'";
7.2如何避免SQL注入

由于编写的SQL语句,是在用户输入数据后,整合后再编译成SQL语句。所以为了避免SQL注入的问题,使SQL语句在用户输入数据前,SQL语句已经完成编译,成为了完整的SQL语句,再进行填充数据(需要在我们控制台录入后,提前把SQL语句编译成一行长长的字符串,防止注入),想知道怎么解决,那就继续看下面的重点,记住是重点哦!

八、 PreparedStatement【重点


PreparedStatement接口继承了Statement接口。执行SQL语句的方法没有区别!

8.1 PreparedStatement的应用

作用:

  • 1.预编译SQL语句,效率高!
  • 2.安全,避免SQL注入
  • 3.可以动态的填充数据,执行多个同构的SQL语句
8.1.1 参数标记
//1.预编译SQL语句
PreparedStatement preparedStatement = connection.prepareStatement(sql);
  • 注意:PreparedStatement应用时,SQL字符串的参数都由?符号占位,被称为参数标记。在执行该SQL语句前,要为每个?参数赋值
8.1.2 动态参数绑定

preparedStatement.setXxx(下标,值); 参数下标是从1开始,为指定占位符下标绑定值

//2.为占位符下标赋值
preparedStatement.setString(1,username);
preparedStatement.setString(2,password);
8.1.3 解决7.1遗留下来的SQL注入问题
import java.sql.*;
import java.util.Scanner;

public class TestSafeLogin {
   
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
   
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入用户名:");
        String username = scanner.nextLine();
        System.out.print("请输入密码:");
        String password = scanner.nextLine();

        //1.注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2.获取连接对象
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/temp?useUnicode=true&characterEncoding=utf8","root", "123456");
        //3.创建执行sql语句的对象
        String sql = "select * from user where username = ? and password = ?";
        //预编译SQL语句————提前把SQL语句编译为字符串,其中用到了转义字符防止个别符号注入SQL
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        /**
         * 查看预编译后的SQL语句字符串
         * 此查看不计为jdbc的开发步骤中
         */
        System.out.println(preparedStatement);

        //为占位符下标赋值
        preparedStatement.setString(1, username);
        preparedStatement.setString(2, password);

        /**
         * 查看赋值后SQL语句的字符串
         * 此查看不计为jdbc的开发步骤中
         */
        System.out.println(preparedStatement);

        //4.执行SQL语句————此时executeQuery()不需要在传入参数
        ResultSet resultSet = preparedStatement.executeQuery();
        //5.处理结果
        if (resultSet.next()) {
   //通过参数,查到一行数据,提示用户登录成功!
            System.out.println("登陆成功!");
        } else {
   
            System.out.println("登录失败!");
        }
        //6.释放资源
        resultSet.close();
        preparedStatement.close();
        connection.close();
    }
}

输入SQL注入问题的用户名和密码得出以下结果!

查看预编译后的SQL语句字符串结果: com.mysql.jdbc.JDBC4PreparedStatement@4b9af9a9: select * from user where username = ** NOT SPECIFIED ** and password = ** NOT SPECIFIED **

查看赋值后SQL语句的字符串结果: com.mysql.jdbc.JDBC4PreparedStatement@4b9af9a9: select * from user where username = ‘lalal’ or 1=1;#’ and password = ‘asdsad’

最终结果: 登录失败!

总结: 我们可以看出’lalal后面’ 被加了转义字符,而 or 1=1;#后加了SQL语句应该加的username结束标志 ’ 。

九、综合练习


9.1创建数据库、表

创建数据库 account

  • 创建一张表 t_ccount。有以下列
    • cardId:字符串,主键
    • password:字符串,非空
    • username:字符串,非空
    • balance:小数,非空
    • phone:字符串,非空
#创建数据库
create database account character set utf8;
#使用account数据库
use account;
#创建表
create table t_account
(
    card_id  character(20) primary key,
    password character(50) not null,
    username character(20) not null,
    balance  double(10, 2) not null,
    phone    character(11) not null
) character set utf8;
9.2 创建项目通过JDBC实现功能

创建AccountSystem类,完成下列功能

  • 开户:控制台输入所有的账户信息,使用PreparedStatement添加至t_account表
  • 存款:输入卡号、密码、存储金额进行修改
  • 取款:输入卡号、密码、取款金额
  • 转账:输入卡号、密码、对方卡号、转账金额进行修改
  • 查看余额: 输入卡号、密码,查询余额
  • 修改密码:输入卡号、密码,再输入新密码进行修改
  • 注销:输入卡号、密码,删除对应的账户信息
import java.util.Scanner;

/**
 * 菜单
 */
public class TestAccount {
   
    public static void main(String[] args) {
   
        AccountSystem accountSystem = new AccountSystem();
        Scanner scanner = new Scanner(System.in);
        System.out.println("欢迎使用中国银行ATM机");
        int choice = 0;
        do {
   
            System.out.println("1.开户 2.存款 3.取款 4.转账 5.修改密码 6.查看账户余额 7.注销 0.退出");
            System.out.print("请选择你的操作:");
            choice = scanner.nextInt();
            switch (choice) {
   
                case 1:
                    accountSystem.register();
                    break;
                case 2:
                    accountSystem.saveMoney();
                    break;
                case 3:
                    accountSystem.takeMoney();
                case 4:
                    accountSystem.transfers();
                    break;
                case 5:
                    accountSystem.updatePassword();
                    break;
                case 6:
                    accountSystem.getBalance();
                    break;
                case 7:
                    accountSystem.logout();
                    break;
                case 0:
                    accountSystem.closeConnection();
                    return;
                default:
                    break;
            }
        } while (choice != 0);
    }
}

import java.sql.*;
import java.util.Scanner;

/**
 * 要求:
 * 

* 开户:输入所有的账户信息,使用PreparedStatement添加至t_account表中 * 存款:输入卡号、密码、存储金额进行修改 * 取款:输入卡号、密码、取款金额 * 转账:输入卡号、密码、需要对其转账的卡号、转账金额进行修改 * 修改密码:输入卡号、密码,再输入新密码进行修改 * 查询余额:输入卡号、密码,查询出对应的卡内余额 * 注销:输入卡号、密码,删除对应的账户信息 */ public class AccountSystem { Scanner scanner = new Scanner(System.in); private static Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; static { //重复的操作,就出发一次加载即可! try { //1.加载驱动 Class.forName("com.mysql.jdbc.Driver"); //2.连接数据库 connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/account?useUnicode=true&characterEncoding=utf8", "root", "Mylifes1110"); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } /** * 关闭数据库连接对象Connection *

* 注意:在程序结束时关闭,如果过早关闭的话,将与数据库断开连接 * 所以我们放在退出ATM机系统时调用关闭 */ public void closeConnection() { if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } //开户 public void register() { System.out.print("请输入卡号:"); String card_id = scanner.next(); System.out.print("请输入密码:"); String password = scanner.next(); System.out.print("请输入用户名:"); String username = scanner.next(); System.out.print("请输入存储金额:"); double balance = scanner.nextDouble(); System.out.print("请输入预留手机号:"); String phone = scanner.next(); //3.创建PreparedStatement,预编译 String sql = "insert into t_account(card_id, password, username, balance, phone) values (?, ?, ?, ?, ?)"; try { preparedStatement = connection.prepareStatement(sql); //4.为占位符赋值 preparedStatement.setString(1, card_id); preparedStatement.setString(2, password); preparedStatement.setString(3, username); preparedStatement.setDouble(4, balance); preparedStatement.setString(5, phone); //5.执行SQL语句 int result = preparedStatement.executeUpdate(); //6.处理结果 if (result > 0) { System.out.println("开户成功!"); } else { System.out.println("开户失败!"); } } catch (SQLException e) { e.printStackTrace(); } finally { if (preparedStatement != null) { try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } } } //存款 public void saveMoney() { System.out.print("请输入卡号:"); String card_id = scanner.next(); System.out.print("请输入密码:"); String password = scanner.next(); System.out.print("请输入存储金额:"); double money = scanner.nextDouble(); if (money > 0) { String sql = "update t_account set balance = balance + ? where card_id = ? and password = ?"; //预编译 try { preparedStatement = connection.prepareStatement(sql); //为占位符赋值 preparedStatement.setDouble(1, money); preparedStatement.setString(2, card_id); preparedStatement.setString(3, password); //执行SQL语句 int result = preparedStatement.executeUpdate(); //处理结果 if (result > 0) { System.out.println("存款成功!"); } else { System.out.println("卡号或密码错误!"); } } catch (SQLException e) { e.printStackTrace(); } finally { if (preparedStatement != null) { try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } } } else { System.out.println("输入存储金额错误!"); } } //取款 public void takeMoney() { System.out.print("请输入卡号:"); String card_id = scanner.next(); System.out.print("请输入密码:"); String password = scanner.next(); System.out.print("请输入取出金额:"); double money = scanner.nextDouble(); if (money > 0) { String sql = "update t_account set balance = balance - ? where card_id = ? and password = ?"; //预编译 try { preparedStatement = connection.prepareStatement(sql); //为占位符赋值 preparedStatement.setDouble(1, money); preparedStatement.setString(2, card_id); preparedStatement.setString(3, password); //执行SQL语句 int result = preparedStatement.executeUpdate(); //处理结果 if (result > 0) { System.out.println("取款成功!"); } else { System.out.println("卡号或密码错误!"); } } catch (SQLException e) { e.printStackTrace(); } finally { try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } } } //查看余额 public void getBalance() { System.out.print("请输入卡号:"); String card_id = scanner.next(); System.out.print("请输入密码:"); String password = scanner.next(); String sql = "select balance from t_account where card_id = ? and password = ?"; try { preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1, card_id); preparedStatement.setString(2, password); ResultSet resultSet = preparedStatement.executeQuery(); if (resultSet.next(

你可能感兴趣的:(JDBC,数据库,JDBC,程序人生,经验分享)