Java研学-jdbc(二)

六 代码重构

  对于需要反复编写的这种代码,可以将其抽取到工具类中,简化开发,以及将可能会修改的值抽取到properties文件中,解决硬编码的问题
工具类

public class JDBCUtil {private static Connection connection=null;/*加载驱动创建连接只需要执行一次*/static {try {//创建Properties对象Properties properties=new Properties();//加载外面的配置文件 通过当前线程获取类加载器,从而获取当前项目根路径下的文件InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties");properties.load(is);//读取外部配置文件的内容String driver = properties.getProperty("jdbc.driver");String url = properties.getProperty("jdbc.url");String user = properties.getProperty("jdbc.user");String password = properties.getProperty("jdbc.password");Class.forName(driver);connection= DriverManager.getConnection(url,user,password);} catch (Exception e) {e.printStackTrace();}}/*加载驱动创建连接对象*/public static Connection getConnection(){return connection;}/*关闭对象释放资源*/public static void close(Connection connection,Statement statement,ResultSet resultSet){try {if (resultSet!=null){resultSet.close();}if (statement!=null){statement.close();}if(connection!=null){connection.close();}} catch (Exception e) {e.printStackTrace();}}
}

properties文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///web_crud
jdbc.user=root
jdbc.password=root

实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Employee {private Long id;private String ename;private String job;private String eid;private Integer salary;
}

接口

public interface IEmployeeDao {//修改员工public void updateEmployee(Employee employee);//增加员工public void addEmployee(Employee employee);//根据id查询员工public Employee queryById(int id);//查询所有public List<Employee> queryALl();
}

实现类

public class EmployeeDaoImpl implements IEmployeeDao {/*修改员工*/@Overridepublic void updateEmployee(Employee employee) {try {// 使用工具类创建连接对象Connection connection = JDBCUtil.getConnection();String sql="update t_employee  set eid=? ,ename=? ,job=?,salary=? WHERE id=?";PreparedStatement statement = connection.prepareStatement(sql);statement.setObject(1,employee.getEid());statement.setObject(2,employee.getEname());statement.setObject(3,employee.getJob());statement.setObject(4,employee.getSalary());statement.setObject(5,employee.getId());statement.executeUpdate();JDBCUtil.close(connection,statement,null);} catch (Exception e) {e.printStackTrace();}}/*增加员工*/@Overridepublic void addEmployee(Employee employee) {try {Connection connection = JDBCUtil.getConnection();String sql="insert into t_employee(eid,ename,job,salary)values(?,?,?,?)";PreparedStatement statement = connection.prepareStatement(sql);statement.setObject(1,employee.getEid());statement.setObject(2,employee.getEname());statement.setObject(3,employee.getJob());statement.setObject(4,employee.getSalary());statement.executeUpdate();JDBCUtil.close(connection,statement,null);} catch (Exception e) {e.printStackTrace();}}/*根据id查询*/@Overridepublic Employee queryById(int id) {try {Connection connection = JDBCUtil.getConnection();String sql="SELECT * from t_employee WHERE id=?";PreparedStatement statement = connection.prepareStatement(sql);statement.setObject(1,id);//执行查询:将查询的员工信息封装在返回结果集对象中ResultSet resultSet = statement.executeQuery();//遍历集合Employee employee=null;while (resultSet.next()){//当遍历的集合中有数据,就获取里面的信息//循环依次获取数据库表的一行数据//获取字段信息Long tid = resultSet.getLong("id");String eid = resultSet.getString("eid");String ename = resultSet.getString("ename");String job = resultSet.getString("job");int salary = resultSet.getInt("salary");//创建员工对象:使用有参构造实例化对象employee=new Employee(tid,eid,ename,job,salary);}JDBCUtil.close(connection,statement,resultSet);//返回员工对象return  employee;} catch (Exception e) {e.printStackTrace();}return null;}//查询所有@Overridepublic List<Employee> queryALl() {try {Connection connection = JDBCUtil.getConnection();String sql="SELECT * FROM t_employee";PreparedStatement statement = connection.prepareStatement(sql);ResultSet resultSet = statement.executeQuery();//创建返回的集合对象List<Employee> list=new ArrayList<>();//遍历结果对象while (resultSet.next()){//获取每个员工表数据的列字段信息Long tid = resultSet.getLong("id");String eid = resultSet.getString("eid");String ename = resultSet.getString("ename");String job = resultSet.getString("job");int salary = resultSet.getInt("salary");//将获取的数据封装到员工对象Employee employee=new Employee(tid,eid,ename,job,salary);//将员工对象添加到集合中list.add(employee);}JDBCUtil.close(connection,statement,resultSet);return list;} catch (Exception e) {e.printStackTrace();}return null;}
}

数据库表

CREATE TABLE `t_employee` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`eid` varchar(10) NOT NULL,`ename` varchar(6) NOT NULL,`job` varchar(10) DEFAULT NULL,`salary` int(10) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `eid` (`eid`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;

七 事务

1 概述

  事务是指将一组操作括为一个单元,为确保数据库中数据的一致性,数据操作是成组的单元,当单元中的一部分操作失败,整个事务应全部视为错误,所有从起始点以后的操作应全部回退到开始状态。

2 事务的 ACID 属性 – 作用

  ① 原子性(Atomicity): 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
  ②一致性(Consistency): 保证数据的完整性,数据不被破坏,事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
  ③ 隔离性(Isolation): 指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
  ④ 持久性(Durability): 指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响

3 操作步骤

  ① 先定义开始一个事务,然后对数据作修改操作,
  ② 执行过程中,如果没有问题就提交(commit)事务,此时的修改将永久地保存下来
  ③ 如果执行过程中有问题(异常),回滚事务(rollback),数据库将放弃本次事务的所有修改回到开始事务时的状态。

4 例子 – 转账操作

不使用事务 – 异常会导致账户金额问题

public class AccountTest {public static void main(String[] args) throws Exception {//1.创建连接对象Connection connection = JDBCUtil.getConnection();//2.创建sql执行对象String sql="SELECT * from account WHERE name='大黄'";PreparedStatement statement = connection.prepareStatement(sql);//3.执行查询转出账号的余额查询ResultSet resultSet = statement.executeQuery();if (!resultSet.next()){System.out.println("账号不存在!");return;}//判断余额是否大于500BigDecimal balance = resultSet.getBigDecimal("balance");if (balance.intValue()<5000){System.out.println("目标账号余额不足!");return;}//4.执行转出操作String sql1="update account set balance =balance- 5000 WHERE name='大黄'";statement = connection.prepareStatement(sql1);statement.executeUpdate();//模拟异常int num= 1/0;//5.执行转入操作String sql2="update account set balance =balance+ 5000 WHERE name='大白'";statement = connection.prepareStatement(sql2);statement.executeUpdate();//6.关闭对象JDBCUtil.close(connection,statement,resultSet);}
}

使用事务

public class AccountTXTest {public static void main(String[] args)  {Connection connection=null;try {//1.创建连接对象connection = JDBCUtil.getConnection();//开启事务手动提交connection.setAutoCommit(false);//2.创建sql执行对象String sql="SELECT * from account WHERE name='大黄'";PreparedStatement statement = connection.prepareStatement(sql);//3.执行查询转出账号的余额查询ResultSet resultSet = statement.executeQuery();if (!resultSet.next()){System.out.println("账号不存在!");return;}//判断余额是否大于500BigDecimal balance = resultSet.getBigDecimal("balance");if (balance.intValue()<5000){System.out.println("目标账号余额不足!");return;}//4.执行转出操作String sql1="update account set balance =balance- 5000 WHERE name='大黄'";statement = connection.prepareStatement(sql1);statement.executeUpdate();//模拟异常//int num= 1/0;//5.执行转入操作String sql2="update account set balance =balance+ 5000 WHERE name='大白'";statement = connection.prepareStatement(sql2);statement.executeUpdate();//手动提交事务connection.commit();System.out.println("转账成功,提交事务!");//6.关闭对象JDBCUtil.close(connection,statement,resultSet);} catch (Exception e) {System.out.println("转账异常,回滚事务!");e.printStackTrace();try {//转帐出现异常,回滚事务connection.rollback();} catch (SQLException ex) {ex.printStackTrace();}}}
}

工具类

public class JDBCUtil {private static Connection connection=null;/*加载驱动创建连接只需要执行一次*/static {try {Class.forName("com.mysql.jdbc.Driver");connection= DriverManager.getConnection("jdbc:mysql:///web_crud","root","root");} catch (Exception e) {e.printStackTrace();}}public static Connection getConnection(){return connection;}public static void close(Connection connection,Statement statement,ResultSet resultSet){try {if(connection!=null){connection.close();}if (statement!=null){statement.close();}if (resultSet!=null){resultSet.close();}} catch (Exception e) {e.printStackTrace();}}
}

数据库表

CREATE TABLE account(
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20),
balance DECIMAL(10,2)
);
INSERT INTO account(name,balance) VALUES('大黄',18000),('大白',0);

5 小结

① 默认事务在执行完 DML 操作就自动提交.
② 查询操作,不需要事务
③ 代码正确无异常,但数据库数据不变,有可能是没有提交事务
④ MySQL ,中 InnoDB 存储引擎支持事务,支持外键,MyISAM 不支持事务.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/218522.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言 二叉树详解(自我理解版)!!!二叉树的实现

目录 1.树的概念和结构&#xff08;了解&#xff09; 1.1树的概念 1.2关于树的每个组成结构的叫法 1.3树的结构体表示 1.4树在实际中的运用 2.二叉树的概念和结构和实现&#xff08;本期偏重点之一&#xff09; 二叉树的概念 ​编辑 特殊的二叉树 1.完全二叉树 2.满二…

Unity 实现单例模式

目录 基本概念 饿汉模式(推荐) 懒汉模式&#xff1a; 基本概念 单例模式&#xff1a;类只有一个实例&#xff0c;一般使用static来实现单例模式&#xff1b; 比如&#xff1a;有一个Test类,实现了单例&#xff0c;假设这个唯一的实例名为SingTonle,实例在类内被实现并被stat…

MAX/MSP SDK学习09:重要示例1

本示例涉及到单个MSP对象同时使用Signal类型、Message类型的入口&#xff1b;代理入口的使用。 注意&#xff1a;MSP对象的入口默认为代理入口&#xff0c;因此Signal类型、Message类型的数据都可接收&#xff1b; #include "ext.h" #include "ext_obex.h&…

【FPGA图像处理实战】- 图像行缓存设计实现方式一(FIFO)

图像处理中稍复杂点的算法,就需要行缓存,以实现3*3窗口、6*6窗口的数据计算。 本文将介绍使用FIFO来实现图像行缓存的设计,包括关键逻辑分析,源代码实现分享。 一、行缓存功能的设计框架 图像数据一般都是按照从左到右,从上到下,一行行数据的方式发送传输的。 这里以…

Java 重写(Override)与重载(Overload)的对比

Java中的重写(Override)和重载(Overload)是两种不同的方法重写/重载的概念。下面是重写和重载的对比及示例代码&#xff1a; 重写(Override) 重写是指在子类中重新定义父类中已有的方法&#xff0c;以便在子类中实现不同的行为。子类中的重写方法必须具有相同的方法名、参数列…

机器学习三个基本要素:优化算法

在确定了训练集 D、假设空间 ℱ 以及学习准则后&#xff0c;如何找到最优的模型&#x1d453;(x,θ∗) 就成了一个最优化&#xff08;Optimization&#xff09;问题。机器学习的训练过程其实就是最优化问题的求解过程。 参数与超参数 在机器学习中&#xff0c;优化又可以分为参…

mybatis查询结果resultMap映射vo源码分析

概述 mybatis是一个常用的持久层框架&#xff1b;通常搭配mysql使用&#xff1b; 在将查询结果映射成一个复杂vo的时候&#xff0c;通常会用到resultMap&#xff0c;在其中嵌套association和collection等操作&#xff1b;将一个复杂查询拆分成简单查询&#xff1b; 在vo中的变…

数据云:数据基础设施的一小步,数字经济的一大步

随着数字经济的崛起&#xff0c;数据正成为推动社会发展和经济增长的核心要素。在这个数字化时代&#xff0c;数据已经被誉为新的生产要素&#xff0c;是数字经济发展的基础性资源和战略性资源。为了更好地支持数据的汇聚、流通和应用&#xff0c;数据基础设施迎来了一次重要的…

WSL 配置 Docker 内存和 CPU 资源限制

我用的电脑一共有40G内存&#xff0c;最近发现电脑重启后&#xff0c;VmmemWSL 进程很快就会占用一多半的内存&#xff08;20G&#xff09;&#xff0c;电脑中有多个停止运行的容器&#xff0c;正常启动状态的只有一个 MySQL 服务&#xff0c;通过 docker stats 查看占用内存也…

PyCharm安装教程

1.1 为什么要安装python开发环境 上一篇文章我们安装了python&#xff0c;准确来说是python解释器&#xff0c;它没有自带的可视化开发工具&#xff0c;只能通过命令行窗口来执行python代码&#xff0c;这里我们就来下载一个用于python开发的可视化工具——PyCharm。 1.2 PyC…

boost1.55 安装使用教程 windows

第一步 &#xff1a;首先在boost官网上下载库压缩包 添加链接描述 选择自己需要的版本进行下载 解压后执行booststrap.bat 用来生成创建b2.exe 和bjam.exe 拓展&#xff1a;.\b2 --help 了解一下有哪些参数可以配置 默认b2.exe编译后&#xff0c;链接到项目如果出现如下错误…

人工智能基本常识:让深度学习技术更加人性化

近年来&#xff0c;人工智能技术日臻成熟。现在&#xff0c;许多产品和服务都依靠人工智能技术实现自动化和智能化&#xff0c;因此它与我们的日常生活息息相关。无论是为我们带来各种便利的家用设备&#xff0c;还是我们一直在使用的产品制造方式&#xff0c;人工智能的影响无…

低代码开发与传统软件开发:未来趋势与竞争格局

近年来&#xff0c;低代码开发平台的快速发展引起了各行各业的广泛关注。低代码开发平台简化了软件开发的复杂性&#xff0c;提供了更快速、更灵活的开发方式。于是&#xff0c;许多人开始产生一个疑问&#xff1a;未来低代码开发是否会取代传统软件开发&#xff1f;今天这篇文…

ThinkPHP6使用Validate验证表单字段唯一

ThinkPHP6使用Validate验证表单字段唯一 1.创建用户验证文件&#xff0c;如User 1.1 单应用创建验证文件 php think make:validate User 1.2 多应用创建验证文件&#xff0c;admin为应用名&#xff0c; php think make:validate adminUser 创建成功后&#xff0c;应用内会…

java8与java9新特性对比

Java 8和Java 9是Java语言的两个重要版本&#xff0c;它们分别引入了许多新的特性和改进。下面是Java 8和Java 9的一些主要特性对比&#xff1a; Lambda表达式和函数式接口 Java 8引入了Lambda表达式和函数式接口&#xff0c;使得在Java中能够更方便地编写函数式风格的代码。L…

nodejs微信小程序+python+PHP沧州地区空气质量数据分析系统-计算机毕业设计推荐 django

本系统不仅主要实现了注册登录&#xff0c;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;城市区域管理&#xff0c;空气状况管理&#xff0c;空气质量管理&#xff0c;系统管理&#xff0c;数据爬取&#xff0c;大屏分析等功能&#xff0c;通过这些功能基本可…

CompressAI benchmark经典/传统图像编码器的使用

文章目录 使用简介安装依赖编译安装BPG 使用简介 CompressAI的github仓库中Usage-Evaluation给出了传统编解码器的使用帮助&#xff0c;但是并未给出详细的使用方法。本文旨在进行总结使用方法。下图是传统编解码器相关代码的存放地点&#xff0c;其中codecs为各种编解码器类的…

Java版企业电子招标采购系统源码—鸿鹄电子招投标系统-企业战略布局下的采购寻源

项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范&#xff0c;以及审…

Impala4.x源码阅读笔记(二)——Impala如何高效读取Iceberg表

前言 本文为笔者个人阅读Apache Impala源码时的笔记&#xff0c;仅代表我个人对代码的理解&#xff0c;个人水平有限&#xff0c;文章可能存在理解错误、遗漏或者过时之处。如果有任何错误或者有更好的见解&#xff0c;欢迎指正。 Iceberg表是一种用于存储大规模结构化数据的…

Shiro框架权限控制

首先去通过配置类的用户认证&#xff0c;在用户认证完成后&#xff0c;进行用户授权&#xff0c;用户通过授权之后再跳转其他的界面时&#xff0c;会进行一个验证&#xff0c;当前账号是否有权限。 前端权限控制显示的原理 在前端中&#xff0c;通常使用用户的角色或权限信息来…