JavaWeb(篇第二周)之JDBC 您所在的位置:网站首页 存款失败vf JavaWeb(篇第二周)之JDBC

JavaWeb(篇第二周)之JDBC

#JavaWeb(篇第二周)之JDBC| 来源: 网络整理| 查看: 265

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驱动)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sz7KqPgm-1585619491326)(C:\Users\fanhu\AppData\Roaming\Typora\typora-user-images\1585381106311.png)]

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 是由多个接口和类进行功能实现

类型全限定名简介classjava.sql.DriverManage管理多个数据库驱动类,提供了获取数据库连接的方法interfacejava.sql.Connection代表一个数据库连接(当Connection不是NULL时,标识已连接一个数据)interfacejava.sql.Statement发送SQL语句到数据库的工具interfacejava.sql.ResultSet保存SQL查询语句的结果数据(结果集)classjava.sql.SQLException处理数据库应用程序时所发生的异常 2.3 环境搭建

1.在项目中创建一个lib文件夹用于存放jar文件

2.将jar包放输入lib文件夹下

3.将lib文件夹作为library

三、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://主机名(ip):端口号/数据库名user:用户名password:密码 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/database?useUnicode=true&characterEncoding=utf8","root","123"); URL(Uniform Resource Locator)统一资源定位符:由协议、IP、端口、SID(程序实例名称)组成 3.3 获取发送SQL的对象

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

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

编写SQL语句,并执行,接收执行后的数据

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

接收并处理操作结果

if(result > 0){ System.out.println("执行成功"); }

受影响行数:逻辑判断,方法返回

查询结果集:迭代、一次获取

3.6释放资源

遵循的是先开后关的原则,释放过程中用到的资源连接

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

综合六步:实现增删改

public class BasicJDBC { public static void main(String[] args) { try { // 注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 连接数据库 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/companydb?useUnicode=true&characterEncoding=utf-8","root","root"); // 获取发送SQL对象 Statement statement = connection.createStatement(); // 编写SQL语句,执行SQL语句(返回受影响行数) String sql = ""; int i = statement.executeUpdate(sql); //处理数据 if(i>0){ System.out.println("执行成功"); } //释放资源 statement.close(); connection.close(); } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } } } 四、ResultSet(结果集)

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

4.1接收结果集

ResultSet rs = statement.executeQuery(sql)

Result rs =statement.executeQuery(""); 4.2 遍历ResultSet中的数据

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

数据行指针:初始位置在第一行数据前,没调用依此boolean next()方法,ResultSet中指针向下移动一行,结果true,表示当前行有数据rs.getXxx(“列名”); 根据列名获得数rs.getXxx(“整数下标”);根据列的编号舒徐获得!从1开始 boolean next() throws SQLException;//判断rs结果集中下一行是否有数据 4.2.1遍历方法 int getInt(int columnIndex) throws SQLException;// 获取当前行的第N列的int值 int getInt(String columnLabel) throws SQLException;//获得当前行column 4.3综合案例

对stu表所有数据进行遍历

4.3.1根据列的名称进行遍历 public class TestDql { public static void main(String[] args) { try { //1.注册驱动 Class.forName("com.mysql.jdbc.Driver"); //2.获得连接 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/companyDB?useUnicode=true&characterEncoding=utf-8","root","lixiaoning12144014"); //3.获得SQL执行对象 Statement statement = connection.createStatement(); //4.执行SQL语句 String sql = "select * from `Student`"; ResultSet resultSet = statement.executeQuery(sql); //5.对结果集进行处理 while(resultSet.next()){ // 判断结果集中是否有下一行! // 根据列名获取当前行的每一列数据 String id= (String)resultSet.getObject("student_id"); String name = (String)resultSet.getObject("student_name"); String sex = (String)resultSet.getObject("sex"); Date borndate = resultSet.getDate("borndate"); String phone = (String)resultSet.getObject("phone"); Integer gradeid = (Integer)resultSet.getObject("GradeId"); System.out.println(id+"\t"+name+"\t"+sex+"\t"+borndate.toString()+"\t"+phone+"\t"+gradeid); } //6.释放资源 resultSet.close(); statement.close(); connection.close(); } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } } } 4.3.2根据列的编号获取 public class BasicJDBC { public static void main(String[] args) { try { // 注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 连接数据库 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/companydb?useUnicode=true&characterEncoding=utf-8","root","lixiaoning12144014"); // 获取发送SQL对象 Statement statement = connection.createStatement(); // 编写SQL语句,执行SQL语句(返回受影响行数) String sql = ""; int i = statement.executeUpdate(sql); //处理数据 if(i>0){ System.out.println("执行成功"); } //释放资源 statement.close(); connection.close(); } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } } } 五、常见的错误 java.lang.ClassNotFoundException 找不到类 或者 没有导入jar包com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:Unkonen colum ‘列名’ 与SQL语句相关的错误(表名 列名 书写错误 、约束错误、插入的值是String类型,但是没有加单引号)com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:Duplicate entry ‘S1003’ for key ‘PRIMARY’ 原因:主键值已经存在!更改要插入的主键值com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:Unknown column ‘password’ in 可能输入的值的类型不对,确定插入元素时,对应的值的类型是否争取 六、综合案例登陆 6.1创建表 创建一张用户表User id:主键 自增长username 字符串类型 非空password 字符串类型 非空phone 字符串类型 11为 插入两条数据 6.2实现登录 通过控制台,用户输入用户名和密码用户输入的用户名和密码作为参数,编写SQL语句如果查询到用户,则用户存在,提示登陆成功,反之,提示失败 七、SQL注入问题 7.1什么是SQL注入

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

7.2 如何避免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 pstms = connection.prepareStatement(sql); 注意:PreparedStatement应用时,SQL字符串的参数由?符号占位,被称为参数标记,再执行该SQL语句前,要为每个?参数赋值 8.1.2 动态参数绑定

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

//2.为占位符下标赋值 pstm.setString(1,username) pstm.setString(2,password) 九、综合练习 9.1创建数据库、表

数据库 Account

创建一张表Account,有以下列 cardId:字符串,主键password:字符串,非空username,字符串,非空balance:小数,非空phone:字符串,非空 9.2.创建项目通过JDBC实现功能

创建AccountSystem类,完成下列功能

开户:控制台输入所有的账户信息,使用PreparedStatement添加至t_account表存款:控制台输入卡号、密码、存储金额进行修改取款:输入卡号、密码、取款金额转账:输入卡号、密码、对方卡号、转账金额进行修改修改密码:控制台输入卡号、密码、在输入新密码进行修改注销:控制台输入卡号、密码,删除对应的账户信息 创建表 CREATE DATABASE if not exists Account CHARACTER SET utf8; USE Account; CREATE TABLE t_account( `cardId` VARCHAR(20) PRIMARY KEY not null, `password` varchar(20) not null, `balance` DOUBLE NOT NULL, `phone` varchar(11) )charset=utf8; try-catch ctrl+alt+t 代码格式化 ctrl+alt+L 快速定位异常处: F2 package com.qfedu.jdbc.t4; import java.sql.*; import java.util.Scanner; public class AccountSystem { Scanner scanner = new Scanner(System.in); private static Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; static { // 1.注册驱动 try { Class.forName("com.mysql.jdbc.Driver"); // 2.创建数据库连接 connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/Account?useUnicode=true&characterEncoding=utf-8","root","lixiaoning12144014"); } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } } // 开户 public void regiter(){ System.out.println("请输入卡号:"); String cardId = scanner.next(); System.out.println("请输入密码"); String password = scanner.next(); System.out.println("请输入用户名"); String username = scanner.next(); System.out.println("请输入存款金额"); String balance = scanner.next(); System.out.println("请输入预留手机号码:"); String phone = scanner.next(); try { //3.创建Preparement String sql ="insert into `t_account`(`cardId`,`password`,`username`,`balance`,`phone`) values(?,?,?,?,?)"; preparedStatement = connection.prepareStatement(sql); //4.为占位符赋值 preparedStatement.setString(1,cardId); preparedStatement.setString(2,password); preparedStatement.setString(3,username); preparedStatement.setString(4,balance); preparedStatement.setString(5,phone); //5.执行SQL语句 int i = preparedStatement.executeUpdate(); if(i>0){ System.out.println("开户成功"); }else{ System.out.println("开户失败"); } } catch (SQLException e) { e.printStackTrace(); }finally { try { if(preparedStatement!=null){ preparedStatement.close(); } } catch (SQLException e) { e.printStackTrace(); } } } // 更新 public void saveMoney(){ System.out.println("请输入卡号:"); String cardId = scanner.next(); System.out.println("请输入密码:"); String pasword = scanner.next(); System.out.println("请输入存款金额"); double money = scanner.nextDouble(); if(money > 0){ //存款操作 String sql = "update t_account set balance = balance + ? where cardId=? and password=?"; try { preparedStatement = connection.prepareStatement(sql); preparedStatement.setDouble(1,money); preparedStatement.setString(2,cardId); preparedStatement.setString(3,pasword); // 执行,接收返回结果 int i = preparedStatement.executeUpdate(); if(i>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.println("请输入卡号:"); String cardId = scanner.next(); System.out.println("请输入密码:"); String password = scanner.next(); System.out.println("请输入取款金额"); double money = scanner.nextDouble(); if(money > 0){ String sql = "select balance from t_account where cardId=? and password=?"; try { preparedStatement =connection.prepareStatement(sql); preparedStatement.setString(1,cardId); preparedStatement.setString(2,password); resultSet = preparedStatement.executeQuery(); if(resultSet.next()){ double balance = resultSet.getDouble(1); if(money0){ System.out.println("取款成功!"); }else{ System.out.println("取款失败!"); } }else{ System.out.println("余额不足!"); } } } catch (SQLException e) { e.printStackTrace(); }finally { if(resultSet!=null){ try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } if(preparedStatement!=null){ try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } } }else{ System.out.println("输入金额有误!"); } } // 转账 public void transferAccountS() { System.out.println("请输入转账方卡号:"); String cardId = scanner.next(); System.out.println("请输入转账方密码:"); String pasword = scanner.next(); System.out.println("请输入转账金额"); double money = scanner.nextDouble(); System.out.println("请输入接收方卡号:"); String cardId2 = scanner.next(); // 确定转账金额大于0 if(money > 0){ // 查询转账方是否存在 String sql = "select balance from t_account where password=? and cardId=?"; try { preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1,pasword); preparedStatement.setString(2,cardId); resultSet = preparedStatement.executeQuery(); if(resultSet.next()){ // 账号密码存在 double aDouble = resultSet.getDouble(1); // 判断转账金额是否小于银行卡金额 connection.setAutoCommit(false); if(aDouble >= money){ // 关闭事务的自动提交 // 减钱 String sql2="update t_account set balance = balance-? where password=? and cardId=?"; preparedStatement = connection.prepareStatement(sql2); preparedStatement.setDouble(1,money); preparedStatement.setString(2,pasword); preparedStatement.setString(3,cardId); int num1 = preparedStatement.executeUpdate(); // 加钱 String sql3="update t_account set balance = balance+? where cardId=?"; preparedStatement = connection.prepareStatement(sql3); preparedStatement.setDouble(1,money); preparedStatement.setString(2,cardId2); int num2 = preparedStatement.executeUpdate(); if(num1>0 && num2>0){ System.out.println("转账成功!"); }else { System.out.println("转账失败"); } connection.commit(); }else{ System.out.println("余额不足"); } }else{ System.out.println("账号或密码不存在"); } } catch (SQLException e) { try { if(connection!=null){ connection.rollback(); } } catch (SQLException ex) { ex.printStackTrace(); } e.printStackTrace(); }finally { if(resultSet!=null){ try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } try { connection.setAutoCommit(true); } catch (SQLException e) { e.printStackTrace(); } if(preparedStatement!=null){ try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } } // 转账金额是否小于卡内余额 // }else{ System.out.println("转账金额输入有误"); } } // 关闭Connection public void closeConnection(){ if(connection!=null){ try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } // 修改密码 public void changePassword() { System.out.println("请输入卡号:"); String cardId = scanner.next(); System.out.println("请输入密码:"); String password = scanner.next(); String sql = "select * from t_account where cardId=? and password=?"; try { preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1,cardId); preparedStatement.setString(2,password); ResultSet resultSet = preparedStatement.executeQuery(); if(resultSet.next()){ System.out.println("用户名密码正确"); System.out.println("请输入新密码:"); String newPassword = scanner.next(); System.out.println("请再次输入新密码:"); String newRewardPassword = scanner.next(); if(newPassword.equals(newRewardPassword)){ String sql1 ="update t_account set password=? where cardId=?"; preparedStatement = connection.prepareStatement(sql1); preparedStatement.setString(1,newRewardPassword); preparedStatement.setString(2,cardId); int i = preparedStatement.executeUpdate(); if(i>0){ System.out.println("修改成功"); }else{ System.out.println("修改失败"); } }else{ System.out.println("两次密码输入不一致,修改失败!"); } } } catch (SQLException e) { e.printStackTrace(); }finally { if(resultSet!=null){ try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } if(preparedStatement!=null){ try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } } } } // 注销 public void writeOff() { System.out.println("请输入卡号:"); String cardId = scanner.next(); System.out.println("请输入密码:"); String password = scanner.next(); String sql = "select * from t_account where cardId=? and password=?"; try { preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1,cardId); preparedStatement.setString(2,password); boolean execute = preparedStatement.execute(); if(execute){ System.out.println("是否一定要注销此账号? 1.是 2.否"); int result = scanner.nextInt(); if(result==1){ // 确认注销 String sql1 ="delete from t_account where cardId=?"; preparedStatement =connection.prepareStatement(sql1); preparedStatement.setString(1,cardId); int i = preparedStatement.executeUpdate(); if(i>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(); } } if(resultSet!=null){ try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } } } } package com.qfedu.jdbc.t4; import java.util.Scanner; public class TestAccount { public static void main(String[] args) { AccountSystem as = new AccountSystem(); Scanner in = new Scanner(System.in); System.out.println("欢迎进入此系统"); int choice = 0; do{ System.out.println("1、开户 2、存款 3、取款 4、转账 5、修改密码 6、注销 0、退出"); System.out.println("请选择"); choice = in.nextInt(); switch (choice){ // 开户 case 1: as.regiter(); break; // 存款 case 2: as.saveMoney(); break; // 取款 case 3: as.takeMoney(); break; // 转账 case 4: as.transferAccountS(); break; // 修改密码 case 5: as.changePassword(); break; // 注销 case 6: as.writeOff(); break; case 0: as.closeConnection();return; default: System.out.println("暂无此功能"); return; } }while(choice!=0); } }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有