通过案例学JDBC的使用

下面我们通过几个JDBC案例来理解JDBC在java中的应用

 

在开始学习案例之前,我们应该先对JDBC的使用流程和使用规范有一个大致了解

 

1.基本应用

JDBC使用规则:

JDBC调用流程:

1.将MySQL服务器厂商提供的Driver接口实现类注册到JVM

2.通过JDBC规范中DriverManager在Java工程与MySQL服务器之间建立一个[连接通道]

3.通过MySQL服务器厂商提供Connection接口实现类建立一个交通工具[PrepareStatement]

4.通过交通工具[PrepareStatement]将SQL命令从Java工程推送到MySQL服务器上执行 并带回执行结果

5.销毁本次交易过程中的所有资源对象

 

JDBC规范下接口介绍:

1.位置:存在于JDK_1.8.jar下java.sql包

2.分类:(1)java.sql.DriverManager类:这个类存在于JDK_1.8.负责将数据库厂商提供的Driver接口实行注册,负责在java和MySQL之间建立一个连接通道

(2)java.sql.Connection接口:

负责管理java工程与数据库服务器之间的连接通道

(3)java.sql.PreparedStatement接口:

负责管理在 连接通道 上进行往返运输的 交通工具

(4)java.sql.ResultSet接口:

负责管理数据库服务器所返回的临时表

 

了解了这些后我们便可以通过下面几个案例加强对JDBC使用流程的理解

 

案例一:通过JDBC向MySQL服务器推送添加数据命令

public class 推送添加命令 {

public static void main(String[] args) throws SQLException {

Driver driver = new com.mysql.jdbc.Driver();

DriverManager.registerDriver(driver);//这句可以省略

//1.将MySQL服务器提供的jar包中的driver接口实现类注册到JVM


String url = "jdbc:mysql://localhost:3306/name";

//ucr的格式:"jdbc:mysql//服务器所在计算机IP地址:服务端口号/数据库"

Connection connection = DriverManager.getConnection(url, "root", "233");//这里的root和233是指数据库的账户及密码

//2.通过DriverManager创建一个java和MySQL之间的通道并交给connection管理


PreparedStatement ps = connection.prepareStatement("");//3.在通道上建一个交通工具用于运输命令并交给ps管理

//注意这里应该是要放入SQL语句的,只不过我们只是定义,所以可以令它为空,相当于一辆"空车"


int result = ps.executeUpdate("insert into dept (deptno,dname,loc) values(88,'bookstore','CN')");

//4.通过交通工具ps将SQL命令推送到MySQL服务器上执行并带回处理结果

//返回的是添加数据的数量,如果添加的数据已经存在会导致异常


//5.销毁相关资源

if(ps!=null)//在销毁前应先确认ps是否任然存在,以防止程序出现异常导致ps已经销毁

{

ps.close();

}

if(connection!=null){

connection.close();

}


System.out.println("本次交易中共添加了"+result+"个数据");

}

}

 

 

案例二:通过JDBC向MySQL服务器推送更新数据命令

public class 推送更新命令 {

public static void main(String[] args) throws ClassNotFoundException, SQLException {

Class.forName("com.mysql.jdbc.Driver");//第二种将Driver实现类注册到JVM的方式


Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/name", "root", "233");


PreparedStatement ps = connection.prepareStatement("");


int result = ps.executeUpdate("update dept set loc = '贵州' where deptno <>90 ");


if(ps!=null){

ps.close();

}

if(connection!=null){

connection.close();

}

System.out.println("本次交易更新了"+result+"条数据");

}

}

 

案例三:通过JDBC向MySQL服务器推送查询命令

public class 推送查询命令 {

public static void main(String[] args) throws ClassNotFoundException, SQLException {

String sql ="select dname from dept where dname like '_c%'";//书写查询语句

Class.forName("com.mysql.jdbc.Driver");

Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/name", "root", "cjysql233");

PreparedStatement ps = connection.prepareStatement("");

ResultSet rs = ps.executeQuery(sql);

//使用while遍历ResultSet得到查询结果

while (rs.next()){

String dname = rs.getString("dname");

System.out.println(dname);

}

//注意ResultSet建立在PrepareStatement之上,所以应该先做完对ResultSet的操作再关闭Statement

if(rs!=null){

rs.close();

}

if(ps!=null){

ps.close();

}

if(connection!=null){

connection.close();

}

}

}

 

通过以上三个案例,我们大概就了解了JDBC在java中的使用流程,但我们也会发现这三个简单案例存在着许多问题,最突出的有

1.SQL语句书写繁琐,容易出错

2.executeUpdate()每次执行,都是要将java->MySQL->java进行一圈,造成了时间和空间的大量浪费

3.没有运用到MySQL中的事务功能,实际运用中大多数的操作应该都是由事务来处理的

那么我们如何解决这些问题呢

可以通过接下来的两个案例来体会一下

 

2.事务管理与批处理

 

案例四:事务管理


 

/*

规则:

在一个需求中,只要有任一个SQL命令无法执行,此时应将需求中所SQL命令都判定为执行失效

*/

public class 事务管理 {

public static void main(String[] args) throws ClassNotFoundException, SQLException {

Class.forName("com.mysql.jdbc.Driver");

Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/name","root","233");

//通过连接通道推送 "start transaction"命令,开启一个事务

connection.setAutoCommit(false);

//如果连接处于自动提交模式下,则其所有的SQL语句将作为单个事务运行并提交。否则,其SQL语句将作为事务组,直到调用Commit方法或rollback方法为止。默认情况下,新连接处于自动提交模式。

//setAutoCommit传入得值为true时,将启用自动提交模式,此时SQL语句有MySQL服务器进行管理,传入false时,关闭自动提交,开启一个事务,此时SQL语句由事务进行管理

PreparedStatement ps = connection.prepareStatement("");


//注意:只有当表的存储引擎为innodb时才会有备份,事务的回滚才能使用,可以使用 alter table 表名 engine = innodb语句来将表的存储引擎设置为innodb,通过show create table 表名 来查看当前表的存储引擎

try{//通过try..catch..来捕获异常确保当任一SQL语句出现问题时,能够对本次事务进行回滚,将本次操作中所有文件的备份覆盖表文件,取消本次操作

ps.executeUpdate("delete from emp where deptno = 20");

ps.executeUpdate("delete from dept where deptno= 20");

//如果能走到这里则证明推送的SQL语句都能正常运行,故而可以提交数据,关闭事务,通知MySQL服务器将备份文件删除

connection.commit();//向MySQL服务器推送 "commit;"关闭事务

}catch (SQLException sqlException){

connection.rollback();//向MySQL服务器推送 "rollback;"进行回滚

}finally {

//销毁

if (ps != null) {

ps.close();

}

if (connection != null) {

connection.close();

}

}

}

}

案例五:批处理尝试


public class 批处理尝试 {

public static void main(String[] args) throws SQLException, ClassNotFoundException {

//预编译形式SQL语句

String sql ="insert into dept (deptNo,dname,loc) values (?,?,?)";

//"?"是占位符,一个问号代表一个值

//预编译SQL相当于一个模具,在后续开发时,只需要将数据填充到占位符,就可以得到一个全新的SQL



Class.forName("com.mysql.jdbc.Driver");

Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/name", "root", "cjysql233");

//我们建立交通工具时,需要将预编译SQL语句注册到PrepareStatement中

PreparedStatement ps = connection.prepareStatement(sql);

for(int i = 0;i<=50;i++){

//通过向预编译SQL语句中填充数据来生成新的SQL命令

ps.setInt(1,i);// 1 指ps所装载的预编译SQL语句中的第一个占位符"?",后面的 i 就是要填入占位符的数据

ps.setString(2,"dept"+i);

ps.setString(3,"CN");

//为了实现SQL语句能成批进行运送处理,而不是一次一次的单独完成往返任务,我们需要像填充子弹一样将已经写好的SQL语句填入"弹夹",等待一起发射

ps.addBatch();//将SQL语句加入弹夹

}

int[] ints = ps.executeBatch();//[一次性]将所有SQL语句推送到MySQL服务器,即"扣动扳机",Batch其实是一个list

//executeBatch()返回一个整形数组,数组内的值为其"弹夹"内的每一条语句所影响的行数,其中如果返回-2的值,表示命令为处理成功,但受影响的行数为未知,返回-3表示该语句无法执行,驱动程序将跳过它继续向下处理

//如果批量更新中的命令之一无法正确执行,此方法引发BatchUpdateException,JDBC driver可能会也可能不会继续处理剩余的命令。但是driver的行为是与特定的DBMS绑定的,要么总是继续处理命令,要么从不继续处理命令。如果驱动程序继续处理,方法将返回 EXECUTE_FAILED(-3)。


for (int i = 0; i < ints.length; i++) {

System.out.println("语句"+i+"执行成功,进行了"+ints[i]+"个操作");

}

if(ps!=null){

ps.close();

}

if (connection != null) {

connection.close();

}

}

}

 

这下就可以解决之前出现的那些问题啦

虽然这样也能进行对数据库的增删改查操作,但实际运用中我们更多的是采用封装的方式,因此我们也要知道JDBC的工具类是如何封装的,可以看看下面这个文章了解一下

  JDBC封装

这些案例主要来源于动力节点老杨的课程,感兴趣的同学可以看看B站动力节点java web

以上是我自己整理的笔记和理解,如果有错误欢迎大家评论区交流指正,如果有什么好的课程也希望大家能分享一下呀

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值