Java研学-jdbc(一)

一 概述

1 持久化概述

  持久化(persistence): 把内存中的数据保存到可掉电式存储设备 (硬盘、U盘等) 中以供之后使用。
  数据持久化是将数据保存到各种关系数据库, 而在 Java中,数据库存取技术只能通过 jdbc 来访问数据库。jdbc 是 Java 语言访问数据库的基石,其他技术都是对 jdbc 的封装.

2 JDBC 概述

  JDBC(Java DataBase Connectivity Java 数据库连接)是一种用于执行 SQL 语句的 Java API,可以为多种关系型数据库提供统一访问,它由一组用 Java 语言编写的类和接口组成。
  其实就是Java 官方提供的一套规范(接口),帮助开发人员快速实现不同关系型数据库的连接。

二 使用的功能类

1 DriverManager 类

  DriverManager:驱动管理对象,主要用于加载注册关系型数据库的 Driver 类以及获取和关系型数据库的连接对象
① 加载注册驱动

// 语法:注册给定的驱动对象
static void registerDriver(Driver driver);// 在 com.mysql.jdbc.Driver 类中存在静态代码块,把 com.mysql.jdbc.Driver 这一份字节码加载进 JVM
// 字节码被加载进JVM,就会执行其静态代码块.而其底层的静态代码块在完成注册驱动工作,将驱动注册到DriverManger 中
static {try {DriverManager.registerDriver(new Driver());} catch (SQLException var1) {throw new RuntimeException("Can't register driver!");}
}// 加载注册驱动
Class.forName("com.mysql.jdbc.Driver");

  Java6 开始,JDBC4.0 无需加载注册驱动在 jar 包中存在一个java.sql.Driver 配置文件。此文件已经包含 com.mysql.jdbc.Driver 驱动名称。
   程序会自动从 META-INF/services/java.sql.Driver 去读取当前的驱动类的全限定名,故不写加载注册驱动也可以,但 web 项目必须写加载注册驱动代码,否则无法连接数据库

② 获取连接对象

// 语法:获取连接对象
static Connection getConnection(String url,String username,String password);// 参数 url 指定连接某一个数据库的路径,语法:
url=jdbc:mysql://localhost:3306/jdbcdemo// 若连接的是本机的 MySQL,并且端口是默认 3306 ,可以简写
url=jdbc:mysql:///jdbcdemo// 连接数据库的账号
username
// 连接数据库的密码
password

2 Connection 类

  关系型数据库连接对象,用于 Java 程序与数据库的通信连接

// 获取执行语句对象(静态语句执行对象)
Statement createStatement();
// 获取执行语句对象(预编译语句执行对象)
PreparedStatement prepareStatement(String sql);
// 释放资源,关闭连接对象
void close();// 设置是否为自动提交事务,setAutoCommit(boolean)默认值为true表示自动提交(每条SQL语句都是一个单独的事务),设置为false相当于开启事务
con.setAutoCommit(false) // 提交结束事务
commit()
// 回滚结束事务
rollback()

3 Statement 类

  静态SQL语句执行对象,用于执行字符串的 SQL 语句

// 执行DML/DDL语句,返回值为DML受影响的行数,DDL则返回0,参数为insert、update、delete、create语句
int executeUpdate(String sql);// 执行DQL语句,返回值为执行查询之后的结果数据,参数为select 
ResuleSet executeQuery(String sql);// 释放资源 关闭Statement对象
void close();

三 创建流程

1 创建数据库表

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=3 DEFAULT CHARSET=utf8;

2 增加一条员工信息

public class Test {// 增加一条员工信息public static void main(String[] args) throws ClassNotFoundException, SQLException {//1.加载jdbc注册驱动com.mysql.jdbc.Driver//反射加载类的字节码对象,目的是实例化Driver对象:底层调用newInstance()方法 需要目标类中包含无参构造Class.forName("com.mysql.jdbc.Driver");//2.获取数据库连接对象//Connection建立java代码和mysql数据库之间的连接关系/** jdbc:mysql:// 协议 表示使用jdbc技术连接mysql数据库* localhost:3306/ 本机回环地址 localhost==127.0.0.1* 3306mysql默认的端口号* localhost:3306当连接本机默认mysql可以省略* 192.168.1.23:3307链接他人数据库的格式* jdbcdemo 需要连接的目标数据库名称* root mysql登录账号* root mysql登录密码* */Connection connection= DriverManager.getConnection("jdbc:mysql://localhost:3306/web_crud","root","root");//3.创建执行sql语句的对象:Statement最终执行sql语句的操作者Statement statement= connection.createStatement();//4.执行目标的sql语句/** Statement对象提供了数据库表数据的CRUD操作的方法API* 增删改:executeUpdate()* 查询:executeQuery()* *///双引号嵌套:通常会将包含的引号加转译字符或者使用单引号//String sql = "INSERT INTO t_employee(eid,ename,job,salary) VALUES(\"tj008\",\"大黄\",\"医药代表\",15000)";//单引号不转义String sql = "INSERT INTO t_employee(eid,ename,job,salary) VALUES('tj006','大黄','医药代表',15000)";int row= statement.executeUpdate(sql);//5.关闭对象,释放资源statement.close();connection.close();}
}

四 Dao组件

1 概述

  DAO(Data Access Object) 数据访问对象,即面向对象的数据库接口,将所有对数据源(数据库)的访问操作抽象封装在一个公共 API 中,实现增删改查

2 方法设计

  ① 对数据库数据进行修改时,调用者需要传递多个参数进来,把这些数据存入数据库
  ② 对数据库数据进行查询时,结果集的每行数据有多个列的值,把这些数据返回给调用者
  ③ 需传递多个数据时,使用 JavaBean 对其进行封装

// 调用者将保存的数据封装到employee对象中,传递进来
void save(Employee ep);
// 通过id进行查询后,将每行数据封装到employee对象中,返回给调用者
Student selectOne(long id);

3 步骤

  ① 创建项目,导入数据库驱动包
  ② 创建表和实体类包以及实体对象 (domain/Employee)
  ③ 创建 DAO 包和 DAO 接口,设计 DAO 接口方法 (dao/IEmployeeDAO)
  ④ 创建 DAO 实现包,实现 DAO 接口(dao.impl/EmployeeDAOImpl)
  ⑤ 创建测试目录,生成测试类和方法(test/EmployeeDAOTest)
  ⑥ 书写实现,实现一个方法测试一个方法并且测试通过

4 演示

实体类

@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);
}

实现类 – 执行 SQL 需要的参数是调用者传递进来的,故需要将其拼接到 SQL 里面

public class EmployeeDaoImpl implements IEmployeeDao {/*修改员工*/@Overridepublic void updateEmployee(Employee employee) {try {Class.forName("com.mysql.jdbc.Driver");Connection connection= DriverManager.getConnection("jdbc:mysql://localhost:3306/web_crud","root","root");Statement statement = connection.createStatement();String sql="update t_employee set ename='"+employee.getEname()+"' ,job='"+employee.getJob()+"',eid='"+employee.getEid()+"',salary='"+employee.getSalary()+"' WHERE id="+employee.getId()+"";System.out.println(sql);int row = statement.executeUpdate(sql);statement.close();connection.close();} catch (Exception e) {e.printStackTrace();}}/*增加员工*/@Overridepublic void addEmployee(Employee employee) {try {Class.forName("com.mysql.jdbc.Driver");Connection connection= DriverManager.getConnection("jdbc:mysql://localhost:3306/web_crud","root","root");Statement statement = connection.createStatement();String sql="insert into t_employee(ename,job,eid,salary)values('"+employee.getEname()+"','"+employee.getJob()+"','"+employee.getEid()+"','"+employee.getSalary()+"')";System.out.println(sql);int row = statement.executeUpdate(sql);statement.close();connection.close();} catch (Exception e) {e.printStackTrace();}}
}

测试类

public class EmployeeTest {/*修改员工信息*/@Testpublic void employee_update(){// 创建dao对象IEmployeeDao employeeDao=new EmployeeDaoImpl();// 修改1号员工信息employeeDao.updateEmployee(new Employee(1L,"大黄","保安","tj028",15000));}/*增加员工信息*/@Testpublic void employee_add() {IEmployeeDao employeeDao=new EmployeeDaoImpl();employeeDao.addEmployee(new Employee(null,"大黄","保安","tj027",15000));}
}

五 预编译对象

1 作用:

  PreparedStatement 接口: 是 Statement 接口的子接口, 享有 Statement 中的方法,预编译语句对象的sql 语句中使用 ? 来作为值的占位符,从而解决拼接sql字符串易出错的问题

2 优化代码

实体类

@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 {Class.forName("com.mysql.jdbc.Driver");Connection connection= DriverManager.getConnection("jdbc:mysql:///web_crud","root","root");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();statement.close();connection.close();} catch (Exception e) {e.printStackTrace();}}/*增加员工*/@Overridepublic void addEmployee(Employee employee) {try {Class.forName("com.mysql.jdbc.Driver");Connection connection= DriverManager.getConnection("jdbc:mysql:///web_crud","root","root");//创建预编译对象:sql执行对象//编译sql的时候使用占位符替换语句中的未知的变量值String sql="insert into t_employee(eid,ename,job,salary)values(?,?,?,?)";PreparedStatement statement = connection.prepareStatement(sql);/*执行CRUD操作前需通过set方法将预编译的占位符替换成客户端传入的具体值*//*statement.setString(1,employee.getEid());statement.setInt(2,employee.getEname());statement.setString(3,employee.getJob());statement.setString(4,employee.getSalary());*/// 顺序与占位符顺序一致(字段类型也一致),使用setObject可不考虑字段类型statement.setObject(1,employee.getEid());statement.setObject(2,employee.getEname());statement.setObject(3,employee.getJob());statement.setObject(4,employee.getSalary());//执行增加操作 此时需要知道占位符的值是什么statement.executeUpdate();statement.close();connection.close();} catch (Exception e) {e.printStackTrace();}}/*根据id查询*/@Overridepublic Employee queryById(int id) {try {Class.forName("com.mysql.jdbc.Driver");Connection connection= DriverManager.getConnection("jdbc:mysql:///web_crud","root","root");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);}statement.close();connection.close();resultSet.close();//返回员工对象return  employee;} catch (Exception e) {e.printStackTrace();}return null;}//查询所有@Overridepublic List<Employee> queryALl() {try {Class.forName("com.mysql.jdbc.Driver");Connection connection= DriverManager.getConnection("jdbc:mysql:///web_crud","root","root");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);}statement.close();connection.close();resultSet.close();return list;} catch (Exception e) {e.printStackTrace();}return null;}
}

测试类

public class EmployeeTest {//创建dao对象private IEmployeeDao employeeDao=new EmployeeDaoImpl();/*修改员工信息*/@Testpublic void employee_update(){employeeDao.updateEmployee(new Employee(2L,"小花","BA","tj035",9000));}/*增加员工信息*/@Testpublic void employee_add() {employeeDao.addEmployee(new Employee(null,"大黄","BA","tj036",9000));}/*根据id查询员工*/@Testpublic void employee_listOne() {Employee employee = employeeDao.queryById(1);System.out.println(employee);}/*查询所有*/@Testpublic void employee_listAll() {employeeDao.queryALl().forEach(System.out::println);List<Employee> list = employeeDao.queryALl();for (Employee employee : list) {System.out.println(employee);}}
}

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

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

相关文章

如何用CHAT了解历史?

问CHAT&#xff1a;古代有什么常见的简单机械&#xff1f; CHAT回复&#xff1a; 1. 滑轮&#xff1a;滑轮是一种简单的机械&#xff0c;主要提供力量放大、改变力的方向等功能。在古代&#xff0c;人们使用滑轮来托起重物&#xff0c;如水井的提水装置&#xff0c;建造大型建…

大模型元年压轴盛会定档12月28日,第十届WAVE SUMMIT即将启航

文章目录 1. 前言2. WAVE SUMMIT五载十届&#xff0c;AI开发者热血正当时3. 酷炫前沿、星河共聚&#xff01;大模型技术生态发展正当时 1. 前言 回望2023年&#xff0c;大语言模型或许将是科技史上最浓墨重彩的一笔。从技术、产业到生态&#xff0c;大语言模型在突飞猛进中加速…

【python中类的介绍】

python中类的介绍 在Python中&#xff0c;定义类需要使用关键字 class类名通常使用大写字母开头&#xff0c;举例&#xff1a; class MyClass:pass解释&#xff1a;定义了一个MyClass的空类。 1、python中类定义 “”" 类中可以定义属性和方法。 1、属性是类的数据成…

使命召唤9缺少buddha.dll的解决方法分享,如何快速修复buddha.dll

《使命召唤》系列作为备受欢迎的第一人称射击游戏,经常会在新作发行后引起广大玩家的讨论。最近&#xff0c;《使命召唤9》玩家中出现了一个常见的技术问题&#xff1a;游戏无法启动&#xff0c;因为系统找不到 buddha.dll 文件。这篇文章将探讨 buddha.dll 的相关信息、丢失原…

软件外包的 20 个问题以及如何避免这些问题

外包很常见。 三分之二的企业进行外包。全国范围内&#xff0c;以某种身份从事自由职业。这意味着全国 40% 的劳动力是个体户或从事零工。 客户支持、软件开发和营销是最常见的外包职能。 外包可以节省成本、提高速度和灵活性。 但这并非没有问题。外包的常见问题最终可能会…

MATLAB中ode45和ode23有什么区别

总的来说二者算法相似&#xff0c;只不过ode45比ode23精度要高一些&#xff0c;其他没什么差别。 具体ode是MATLAB专门用于解常微分方程的功能函数&#xff1b;solver有变步长(variable-step)和定步长(fixed-step)两种类型&#xff0c;不同类型有着不同的求解器。ode45求解器属…

gdb本地调试版本移植至ARM-Linux系统

移植ncurses库 本文使用的ncurses版本为ncurses-5.9.tar.gz 下载地址&#xff1a;https://ftp.gnu.org/gnu/ncurses/ncurses-5.9.tar.gz 1. 将ncurses压缩包拷贝至Linux主机或使用wget命令下载并解压 tar-zxvf ncurses-5.9.tar.gz 2. 解压后进入到ncurses-5.9目录…

智能优化算法应用:基于鸡群算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于鸡群算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于鸡群算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.鸡群算法4.实验参数设定5.算法结果6.参考文献7.MA…

“拼团购”实现商业爆发式增长,魅力吸引消费者多次参与

每天五分钟讲解一个电商模式&#xff0c;大家伙我是模式策划阿浩在当今电商行业快速发展的时代&#xff0c;拼团模式作为一种新兴的商业模式&#xff0c;正逐渐受到广大消费者的青睐。拼团模式通过多人组团购买同一件商品&#xff0c;借助社交媒体等渠道的传播&#xff0c;实现…

arcgis for js 添加自定义叠加图片到地图坐标点上

在使用arcgis for js开发地图绘制图层时&#xff0c;可以通过相关api实现添加图标到某个坐标点&#xff0c;那么如果现在有一个需要添加一个小图叠大图的需求&#xff0c;又或者是自定义绘制图标&#xff0c;如何实现&#xff1f; 1、简单地绘制一个图标到底图图层上面 const…

C++STL之List的实现

首先我们要实现List的STL,我们首先要学会双向带头链表的数据结构。那么第一步肯定是要构建我们的节点的数据结构。 首先要有数据域&#xff0c;前后指针域即可。 再通过模板类进行模板化。 然后再写List的构造函数&#xff0c;这个地方用T&,通过引用就可以减少一次形参拷…

JavaFX窗口生成

JavaFX 窗口生成 JavaFX中存在Application类&#xff0c;用于窗口的初始化&#xff08;init()&#xff09;、显示&#xff08;show()&#xff09;、结束&#xff08;stop()&#xff09;操作。 步骤 &#xff08;不适用于jdk11及以上版本&#xff09; 调用静态方法launch(S…

vue2-elementUI部分组件样式修改

el-radio样式&#xff1a; /deep/ .el-radio__input .el-radio__inner {width: 20px;height: 20px;position: relative;cursor: pointer;-webkit-appearance: none;-moz-appearance: none;appearance: none;border: 1px solid #999;border-radius: 0;outline: none;transition…

阿里云cdn设置相同的域名路径访问不同的oss目录

1.设置回源配置&#xff0c;添加回源URL改写 2.设置跨域&#xff0c;cdn的跨域优先oss 3.回源设置

电商早报 | 12月12日| 淘宝公布2023年度商品初选名单入围

淘宝公布2023年度商品初选名单&#xff1a;军大衣、酱香拿铁、熊猫周边入围 又一年临近收官&#xff0c;淘宝如期启动了“2023年度十大商品”评选。 12月11日&#xff0c;淘宝官方发布了初选入围名单&#xff0c;30件最具代表性的商品脱颖而出。据淘宝路边社介绍&#xff0c;…

784. 字母大小写全排列

字母大小写全排列 描述 : 给定一个字符串 s &#xff0c;通过将字符串 s 中的每个字母转变大小写&#xff0c;我们可以获得一个新的字符串。 返回 所有可能得到的字符串集合 。以 任意顺序 返回输出。 回文串 是正着读和反着读都一样的字符串。 题目 : LeetCode 784. 字母…

10、RocketMQ的Comsumer的消息队列的分配

前置知识&#xff1a;RocketMQ的topic存在多个队列&#xff0c;而多个topic分配在同一消费组里面&#xff0c;消费组里面存在多个消费者&#xff0c;当消费者注入到消费组时要进行消费者与多个队列之间的分配&#xff0c;而这种分配被称之为Rebalance机制&#xff0c;该机制的本…

Linux命令大全(全网最细讲解)

文章目录 一、基础知识&#xff08;1&#xff09; Linux系统的文件结构&#xff08;2&#xff09; Linux系统命令行的含义&#xff08;3&#xff09;命令的组成二、基础操作&#xff08;1&#xff09; 关闭系统&#xff08;2&#xff09; 关闭重启&#xff08;3&#xff09; 帮…

节日问候:在 Metaverse 中一起庆祝节日!

冬季即将来临&#xff0c;节日的脚步也越来越近&#xff0c;是时候通过 The Sandbox 中的最新活动——“节日问候”来迎接节日气氛了&#xff01;为期 43 天的庆祝活动从 12 月 11 日开始&#xff0c;到 1 月 22 日结束&#xff0c;将带领玩家穿越一个充满 60 种体验的冬季仙境…

vue-打包后的dist文件如何在本地测试

vue-打包后的dist文件如何在本地测试 1.执行打包命令 npm run bulid后,生成dist文件夹2.全局安装http-server npm install http-server -g3.dist文件夹下 打开终端 开启服务 http-server -p 8888 //8888未指定端口号