一、添加数据  

  在SQL语句中,一条INSERT语句只能添加一条记录,因此分为几种情况进行添加数据操作。

  1.添加一条记录

  (1)如果只需要添加一条记录,通常情况下通过Statament实例完成。

        try {
Connection conn = DriverManager.getConnection(Url, User, Password);
Statement statement = conn.createStatement(); String sql = "insert into user(id, name, sex, birthday) values(4, 'winner', '男', '2018-08-07')";
int num = statement.executeUpdate(sql);
System.out.println(num);  // 打印:1 statement.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}

  (2)通过PreparedStatement实例添加单条记录时,在设置完参数值后,需要调用executeUpdate()方法。

        try {
Connection conn = DriverManager.getConnection(Url, User, Password); String sql = "insert into user(id, name, sex, birthday) values(?,?,?,?)";
PreparedStatement prepStatement = conn.prepareStatement(sql);
prepStatement.setInt(1, 5);
prepStatement.setString(2, "zigbee");
prepStatement.setString(3, "女");
prepStatement.setDate(4, new Date(System.currentTimeMillis()));
int num = prepStatement.executeUpdate();
System.out.println(num);  // 打印:1 prepStatement.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}

  (3)通过CallableStatement实例添加单条记录时,在设置完参数值后,也需要调用executeUpdate()方法。

  创建包含INSERT语句的存储过程并测试

mysql> delimiter //
mysql> create procedure proc_insert(IN userId INT(11), IN userName VARCHAR(255), IN userSex VARCHAR(255), IN userBir DATE )
-> BEGIN
-> INSERT INTO user(id, name, sex, birthday)VALUES(userId, userName, userSex, userBir);
-> END
-> //
Query OK, 0 rows affected (0.00 sec) mysql> call proc_insert(6, 'tmz', '女', '1996-01-01') //
Query OK, 1 row affected (0.01 sec) mysql> select * from user where id=6 //
+----+------+------+------------+
| id | name | sex | birthday |
+----+------+------+------------+
| 6 | tmz | 女 | 1996-01-01 |
+----+------+------+------------+
1 row in set (0.00 sec)

  通过CallableStatement实例调用包含单条INSERT记录的存储过程

        try {
Connection conn = DriverManager.getConnection(Url, User, Password); String sql = "{call proc_insert(?,?,?,?)}";
CallableStatement callStat = conn.prepareCall(sql);
callStat.setInt(1, 7);
callStat.setString(2, "python");
callStat.setString(3, "女");
callStat.setDate(4, new Date(System.currentTimeMillis()));
int num = callStat.executeUpdate();
System.out.println(num); callStat.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}

  2.添加多条记录

  (1)通过Statement实例反复执行静态INSERT语句完成,但是每条SQL语句都要单独提交一次,即调用一次executeUpdate方法。

statement.executeUpdate("insert into user(id, name, sex, birthday) values(4, 'winner', '男', '2018-08-07')");
statement.executeUpdate("insert into user(id, name, sex, birthday) values(5, 'winner', '女', '2018-08-06')");

  (2)通常通过PreparedStatement实例批量执行Batch中所有的动态INSERT语句完成。

        try {
Connection conn = DriverManager.getConnection(Url, User, Password); Object[][] records = {{8,"eight","女",new Date(System.currentTimeMillis())},
{9,"nine", "男",new Date(System.currentTimeMillis())}};
String sql = "insert into user(id, name, sex, birthday) values(?,?,?,?)";
PreparedStatement prepStatement = conn.prepareStatement(sql); prepStatement.clearBatch(); // 清空Batch
for (int i = 0; i < records.length; i++) {
prepStatement.setInt(1, (int) records[i][0]);
prepStatement.setString(2, (String) records[i][1]);
prepStatement.setString(3, (String) records[i][2]);
prepStatement.setDate(4, (Date) records[i][3]);
prepStatement.addBatch(); // 将INSERT语句添加到Batch中
}
prepStatement.executeBatch(); // 批量执行Batch中的INSERT语句 prepStatement.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}

  (3)通常也可以通过CallableStatement实例多次执行只包含一条INSERT语句的存储过程完成。

  同理,将上面的代码中的PreparedStatement prepStatement = conn.prepareStatement(sql);改成调用存储过程,其他均一样即可。

String sql = "{call proc_insert(?,?,?,?)}";
CallableStatement callStat = conn.prepareCall(sql);

  二、查询数据

  无论利用哪个实例查询数据,只要执行需要执行SELECT语句,就必须要执行executeQuery()方法,并且返回一个ResultSet类型的结果集。

  (1)通过Statement实例执行静态SELECT语句完成。

ResultSet rs = statement.executeQuery("select * from user where sex='男'");

  (2)通过PreparedStatement实例执行动态SELECT语句完成。

PreparedStatement predStatement = conn.prepareStatement("select * from user where sex=? ");
predStatement.setString(1, "女");
predStatement.executeQuery();

  (3)通过CallableStatement实例执行包含SELECT语句的存储过程完成。

String sql = "{call proc_count_select_by_sex(?)}";
CallableStatement cablStat = conn.prepareCall(sql);
cablStat.setString(1, "女");
cablStat.executeQuery();

  (4)在获得查询结果集ResultSet类型的对象后,可以通过getMetaData()方法得到ResultSet实例的相关信息

            ResultSet rs_queue = statement.executeQuery("select * from user where sex='男'");

            ResultSetMetaData metaData = rs_queue.getMetaData();
System.out.println(metaData.getColumnCount());   // 打印:4
System.out.println(metaData.getColumnName(3));     // 打印:sex
System.out.println(metaData.getColumnTypeName(3)); // 打印:VARCHAR while (rs_queue.next()) { // 遍历查询到的结果集
System.out.println(rs_queue.getInt("id") + " "
+ rs_queue.getString("name") + " "
+ rs_queue.getString("sex") + " "
+ rs_queue.getString("birthday"));
}

  三、修改数据

  无论利用哪个实例修改数据,只要执行需要执行UPDATE语句,就必须要执行executeUpdate()方法,该方法将返回一个int类型的整数,是被修改记录的条数。

  (1)通过Statement实例执行静态UPDATE语句完成。

statement.executeUpdate("update user set sex='女' where id=1")

  (2)通过PreparedStatement实例执行动态UPDATE语句完成。

            Connection conn = DriverManager.getConnection(Url, User, Password);
String sql = "update user set name = ?, sex = ?, birthday = ?where id =?";
PreparedStatement predStatement = conn.prepareStatement(sql);
predStatement.setString(1, "loser");
predStatement.setString(2, "女");
predStatement.setDate(3, new Date(System.currentTimeMillis()));
predStatement.setInt(4, 1);
System.out.println(predStatement.executeUpdate());
predStatement.close();

  (3)通过CallableStatement实例执行包含UPDATE语句的存储过程完成。(略)

  (4)通过PreparedStatement实例利用Batch一次执行多条UPDATE语句实现修改多条记录。(略)

  四、删除数据 

  无论利用哪个实例删除数据,只要执行需要执行DELETE语句,就必须要执行executeUpdate()方法,该方法将返回一个int类型的整数,是被删除记录的条数。

  (1)通过Statement实例执行静态DELETE语句完成。

statement.executeUpdate("delete from user where birthday<'2018-08-07'")

  (2)通过PreparedStatement实例执行动态DELETE语句完成。(略)

  (3)通过CallableStatement实例执行包含DELETE语句的存储过程完成。(略)

  (4)通过PreparedStatement实例使用Batch一次执行多条DELETE语句实现删除多条记录。(略)

  五、JDBC事务

  事务是指一组相互依赖的操作单元的集合,用来保证对数据库的正确修改,保持数据的完整性,如果一个事务的某个单元操作失败,将取消本次事务的全部操作。

  数据库事务的四大特征(ACID):

  • 原子性(Atomic)
  • 一致性(Consistency)
  • 隔离性(Isolation)
  • 持久性(Durability)

  以银行转账为例使用JDBC实现数据库事务:

  1.设置不自动提交事务

  2.清空Batch

  3.插入转入账户记录到Batch

  4.插入转出账户记录到Batch

  5.执行Batch中所有语句

  6.提交此次事务

  7.判断事务提交后即转账完成后,账户余额是否小于0,如果小于0,则回滚此次事务

  JDBC实现数据库事务是通过Connection的实例完成的,其中包含了一些与事务相关的方法:

  • setAutoCommit(false):设置为不自动提交
  • getAutoCommit():查看当前是否处于自动提交模式,如果是则返回true,否则返回false。
  • commit():将从上一次提交或回滚以来进行的所有更改同步到数据库
  • rollback():取消当前事务中的所有更改

  代码举例:

public String turnMoney(int outAccount, int inAccount, int money) {
String info = "转账成功!";
Connection conn = null;
try {
conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
conn.setAutoCommit(false);// 设置为不自动提交
String sql = "insert into tb_note(account_id,operate_money,total_money,date) values(?,?,?,getdate())";
PreparedStatement prpdStmt = conn.prepareStatement(sql);
prpdStmt.clearBatch();
prpdStmt.setInt(1, inAccount);
prpdStmt.setInt(2, money);
prpdStmt.setInt(3, getTotalMoney(inAccount) + money);
prpdStmt.addBatch();// 插入转入账户记录
prpdStmt.setInt(1, outAccount);
prpdStmt.setInt(2, -money);
prpdStmt.setInt(3, getTotalMoney(outAccount) - money);
prpdStmt.addBatch();// 插入转出账户记录
prpdStmt.executeBatch();
prpdStmt.close();
conn.commit();// 提交此次事务
} catch (SQLException e) {
try {
info = "转账失败,您的账户余额不足!";
conn.rollback();// 回滚此次事务
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
} finally {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return info;
}

Java基础(三十三)JDBC(3)操作数据库的更多相关文章

  1. Java基础-面向接口编程-JDBC详解

    Java基础-面向接口编程-JDBC详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.JDBC概念和数据库驱动程序 JDBC(Java Data Base Connectiv ...

  2. Java基础教程:JDBC编程

    Java基础教程:JDBC编程 1.什么是JDBC JDBC 指 Java 数据库连接,是一种标准Java应用编程接口( JAVA API),用来连接 Java 编程语言和广泛的数据库. JDBC A ...

  3. “全栈2019”Java第三十三章:方法

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  4. jdbc原生操作数据库

    jdbc原生操作数据库流程: 第一步:Class.forName()加载数据库连接驱动: 第二步:DriverManager.getConnection()获取数据连接对象; 第三步:根据 SQL 获 ...

  5. Java基础之原生JDBC操作数据库

    前言 日常开发中,我们都习惯了使用ORM框架来帮我们操作数据库,本文复习.记录Java如何使用原生JDBC操作数据库 代码编写 封装几个简单方法 find查询方法 findOne查询方法 update ...

  6. JAVA采用JDBC连接操作数据库详解

    JDBC连接数据库概述 一.JDBC基础知识 JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供 ...

  7. 重学 Java 设计模式:实战中介者模式「按照Mybaits原理手写ORM框架,给JDBC方式操作数据库增加中介者场景」

    作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 同龄人的差距是从什么时候拉开的 同样的幼儿园.同样的小学.一样 ...

  8. Java进阶(三十三)java基础-filter

    java基础-filter 我们先看看没有filter的时候,整个web客户端-服务端的一个流程. 接下来我们再看看引入了filter之后的Uml图.尝试分析这两者之间的差别. filter从哪里来? ...

  9. 使用JDBC连接操作数据库

    JDBC简介 Java数据库连接(Java Database Connectivity,JDBC),是一种用于执行SQL语句的Java API,它由一组用Java编程语言编写的类和接口组成. JDBC ...

  10. 在java程序中使用JDBC连接mysql数据库

    在java程序中我们时常会用到数据库中的数据或操作数据库中的数据,如果java程序没有和我们得数据库连接,就不能实现在java程序中直接操作数据库.使用jdbc就能将java程序和数据库连起来,此时我 ...

随机推荐

  1. 夯实Java基础系列6:一文搞懂抽象类和接口,从基础到面试题,揭秘其本质区别!

    目录 抽象类介绍 为什么要用抽象类 一个抽象类小故事 一个抽象类小游戏 接口介绍 接口与类相似点: 接口与类的区别: 接口特性 抽象类和接口的区别 接口的使用: 接口最佳实践:设计模式中的工厂模式 接 ...

  2. Ubuntu su命令 Authentication failure的解决办法

    重新设置root的密码: $ sudo passwd root Enter new UNIX password: Retype new UNIX password: passwd: password ...

  3. windows下 python 如何安装pygame模块

    本机系统:win7,Pyhon版本: 3.6.0 1. 安装下载python官网 https://www.python.org/ 下载地址 https://www.python.org/downloa ...

  4. jq中attr()和prop() 属性的区别

    query1.6中新加了一个方法prop(),一直没用过它,官方解释只有一句话:获取在匹配的元素集中的第一个元素的属性值. 大家都知道有的浏览器只要写disabled,checked就可以了,而有的要 ...

  5. Thinkphp5.0第五篇

    原样输出 使用literal标签防止模板标签被解析 例如 {literal} {$name}<br/> {/literal} 模板单行注释 {//注释内容} 多行注释 {/*注释内容*/} ...

  6. TCP/UDP的小事情

    UDP: 没有复杂的控制机制,面向无连接的通信服务. 常用于: 包总量少的通信 音视频传输(即时通信) TCP: 对传输.发送.通信.进行控制的协议.面向有连接的协议,只有在确认通信对端存在时才会发送 ...

  7. CentOS 8 网卡设置

    本次测试环境是在虚拟机上测试 网卡配置文件路径:/etc/sysconfig/network-scripts/ifcfg-ens33 [root@localhost ~]# cd /etc/sysco ...

  8. 浅谈sqlserver的事务锁

    锁的概述 一. 为什么要引入锁 多个用户同时对数据库的并发操作时会带来以下数据不一致的问题: 丢失更新 A,B两个用户读同一数据并进行修改,其中一个用户的修改结果破坏了另一个修改的结果,比如订票系统 ...

  9. tesseract 测试样例

    该图片的链接为https://raw.githubusercontent.com/Python3WebSpider/TestTess/master/image.png,可以直接保存或下载. 首先用命令 ...

  10. requests模块(get请求)篇

    - HTTP for Humans,更简洁更友好- 继承了urllib的所有特征- 底层使用的是urllib3- 开源地址: https://github.com/requests/requests- ...