jdbc-day01

ops/2024/9/23 6:28:12/

_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


http://www.ppmy.cn/ops/106303.html

相关文章

JVM 锁的种类

优质博文&#xff1a;IT-BLOG-CN 一、JVM 锁【偏向锁|轻量级锁|重量级锁】 对象头[每个对象都具有对象头] Mark&#xff1a;对象头的标记&#xff08;32位&#xff09;&#xff0c;描述对象的hash、锁信息、垃圾回收标记、年龄&#xff1b;内容包括&#xff1a;①、指向锁记录…

网关,DNS,MAC地址,子网掩码,网段分别是什么?

网关、DNS、MAC地址、子网掩码和网段是计算机网络中的基础概念&#xff0c;它们在网络通信和数据交换中扮演着关键角色。以下将详细解释每个概念及其功能&#xff1a; 网关 定义&#xff1a;网关&#xff08;Gateway&#xff09;又称网间连接器或协议转换器&#xff0c;是用于…

书客、孩视宝、雷士护眼大路灯怎么样?测评寻找顶尖机型天花板!

书客、孩视宝、雷士护眼大路灯怎么样&#xff1f;最近&#xff0c;众多读者纷纷表达了对护眼大路灯推荐和护眼大路灯测评的需求&#xff0c;希望能够提高室内光线质量&#xff0c;缓解孩子在长时间用眼带来的视觉疲劳、眼睛酸痛的问题。基于多年的使用经验&#xff0c;我汇总了…

Linux管道式操作命令

Linux管道&#xff08;Pipe&#xff09;是一种将一个命令的输出作为另一个命令输入的技术。管道操作符是|。这种机制非常强大&#xff0c;因为它允许你将多个简单的命令组合成复杂的操作&#xff0c;实现数据的流式处理。 以下是一些常见的管道式操作命令的例子&#xff1a; …

去中心化身份验证:Web3时代数字身份的革新

随着Web3时代的到来&#xff0c;去中心化技术正在重新定义数字身份验证的方式。传统的身份验证方法常常依赖于中心化的数据库和中介机构&#xff0c;这些系统不仅易受攻击&#xff0c;还可能侵犯用户的隐私。而去中心化身份验证&#xff08;DID, Decentralized Identifier&…

如何优化浏览器缓存

每当用户访问您的网站&#xff0c;他他们的浏览器需要从服务器上下载页面显示所需的资源&#xff08;图片、CSS、JavaScript 和字体等&#xff09;&#xff0c;这些资源的下载会占用带宽&#xff0c;并需要一定的传输时间。但通过正确配置&#xff0c;您可以告知用户的浏览器保…

opencv轮廓近似,模板匹配

在图像处理领域&#xff0c;轮廓近似和模板匹配是两种非常关键的技术&#xff0c;它们广泛应用于计算机视觉、图像分析和图像识别等多个方面。本文将详细介绍如何使用OpenCV库进行轮廓近似和模板匹配&#xff0c;并给出具体的代码示例。 一、轮廓近似&#xff08;Contour Appr…

[Labview] 表格改值后单元格编辑功能,更改颜色、字体、颜色等

效果如下所示&#xff1a; 例子中演示了单元格变色&#xff0c;具体需要什么修改&#xff0c;在相同的位置进行操作即可。 检测到[鼠标释放]事件&#xff0c;则记录被选中的单元格。 使用[鼠标按下]事件也可以&#xff0c;不过我个人测试下来&#xff0c;[按下]的判断精准度不…