软件设计之JDBC(1)

2024-09-04 12:20
文章标签 jdbc 软件设计

本文主要是介绍软件设计之JDBC(1),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

软件设计之JDBC(1)

此篇应在MySQL之后进行学习:
路线图推荐:
【Java学习路线-极速版】【Java架构师技术图谱】
尚硅谷2024最新JDBC教程 | jdbc基础到高级一套通关!

资料可以去尚硅谷官网免费领取

学习内容:

  1. 前言
  2. JDBC
  3. PreparedStatement实现CRUD
  4. 常见问题

1、前言

1、开发Java程序时,数据都是存储在内存中,属于临时存储,当程序停止或重启时,内存中的数据就丢失了
2、因此数据通过I/O技术,存储在本地磁盘中,解决了持久化问题,但是没有结构和逻辑,不方便管理和维护
3、通过关系型数据库,将数据可以按照特定的格式交由数据库管理系统维护。关系型数据库是通过库和表分隔不同的数据,表中数据存储的方式是行和列,区分相同格式不同值的数据。
4、如何通过Java程序对数据库中的数据做增删改查?JDBC

2、JDBC

JDBC概念

JDBC:Java Database Connectivity
JDBC是Java提供的一组独立于任何数据库管理系统的API
Java提供接口规范,后由数据库厂商提供接口的实现
在这里插入图片描述

项目入门

使用select version() from DUAL;语句在Navicat中查看MySQL版本
下载MySQL对应JDBC驱动,下载官网点击此处
找到对应MySQL版本,其中Operating System这里选择Platform independent
下载好的驱动导入到项目里并右键Add as library(具体看视频教程哦)
其中JDK使用的是JDK21

数据库SQL语句创建表

CREATE DATABASE atguigu;
USE atguigu;
CREATE TABLE t_emp
(emp_id INT AUTO_INCREMENT COMMENT '员工编号' PRIMARY KEY,emp_name VARCHAR(100) NOT NULL COMMENT '员工姓名',emp_salary DOUBLE(10,5) NOT NULL COMMENT '员工薪资',emp_age INT NOT NULL COMMENT '员工年龄'
);
INSERT INTO t_emp(emp_name,emp_salary,emp_age)
VALUES ('andy',777.77,32),
('大风哥',666.66,41),
('康师傅',111,23),
('Gavin',123,26),
('小鱼儿',123,28);

Java对应语句

package com.atguigu.base;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;public class JDBCQuick {public static void main(String[] args) throws Exception {//1 注册驱动Class.forName("com.mysql.cj.jdbc.Driver");//2 获取连接对象String url = "jdbc:mysql://localhost:3306/atguigu";String username = "root";String password = "root";Connection connection = DriverManager.getConnection(url, username, password);//3 获取执行SQL语句对象Statement statement = connection.createStatement();//4 编写SQL语句,并执行,接收返回的结果集String sql = "SELECT emp_id,emp_name,emp_salary,emp_age FROM t_emp";ResultSet resultSet = statement.executeQuery(sql);//5 处理结果:遍历resultSet结果集while(resultSet.next()){int empId = resultSet.getInt("emp_id");String empName = resultSet.getString("emp_name");double empSalary = resultSet.getDouble("emp_salary");int empAge = resultSet.getInt("emp_age");System.out.println(empId +"\t" + empName + "\t" + empSalary + "\t" + empAge);}//6 释放资源 先开后关原则resultSet.close();statement.close();connection.close();}
}

注册驱动

在这里插入图片描述

Connection

在这里插入图片描述

Statement

在这里插入图片描述

SQL注入攻击问题

当控制台输入 a’ or ‘1’ = ‘1 时候,会把所有数据显示
‘a’ or ‘1’ = ‘1’
因为 在SQL语句中WHERE emp_name = true 时,所有都为真

public class JDBCInjection{public static void main(String[] args) throws SQLException {//1 注册驱动 可省略//2 获取连接对象String url = "jdbc:mysql://localhost:3306/atguigu";String username = "root";String password = "root";Connection connection = DriverManager.getConnection(url, username, password);//3 获取执行SQL语句对象Statement statement = connection.createStatement();System.out.println("请输入员工姓名:");Scanner scanner = new Scanner(System.in);String name = scanner.nextLine();//4 编写SQL语句,并执行,接收返回的结果集String sql = "SELECT emp_id,emp_name,emp_salary,emp_age FROM t_emp WHERE emp_name = '"+name+"'";ResultSet resultSet = statement.executeQuery(sql);//5 处理结果:遍历resultSet结果集while(resultSet.next()){int empId = resultSet.getInt("emp_id");String empName = resultSet.getString("emp_name");double empSalary = resultSet.getDouble("emp_salary");int empAge = resultSet.getInt("emp_age");System.out.println(empId +"\t" + empName + "\t" + empSalary + "\t" + empAge);}//6 释放资源 先开后关原则resultSet.close();statement.close();connection.close();}
}

PreparedStatement

在这里插入图片描述

package com.atguigu.base;
import java.sql.*;
import java.util.Scanner;
public class JDBCPrepared {public static void main(String[] args) throws SQLException {//1 注册驱动 可省略//2 获取连接对象String url = "jdbc:mysql://localhost:3306/atguigu";String username = "root";String password = "root";Connection connection = DriverManager.getConnection(url, username, password);//3 获取执行SQL语句对象PreparedStatement preparedStatement = connection.prepareStatement("SELECT emp_id,emp_name,emp_salary,emp_age FROM t_emp WHERE emp_name = ?");System.out.println("请输入员工姓名:");Scanner scanner = new Scanner(System.in);String name = scanner.nextLine();//4 为?占位符赋值,并执行SQL语句,接收返回的结果集//下标从1开始,此处参数只有一个emp_namepreparedStatement.setString(1,name);ResultSet resultSet = preparedStatement.executeQuery();//5 处理结果:遍历resultSet结果集while(resultSet.next()){int empId = resultSet.getInt("emp_id");String empName = resultSet.getString("emp_name");double empSalary = resultSet.getDouble("emp_salary");int empAge = resultSet.getInt("emp_age");System.out.println(empId +"\t" + empName + "\t" + empSalary + "\t" + empAge);}//6 释放资源 先开后关原则resultSet.close();preparedStatement.close();connection.close();}
}

ResultSet

在这里插入图片描述

3、PreparedStatement实现CRUD

前期准备

需要下载junit-4.12.jar 和hamcrest-2.2.jar包导入进项目中
下载地址可以点击此处:
下载链接1对应junit
下载链接2对应hamcrest

单行单列查询

    @Testpublic void testQuerySingleRowAndCol() throws SQLException {//1 注册驱动 可省略//2 获取连接对象Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/atguigu", "root", "root");//3 获取执行SQL语句对象PreparedStatement preparedStatement = connection.prepareStatement("SELECT COUNT(*) as count FROM t_emp");//4 执行SQL语句,接收返回的结果集ResultSet resultSet = preparedStatement.executeQuery();//5 处理结果:遍历resultSet结果集while(resultSet.next()){int count = resultSet.getInt("count");System.out.println(count);}//6 释放资源 先开后关原则resultSet.close();preparedStatement.close();connection.close();}

单行多列查询

@Testpublic void testQuerySingleRow() throws SQLException {//1 注册驱动 可省略//2 获取连接对象Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/atguigu", "root", "root");//3 获取执行SQL语句对象PreparedStatement preparedStatement = connection.prepareStatement("SELECT emp_id,emp_name,emp_salary,emp_age FROM t_emp WHERE emp_id = ?");//4 为?占位符赋值,并执行SQL语句,接收返回的结果集preparedStatement.setInt(1,3);ResultSet resultSet = preparedStatement.executeQuery();//5 处理结果:遍历resultSet结果集while(resultSet.next()){int empId = resultSet.getInt("emp_id");String empName = resultSet.getString("emp_name");double empSalary = resultSet.getDouble("emp_salary");int empAge = resultSet.getInt("emp_age");System.out.println(empId +"\t" + empName + "\t" + empSalary + "\t" + empAge);}//6 释放资源 先开后关原则resultSet.close();preparedStatement.close();connection.close();}

多行多列查询

    @Testpublic void testQueryMoreRow() throws SQLException {//1 注册驱动 可省略//2 获取连接对象Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/atguigu", "root", "root");//3 获取执行SQL语句对象PreparedStatement preparedStatement = connection.prepareStatement("SELECT emp_id,emp_name,emp_salary,emp_age FROM t_emp WHERE emp_age > ?");//4 为?占位符赋值,并执行SQL语句,接收返回的结果集preparedStatement.setInt(1,25);ResultSet resultSet = preparedStatement.executeQuery();//5 处理结果:遍历resultSet结果集while(resultSet.next()){int empId = resultSet.getInt("emp_id");String empName = resultSet.getString("emp_name");double empSalary = resultSet.getDouble("emp_salary");int empAge = resultSet.getInt("emp_age");System.out.println(empId +"\t" + empName + "\t" + empSalary + "\t" + empAge);}//6 释放资源 先开后关原则resultSet.close();preparedStatement.close();connection.close();}

新增一条数据

 @Testpublic void testInsert() throws SQLException {//1 注册驱动 可省略//2 获取连接对象Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/atguigu", "root", "root");//3 获取执行SQL语句对象PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO t_emp(emp_name,emp_salary,emp_age) VALUES (?,?,?)");//4 为?占位符赋值,并执行SQL语句,接收返回的结果集preparedStatement.setString(1,"Rose");preparedStatement.setDouble(2,888.88);preparedStatement.setInt(3,28);int result = preparedStatement.executeUpdate();//5 处理结果:根据受影响的行数做判断,得到成功或失败if (result > 0){System.out.println("成功");}else {System.out.println("失败");}//6 释放资源 先开后关原则preparedStatement.close();connection.close();}

修改一条数据

    @Testpublic void testUpdate() throws SQLException {//1 注册驱动 可省略//2 获取连接对象Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/atguigu", "root", "root");//3 获取执行SQL语句对象PreparedStatement preparedStatement = connection.prepareStatement("UPDATE t_emp SET emp_salary = ? WHERE emp_id = ?");//4 为?占位符赋值,并执行SQL语句,接收返回的结果集preparedStatement.setDouble(1,999.99);preparedStatement.setInt(2,6);int result = preparedStatement.executeUpdate();//5 处理结果:根据受影响的行数做判断,得到成功或失败if (result > 0){System.out.println("成功");}else {System.out.println("失败");}//6 释放资源 先开后关原则preparedStatement.close();connection.close();}

4、常见问题

java.sql.SQLSyntaxErrorException

1、SQL语句有错误,建议SQL语句在SQL工具中测试后再复制到java程序中
2、连接数据库的URL中,数据库名称编写错误

java.sql.SQLException:No value specified parameter 1

在使用预编译SQL时,如果有?占位符,要为每一个占位符赋值,否则报该错误

java.sql.SQLException: Access denied for user ‘root’@‘localhost’(using password: YES)

连接数据库时,如果用户名或密码输入错误,也会报SQLException

CommunicationException:Communication link failure

在连接数据库的URL时,如果IP或端口写错了,会报如下异常

这篇关于软件设计之JDBC(1)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1136012

相关文章

滚雪球学Java(87):Java事务处理:JDBC的ACID属性与实战技巧!真有两下子!

咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE啦,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~ 🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!! 环境说明:Windows 10

Hibernate框架中,使用JDBC语法

/*** 调用存储过程* * @param PRONAME* @return*/public CallableStatement citePro(final String PRONAME){Session session = getCurrentSession();CallableStatement pro = session.doReturningWork(new ReturningWork<C

读软件设计的要素04概念的关系

1. 概念的关系 1.1. 概念是独立的,彼此间无须相互依赖 1.1.1. 一个概念是应该独立地被理解、设计和实现的 1.1.2. 独立性是概念的简单性和可重用性的关键 1.2. 软件存在依赖性 1.2.1. 不是说一个概念需要依赖另一个概念才能正确运行 1.2.2. 只有当一个概念存在时,包含另一个概念才有意义 1.3. 概念依赖关系图简要概括了软件的概念和概念存在的理

jdbc连接数据库使用sid和service_name的区别 ?

问题描述: ORA-12505, TNS:listener does not currently know of SID given in connect descriptor The Connection descriptor used by the client was: 10.12.162.84:1521:xxxx  oracle数据的tnsnames.ora中配置的是:SERVICE

Java项目中,配置打印 JDBC 日志的几种方法

在 IDEA 项目中,如果你想打印 JDBC 日志,可以通过配置日志框架(如 Logback 或 Log4j)来实现。Spring Boot 使用的默认日志框架是 Logback,你可以通过在 application.yml 文件中配置日志级别来打印 JDBC 日志。 方法 1: 使用 application.yml 配置 JDBC 日志 logging:level:# 显示 SQL 语句co

基于shard-jdbc中间件,实现数据分库分表

一、水平分割 1、水平分库 1)、概念: 以字段为依据,按照一定策略,将一个库中的数据拆分到多个库中。 2)、结果 每个库的结构都一样;数据都不一样; 所有库的并集是全量数据; 2、水平分表 1)、概念 以字段为依据,按照一定策略,将一个表中的数据拆分到多个表中。 2)、结果 每个表的结构都一样;数据都不一样; 所有表的并集是全量数据; 二、Shard-jdbc 中间件 1、架构图 2、特点

基于Shard-Jdbc分库分表,数据库扩容方案

一、数据库扩容 1、业务场景 互联网项目中有很多“数据量大,业务复杂度高,需要分库分表”的业务场景。 这样分层的架构 (1)上层是业务层biz,实现业务逻辑封装; (2)中间是服务层service,封装数据访问; (3)下层是数据层db,存储业务数据; 2、扩容场景和问题 当数据量持续新增,面临着这样一些需求,两台数据库无法容纳,需要数据库扩容,这里选择2台—扩容到3台的模式,如下图

Java笔试面试题AI答之JDBC(3)

文章目录 13. 编写JDBC连Oracle的程序?14. 简述JDBC的主要组件有哪些 ?15. JDBC中如何防止SQL注入攻击?1. 使用预处理语句(PreparedStatement)2. 避免在SQL查询中直接拼接用户输入的数据总结 16. JDBC的脏读是什么?哪种数据库隔离级别能防止脏读?脏读(Dirty Read)哪种数据库隔离级别能防止脏读? 17. 简述JDBC ex

JavaBug系列- Failed to load driver class com.mysql.cj.jdbc.Driver in either of HikariConfig class load

JavaBug系列之Mysql驱动问题 Java医生一、关于错误信息二、如何解决问题 Java医生 本系列记录常见Bug,以及诊断过程和原因 Java/一对一零基础辅导/企业项目一对一辅导/日常Bug解决/代码讲解/毕业设计等 V:study_51ctofx 一、关于错误信息 APPLICATION FAILED TO START Description: Fai

读软件设计的要素03概念的组合

1. 概念的组合 1.1. 概念不像程序那样,可以用较大的包含较小的 1.1.1. 每个概念对用户来说都是平等的,软件或系统就是一组串联运行的概念组合 1.2. 概念是通过操作来同步组合的 1.2.1. 同步并不增加新的概念操作,但会限制已有的操作,从而消除一些独立概念可能会出现的操作序列 1.3. 在自由组合中,概念彼此独立,仅受一些记录的约束,这些约束是为了确保概念对事物观点的一