当前位置: 首页 > news >正文

jdbc-day01

_01Simple_JDBCDemo01

package com.jdbc._01Simple;import java.sql.*;/***  JDBC的第一个程序编写: 修改mydb库中的emp表中的7369这个员工的部门编号为30*   准备工作: 准备好项目,然后加载第三方jar包,即MYSQL的驱动程序。注意, add as Library*/public class JDBCDemo01 {public static void main(String[] args) throws ClassNotFoundException, SQLException {//第一步:加载驱动Class.forName("com.mysql.cj.jdbc.Driver");/*第二步:获取连接,(使用DriverManager 自动识别程序,并向数据库发送连接请求,如果成功,则返回连接会话)参数url: 连接数据库的路径地址 jdbc:mysql://ip:port/库名?serverTimezone=Asia/Shanghai&useTimezone=true参数user: 连接数据库的用户名  root参数password: 连接数据库的密码  111111*/Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai&useTimezone=true","root","111111");//第三步:通过连接会话对象,来获取可以发送sql语句的对象Statement stat = conn.createStatement();//第四步:使用Statement的方法来发送sql语句/*execute(String sql): 发送DDL的方法executeUpdate(String sql): 发送DML的方法,返回受影响的行数executeQuery(String sql): 发送DQL的方法,返回结果集Statement该对象发送的sql语句,每次都会解析、编译,效率低,所以使用PreparedStatement解析SQL: 校验SQL的语法格式是否正确编译SQL: 验证书写的表名,字段等是否正确,是否与数据库中一致,若存在,则编译通过*/// 修改mydb库中的emp表中的7369这个员工的部门编号为30int num = stat.executeUpdate("update emp set deptno= 30 where empno = 7369");//第五步:处理结果集System.out.println("受影响的条数"+num);//第六步:关闭资源stat.close();}
}

_01Simple_JDBCDemo02

package com.jdbc._01Simple;import java.sql.*;/*** 使用JDBC来完成第二个程序:查询emp表中的20号部门所有的员工,信息不使用**/public class JDBCDemo02 {public static void main(String[] args) throws ClassNotFoundException, SQLException {// 第一步 加载驱动Class.forName("com.mysql.cj.jdbc.Driver");//第二步:获取连接,(使用DriverManager 自动识别程序,并向数据库发送连接请求,如果成功,则返回连接会话)Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai&useTimezone=true","root","111111");// 第三步:通过连接会话对象,来获取可以发送sql语句的对象,并发送sqlStatement stat = conn.createStatement();ResultSet sql = stat.executeQuery("select empno,ename,job,mgr,deptno,sal,comm,hiredate from emp where deptno = 20 ");//注意: DBMS执行之后的结果被发送到客户端,被封装到ResultSet对象中// 第四步:处理查询结果集   里面存储了N行记录,指针默认在第一行之前,因此想要获取每一行的数据,需要移动指针while(sql.next()){  //向下移动指针int empno = sql.getInt(1);String ename = sql.getString(2);String job = sql.getString(3);int mgr = sql.getInt(4);int deptno = sql.getInt(5);double sal = sql.getDouble("sal");double comm = sql.getDouble("comm");Date hiredate = sql.getDate("hiredate");System.out.println(empno + "\t" + ename + "\t" + job + "\t" + mgr + "\t" + deptno + "\t" + sal + "\t" + comm + "\t" + hiredate);}// 第五步:关闭资源conn.close();}
}

_01Simple_JDBCDemo03

package com.jdbc._01Simple;import java.sql.*;public class JDBCDemo03 {public static void main(String[] args) throws ClassNotFoundException, SQLException {Class.forName("com.mysql.cj.jdbc.Driver");Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai&useTimezone=true","root","111111");Statement stat = conn.createStatement();int sql = stat.executeUpdate("insert into emp values (10000,'superman','hero',7369,'2024-08-30',2000,500,40 )");System.out.println(sql);stat.close();}}

_01Simple_JDBCDemo04

package com.jdbc._01Simple;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;public class JDBCDemo04 {public static void main(String[] args) throws ClassNotFoundException, SQLException {Class.forName("com.mysql.cj.jdbc.Driver");Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai&useTimezone=true","root","111111");Statement stat = conn.createStatement();int sql = stat.executeUpdate("delete from emp where empno=10000");System.out.println(sql);conn.close();}
}

_02TestDBUtil_JDBCDemo01

package com.jdbc._02TestDBUtil;import com.jdbc.Util.DBUtil;import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;/*** 使用DBUtil 重构 _01Simple.JDBCdemo01中的代码*/public class JDBCDemo01 {public static void main(String[] args) throws SQLException {//调用DBUtil的连接对象,获取连接会话Connection conn = DBUtil.getConnection();Statement stat = conn.createStatement();int num = stat.executeUpdate("update emp set deptno= 30 where empno = 7369");System.out.println("受影响的条数" + num);DBUtil.closeConnection(conn);}
}

_02TestDBUtil_JDBCDemo02

package com.jdbc._02TestDBUtil;import com.jdbc.Util.DBUtil;import java.sql.*;/*** 使用JDBC来完成第二个程序:查询emp表中的20号部门所有的员工,信息不使用**/public class JDBCDemo02 {public static void main(String[] args) throws ClassNotFoundException, SQLException {Connection conn = DBUtil.getConnection();Statement stat = conn.createStatement();ResultSet sql = stat.executeQuery("select empno,ename,job,mgr,deptno,sal,comm,hiredate from emp where deptno = 20 ");while(sql.next()){  //向下移动指针int empno = sql.getInt(1);String ename = sql.getString(2);String job = sql.getString(3);int mgr = sql.getInt(4);int deptno = sql.getInt(5);double sal = sql.getDouble("sal");double comm = sql.getDouble("comm");Date hiredate = sql.getDate("hiredate");System.out.println(empno + "\t" + ename + "\t" + job + "\t" + mgr + "\t" + deptno + "\t" + sal + "\t" + comm + "\t" + hiredate);}DBUtil.closeConnection(conn);}
}

_03Batch_BatchTest

package com.jdbc._03Batch;import com.jdbc.Util.DBUtil;import java.sql.Connection;
import java.sql.Statement;/*** 为什么使用JDBC的批处理: 因为Statement发送的SQL语句,DBMS每次逗号解析,编译,性能较低** 批处理的方法:  可以提前将一部分SQL存储在缓存区中,然后一次性的将缓存区中的SQL刷到DBMS里* 这样可以大大减少了客户端与数据库的交互次数,从而变相的提高效率。**         testbatch*               id int primary key auto_increment,*               name varchar(20),*               ender char(1)*/public class BatchTest {public static void main(String[] args) {Connection conn =null;try {conn = DBUtil.getConnection();// 向数据库中插入1030条记录Statement stat = conn.createStatement();for (int i = 0; i < 1030; i++) {String[] genders= {"f","m"};String gender = genders[(int)(Math.random()*2)];String sql = "insert into testbatch values(null,'zhaoyun"+i+"','"+gender+"')";// 将SQL语句存储在缓存区中stat.addBatch(sql);// 缓存区储存50个,就冲刷一次if (i%50==0){stat.executeBatch();}}// 清空缓存区stat.clearBatch();} catch (Exception e){e.printStackTrace();}finally {DBUtil.closeConnection(conn);}}
}

_04SQLIniect_Account

package com.jdbc._04SQLInject;import java.sql.Date;
import java.util.Objects;/*** 定义一个java类型Account 与表的记录进行映射。   一个Account对象表示表中的一条记录信息*/
public class Account {private int id;private String accountId;private double balance;private String username;private String password;private String idcard;private Date opertime;private char gender;private Account(){}public Account(int id, String accountId, double balance, String username, String password, String idcard, Date opertime, char gender) {this.id = id;this.accountId = accountId;this.balance = balance;this.username = username;this.password = password;this.idcard = idcard;this.opertime = opertime;this.gender = gender;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getAccountId() {return accountId;}public void setAccountId(String accountId) {this.accountId = accountId;}public double getBalance() {return balance;}public void setBalance(double balance) {this.balance = balance;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getIdcard() {return idcard;}public void setIdcard(String idcard) {this.idcard = idcard;}public Date getOpertime() {return opertime;}public void setOpertime(Date opertime) {this.opertime = opertime;}public char getGender() {return gender;}public void setGender(char gender) {this.gender = gender;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Account account = (Account) o;return id == account.id && Double.compare(balance, account.balance) == 0 && gender == account.gender && Objects.equals(accountId, account.accountId) && Objects.equals(username, account.username) && Objects.equals(password, account.password) && Objects.equals(idcard, account.idcard) && Objects.equals(opertime, account.opertime);}@Overridepublic int hashCode() {return Objects.hash(id, accountId, balance, username, password, idcard, opertime, gender);}@Overridepublic String toString() {return "Account{" +"id=" + id +", accountId='" + accountId + '\'' +", balance=" + balance +", username='" + username + '\'' +", password='" + password + '\'' +", idcard='" + idcard + '\'' +", opertime=" + opertime +", gender=" + gender +'}';}
}

_04SQLIniect_AppClient

package com.jdbc._04SQLInject;import java.util.Scanner;/*** 使用Scanner来模拟登录案例的客户端界面*/
public class AppClient {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入用户名:");String username = sc.nextLine();System.out.println("请输入密码:");String password = sc.nextLine();//来一个服务端对象//AppServer server   = new AppServer();AppServer2 server = new AppServer2();//调用服务端的checkLogin方法检查Account account = server.checkLogin(username,password);if(account == null){System.out.println("用户名或密码不正确,登录失败");}else{System.out.println("登录成功,正在跳转......");}}
}

_04SQLIniect_AppServer

package com.jdbc._04SQLInject;import com.jdbc.Util.DBUtil;import java.sql.Connection;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.Statement;/*** 定义一个服务端。*   提供一个用于检测用户名和密码是否正确的方法。*   如果正确,返回一个Account对象*   如果不正确,返回一个null*/
public class AppServer {/**** @param username   要验证的用户名* @param password   要验证的密码* @return*/public Account checkLogin(String username, String password) {Account account = null;Connection conn = null;try{//连接数据库conn = DBUtil.getConnection();Statement stat = conn.createStatement();//用户名和密码同时作为where里的条件,进行查询,如果能查询到数据,说明用户名和密码是正确的String sql = "select * from bank_account where user_name = '" + username + "' and user_pwd = '" + password + "'";//发送到数据库中执行ResultSet resultSet = stat.executeQuery(sql);if(resultSet.next()){int id = resultSet.getInt("id");String account_id = resultSet.getString("account_id");double balance = resultSet.getDouble("account_balance");String user_name = resultSet.getString("user_name");String user_pwd = resultSet.getString("user_pwd");String idcard = resultSet.getString("user_idcard");Date oper_time = resultSet.getDate("oper_time");String gender = resultSet.getString("gender");account = new Account(id,account_id,balance,user_name,user_pwd,idcard,oper_time,gender.charAt(0));}}catch (Exception e){e.printStackTrace();}finally {DBUtil.closeConnection(conn);}return account;}
}

_04SQLIniect_AppServer2

package com.jdbc._04SQLInject;import com.jdbc.Util.DBUtil;import java.sql.*;/*** 定义一个服务端。*   提供一个用于检测用户名和密码是否正确的方法。*   如果正确,返回一个Account对象*   如果不正确,返回一个null***   SQL注入:  黑客通过传值的方式,改变SQL的条件结构,比如由两个条件,变成了三个条件*             "....where username ='"+username+"' and password='"+password+"'**             password的值,传入了  111111' or '1'='1  因此就会变成**              "....where username ='"+username+"' and password='111111' or '1'='1'**              可以看出,多一个or连接  1=1恒成立的条件。**  也就是说Statement可以通过SQL注入的方法将条件的个数改变,换句话说,就是改变了SQL语句的整体结构。**  因此Sun公司有设计了一个Statement的子接口PreparedStatement。**  PrepatedStatement这个接口会先将SQL结构提前发送到DBMS中,并且DBMS会将该结构锁死。黑客再次通过SQL注入*  的方法传入了带有or连接的恒成立的条件,DBMS也只会将其当成一个参数,而不是条件。**  同一个SQL语句或者是相似的SQL语句,PreparedStatemnt只会解析一次。因此效率相对于Statement也高。**/
public class AppServer2 {/**** @param username   要验证的用户名* @param password   要验证的密码* @return*/public Account checkLogin(String username, String password) {Account account = null;Connection conn = null;try{//连接数据库conn = DBUtil.getConnection();/*** 调用prepareStatement(String sql)  先确定SQL的结构,发送到DBMS中* 使用?来表示占位,用于传参。*/String sql = "select * from bank_account where user_name = ? and user_pwd = ? ";PreparedStatement stat = conn.prepareStatement(sql);//提前发送完毕后,要继续给?赋值    ?从左到右的索引 是从1开始stat.setString(1, username);stat.setString(2, password);//再次将参数发送到数据库中执行ResultSet resultSet = stat.executeQuery();if(resultSet.next()){int id = resultSet.getInt("id");String account_id = resultSet.getString("account_id");double balance = resultSet.getDouble("account_balance");String user_name = resultSet.getString("user_name");String user_pwd = resultSet.getString("user_pwd");String idcard = resultSet.getString("user_idcard");Date oper_time = resultSet.getDate("oper_time");String gender = resultSet.getString("gender");account = new Account(id,account_id,balance,user_name,user_pwd,idcard,oper_time,gender.charAt(0));}}catch (Exception e){e.printStackTrace();}finally {DBUtil.closeConnection(conn);}return account;}
}

_05Transfer_BankTransferDemo

package com.jdbc._05Transfer;import com.jdbc.Util.DBUtil;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;/*** 演示银行转账业务:*     两个账号,一个金额*/
public class BankTransferDemo {public static void main(String[] args) throws Exception {boolean flag = transfer("6225113088436225","6225113088436226",10000);System.out.println("flag:"+flag);}/**** @param fromAccount  转出账号* @param toAccount    转入账号* @param money        要转出的金额* @return      成功 true   失败false*/public static boolean transfer(String fromAccount, String toAccount, int money) throws Exception {Connection conn = null;try {//第一大步:先校验参数是否合理if(money < 0){return false;}if(fromAccount == null || toAccount == null|| fromAccount.trim().length() == 0|| toAccount.trim().length() == 0){return false;}//验证两个账号是否真实有效,去数据库中验证conn = DBUtil.getConnection();String sql = "select * from bank_account where account_id=?";//先验证转出账号PreparedStatement ps = conn.prepareStatement(sql);ps.setString(1, fromAccount);ResultSet resultSet = ps.executeQuery();if(!resultSet.next()){System.out.println("转出账号不存在");//说明转出账号不存在return false;}//再验证转入账号PreparedStatement ps2 = conn.prepareStatement(sql);ps2.setString(1, toAccount);ResultSet resultSet1 = ps2.executeQuery();if(!resultSet1.next()){System.out.println("转入账号不存在");//说明转入账号不存在return false;}//第二大步: 上述验证都通过了,就可以转账了//因为转账设计两个update语句,因此应该将这两个update语句当做一个事务来对待//所以,在第一个update 之前,开启一个事务conn.setAutoCommit(false);//获取转出账号的余额double fromBalance = resultSet.getDouble("account_balance");if (fromBalance<money){System.out.println("余额不足");return false;}//余额充足,可以转出String Sql2 = "update bank_account set account_balance=? where account_id=?";PreparedStatement prep = conn.prepareStatement(Sql2);prep.setDouble(1, fromBalance-money);prep.setString(2, fromAccount);prep.executeUpdate();//写一个异常,来模拟程序正好执行到这里,银行断电String str = null;System.out.println(str.length());/*造成的结果: 出账没问题,已经扣除相应的金额,但是入账除了问题,没有执行入账,因此入账失败程序员不应该让这样的事情发生,因此引入了一个关于数据库的概念: 事务事务的简单理解: 就是做一件事,这件事是一个整体,做就完全做完;不做就完全不做,不管进行到什么环节,都认为没有开始特点:ACIDA:原子性:一个事务,是一个整体,不可切割C:一致性:一个事务,做这件事之前和之后的数据之后是一样的I:隔离性:一个事务,只能进行一个操作,不能被其他事务干扰(类似线程同步)D:持久性:一个事务,如果完成了,就必须持久化到磁盘上TCL(事务控制语言): 提供三个关键字,保证这些特性:commit: 提交,进行持久化保存rollback: 回滚,撤销,将数据恢复到上一步savepoint: 设置一个保存点,如果出错,可以回滚到这个点,而不是从一开始什么时候设计到事务的概念?只有当使用DML语言(insert into;update;delete)时,才会触发事务- 默认情况下,mysql的一个DML语句,就是一个完整的事务,会自动触发commit操作- 如果你的事务涉及到多个DML时,应该取消mysql的默认机制,自己来控制事务的提交和回滚*///转入double toBalance = resultSet1.getDouble("account_balance");PreparedStatement prep2 = conn.prepareStatement(Sql2);prep2.setDouble(1, toBalance+money);prep2.setString(2, toAccount);prep2.executeUpdate();//能执行到此,说明转账业务成功进行 就应该手动提交该事务conn.commit();return true;}catch (Exception e) {e.printStackTrace();//如果出现异常,或者断电的情况,我们要将事务回滚到最初的状态try {conn.rollback();} catch (SQLException ex) {throw new RuntimeException(ex);}}finally {DBUtil.closeConnection(conn);}return false;}
}

Util_DBUtil

package com.jdbc.Util;import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;/*** 自定义一个连接、关闭数据库的工具类型。* 提供一个连接方法:  getConnection()* 提供一个关闭方法:  closeConnection(Connection conn)*/public class DBUtil {private static String driverClass;private static String url;private static String user;private static String password;static {try {//使用IO流读取jdbc.properties配置文件//getResourceAsStream的形参是相对路径,从当前类所在的包中寻找InputStream inputStream = DBUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");// 创建Properties对象Properties prop = new Properties();//调用集合对象的load方法,读取流中信息prop.load(inputStream);// 从对象身上获取相关的键值对,注意传入的key是文件中等号前的名driverClass = prop.getProperty("driverClass");url = prop.getProperty("url");user = prop.getProperty("username");password = prop.getProperty("password");} catch (IOException e) {throw new RuntimeException(e);}}public static void main(String[] args) {//调用连接数据库的方法Connection connection = DBUtil.getConnection();System.out.println(connection);//调用关闭数据库的方法closeConnection(connection);}// 连接数据库public static Connection getConnection() {Connection conn = null;try {Class.forName(driverClass);conn = DriverManager.getConnection(url, user, password);} catch (Exception e) {e.printStackTrace();}return conn;}// 关闭连接public static void closeConnection(Connection conn) {if (conn != null) {try {conn.close();} catch (Exception e) {e.printStackTrace();}}}
}

jdbc.properties

driverClass=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai&useTimezone=true
username=root
password=111111

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • [python]线程与进程的区别及代码演示
  • C语言编译的过程
  • 数据资产入表元年,企业如何抓住数据资产增值的机遇?
  • 日志系统(最新版)
  • 09-03 周二 ansible部署与使用指南
  • 深入解析 Netty 的线程模型
  • Android13修改Setting实现电量低于30%的话不可执行Rest操作
  • 腾讯云Linux服务器运维,安装JDK、rabbitmq、nginx、Redis、ClickHouse
  • 【面试题】MySQL的聚簇索引与非聚簇索引与主键索引:深入理解与应用
  • 智能手机、汽车新应用,星纪魅族幸运星号”卫星即将发射
  • 【LeetCode】03.无重复字符的最长子串
  • javascript利用for循环输出0-100的数
  • 针对STM32串口输出乱码错误问题
  • 心得与体会
  • JavaWeb JavaScript 9.正则表达式
  • [nginx文档翻译系列] 控制nginx
  • Angular 4.x 动态创建组件
  • C++回声服务器_9-epoll边缘触发模式版本服务器
  • DataBase in Android
  • docker python 配置
  • github从入门到放弃(1)
  • Java程序员幽默爆笑锦集
  • MySQL几个简单SQL的优化
  • PHP那些事儿
  • rc-form之最单纯情况
  • RxJS: 简单入门
  • spark本地环境的搭建到运行第一个spark程序
  • Traffic-Sign Detection and Classification in the Wild 论文笔记
  • uva 10370 Above Average
  • vue总结
  • 闭包,sync使用细节
  • - 概述 - 《设计模式(极简c++版)》
  • 如何在GitHub上创建个人博客
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • ​虚拟化系列介绍(十)
  • # Swust 12th acm 邀请赛# [ A ] A+B problem [题解]
  • #!/usr/bin/python与#!/usr/bin/env python的区别
  • #laravel 通过手动安装依赖PHPExcel#
  • #常见电池型号介绍 常见电池尺寸是多少【详解】
  • #微信小程序:微信小程序常见的配置传值
  • (20)目标检测算法之YOLOv5计算预选框、详解anchor计算
  • (安全基本功)磁盘MBR,分区表,活动分区,引导扇区。。。详解与区别
  • (六)Flink 窗口计算
  • (三)Pytorch快速搭建卷积神经网络模型实现手写数字识别(代码+详细注解)
  • (十六)一篇文章学会Java的常用API
  • (实战篇)如何缓存数据
  • (一)、软硬件全开源智能手表,与手机互联,标配多表盘,功能丰富(ZSWatch-Zephyr)
  • (一)UDP基本编程步骤
  • .net core 使用js,.net core 使用javascript,在.net core项目中怎么使用javascript
  • .NET Framework Client Profile - a Subset of the .NET Framework Redistribution
  • .net mvc 获取url中controller和action
  • .Net mvc总结
  • .net websocket 获取http登录的用户_如何解密浏览器的登录密码?获取浏览器内用户信息?...
  • .NET 线程 Thread 进程 Process、线程池 pool、Invoke、begininvoke、异步回调
  • .NET 中 GetHashCode 的哈希值有多大概率会相同(哈希碰撞)