当前位置: 首页 > news >正文

java程序员入行科目一之CRUD轻松入门教程(一)

之前在操作MySQL的时候,都是采用Navicat,或者cmd黑窗口。

无论使用什么方式和MySQL交互,大致步骤是这样的

  • 建立连接,需要输入用户名和密码
  • 编写SQL语句,和数据库进行交互

这个连接方式不会变,但是现在需要 基于Java语言去和MySQL进行一波

image.png

在实际开发中,当用户要对数据进行一些改变的时候,不能通过工具去执行SQL或者直接点来点去修改的,需要用Java语言去进行交互,使用Java会让操作更有效率和准确性。

Java语言为了提供和多种数据库都可以用一样的方式进行交互,Java提供了一个规范,这个规范 JDBC(Java Database Connectivity)

JDBC介绍

什么是JDBC

JDBC就是Java对外提供的一种规范,JDBC的目的就是让Java语言可以和数据库进行交互,完成CRUD。

JDBC的核心思想

JDBC是个规范,Java就对外发布了这个规范,如果各个数据库厂商,想让你的数据库可以和Java进行交互,数据库厂商就需要根据我JDBC的规范去做具体的实现,提供一个驱动(Driver)。

image.png

MySQL数据库驱动

这里在课程资料中会提供,如果想自行下载,可以去一个地址搜索。

http://mvnrepository.com

可以直接搜索需要的jar包,只要大版本没问题,正常下载即可

image.png

JDBC API

JDBC的API主要掌握4个,了解1个。

类型类的全路径描述
classjava.sql.DriverManager管理数据库的驱动类,需要基于他来获取到Connection连接对象
interfacejava.sql.Connection代表一个和数据库的连接,通过他获取到Statement发送SQL
interfacejava.sql.Statement将SQL语句发送给数据库服务端
interfacejava.sql.ResultSet数据库服务端执行完毕SQL后的返回结果
classjava.sql.SQLException和数据库交互时,会抛出的异常。

JDBC开发步骤

构建项目

image.png

导入依赖

第一步,先将jar文件copy到项目的所在目录下。

image.png

第二步,需要将这个jar包添加到工程中。

image.png

第三步,随便搞一个测试类,看一下Driver类有没有MySQL提供的驱动

image.png

编写开发过程

注册驱动

//        ###  注册驱动
// 本质就是将Driver类构建好对象并且封装好,将封装好的Driver对象扔到DriverManager类中的一个List集合中
Class.forName("com.mysql.cj.jdbc.Driver");

建立连接

//        ###  建立连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?characterEncoding=utf-8",
"root","root");

获取发送SQL的对象

//        ###  获取发送SQL的对象
Statement statement = conn.createStatement();

执行SQL

//        ###  执行SQL
String sql = "insert into account (id,name,money) values (5,'赵六',9999)";
int count = statement.executeUpdate(sql);

处理结果

//        ###  处理结果
if(count == 1){System.out.println("当前操作成功!");
}

释放资源

//      释放资源
statement.close();
conn.close();

完整操作

package com.jimihua;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;/*** 在当前类中完成最基本的和MySQL交互。* 完成一个添加操作。*/
public class Demo1 {public static void main(String[] args) throws ClassNotFoundException, SQLException {
//        ###  注册驱动
// 本质就是将Driver类构建好对象并且封装好,将封装好的Driver对象扔到DriverManager类中的一个List集合中Class.forName("com.mysql.cj.jdbc.Driver");//        ###  建立连接Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?characterEncoding=utf-8","root", "root");//        ###  获取发送SQL的对象Statement statement = conn.createStatement();//        ###  执行SQLString sql = "insert into account (id,name,money) values (5,'赵六',9999)";int count = statement.executeUpdate(sql);//        ###  处理结果if (count == 1) {System.out.println("当前操作成功!");}
//        ### 3.3.6 释放资源statement.close();conn.close();}}

常见错误

image.png


image.png


image.pngResultSet结果集

ResultSet操作

前面操作是针对增删改,返回结果是几行受影响,就是一个int类型的数值。

现在需要玩一波查询操作,而查询操作,返回的就是一个虚拟表。

直接查询之前test库中的account表

首先在执行查询的select的SQL语句时,需要使用的是statement提供的executeQuery方法。

其次,在执行executeQuery方法后,返回的是一个ResultSet结果集,他相当你查询的数据内容。

image.png

再有就是针对ResultSet的操作。首先要记住ResultSet的next方法。

next方法类似一个指针,你每次next,指针都会移动到下一行。如果下一行有数据,next方法会返回true,如果下一行没数据,next方法会返回false。

Ps:ResultSet第一次执行next,指针才会指向第一行。

在指针指向某一个行之后,可以再基于ResultSet提供的getXxx方法获取对应列的数据,获取对应列的方式,可以通过序号来找,从1开始,但是 推荐使用列名去找具体数据

package com.jimihua;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;/*** 查询account表,获取返回的结果集ResultSet*/
public class Demo2 {public static void main(String[] args) throws Exception {//1、注册驱动Class.forName("com.mysql.cj.jdbc.Driver");//2、获取连接Connection conn =DriverManager.getConnection("jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8","root","root");//3、获取StatementStatement statement = conn.createStatement();//4、执行查询的SQLString sql = "select * from account";ResultSet rs = statement.executeQuery(sql);//5、操作ResultSet结果集//5.1 先用ResultSet的一个next方法确认是否有返回的数据while(rs.next()){// 如果进到while循环,说明有数据// 5.2 基于ResultSet提供的get类型方法去获取结果long id = rs.getLong("id");String name = rs.getString("name");long money = rs.getLong("money");System.out.println("获取数据:" + id + "," + name + "," + money + "。");}// 到这,说明指针已经到最后了,没有数据了。//6、释放资源rs.close();statement.close();conn.close();}
}

常见错误

image.png

综合案例

完成一个注册登录的小案例。

准备表

创建一张用户表user

  • id,数值类型,主键,自增
  • username,用户名,字符串类型,唯一,非空
  • password,密码,字符串类型,非空
create table user(id bigint primary key auto_increment comment '主键id',username varchar(32) unique not null comment '用户名',password varchar(32) not null comment '密码'
)comment '用户表';

查询2条测试数据

insert into user values (1,'admin','admin'),(2,'zhangsan','123456');

实现注册和登录操作

注册驱动这个事情,只需要做一次就足够了。

注册驱动的本质就是将MySQL的Driver对象存放到DriverManager中的一个List集合中。

package com.jimihua;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;/***  实现注册和登录操作*/
public class Demo3 {public static void main(String[] args) throws Exception {// 因为注册驱动的操作,做一次就够了,他就是将Driver的对象扔到DriverManager的一个List集合中Class.forName("com.mysql.cj.jdbc.Driver");Scanner input = new Scanner(System.in);while(true){// 基于提示,做具体什么操作System.out.println("当前可以选择注册或者登录");System.out.println("注册操作输入 1");System.out.println("登录操作输入 2");int i = input.nextInt();// 因为无论是注册还是登录,都需要用户输入用户名和密码System.out.println("请输入用户名:");String username = input.next();System.out.println("请输入密码:");String password = input.next();// 根据i执行不同的逻辑if(i == 1){// 注册操作//1、获取链接Connection conn =DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc_test?characterEncoding=UTF-8", "root", "root");//2、拿到statementStatement statement = conn.createStatement();//3、准备注册的insert的SQLString sql = "insert into user (username,password) values ('"+username+"','"+password+"');";System.out.println("注册要执行的SQL:" + sql);//4、执行SQLint count = statement.executeUpdate(sql);//5、根据返回结果基于提示if(count == 1){System.out.println("注册成功!!");}//6、释放资源statement.close();conn.close();}else {// 登录操作//1、获取链接Connection conn =DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc_test?characterEncoding=UTF-8", "root", "root");//2、拿到statementStatement statement = conn.createStatement();//3、准备登录的查询SQLString sql = "select * from user where username='"+username+"' and password='"+password+"';";System.out.println("登录要执行的SQL:" + sql);//4、执行SQLResultSet resultSet = statement.executeQuery(sql);if (resultSet.next()){// 到这,说明用户名和密码正确,登录成功!System.out.println("用户名和密码正确,登录成功!");}else{// 到这,说明用户名和密码错误,登录失败!System.out.println("用户名和密码错误,登录失败!");}//5、释放资源resultSet.close();statement.close();conn.close();}}}
}

SQL注入问题

问题介绍

用户输入的数据中有SQL关键字或者语法,并且这些内容参与了SQL语句的编译,导致SQL语句编译后的条件含义为true,一致得到正确的结果,你输入的内容其实不是正确的。这种现象就成为 SQL注入

image.png

SQL注入是一个很经典的问题。 由于编写的SQL语句是在用户输入数据,整合后再进行编译的。所以为了避免SQL注入的问题,咱们要使SQL语句在用户输入数据前,就已经编译完成了完整的SQL语句,再进行填充数据。

PreparedStatement

PreparedStatement实现了Statement接口,执行SQL语句的方法,和最开始使用的Statement对象是一样的。

之前通过createStatement方法获取到的是

public class StatementImpl

现在需要使用到的是,PreparedStatement的实现类

public interface PreparedStatement

咱们也在PreparedStatement接口上的注释信息看到了基本的使用方式

将SQL语句中需要咱们填充的值,采用?代替,然后再通过PreparedStatement对象的setXxx方法,通过从1开始的索引位置,给每个?赋值。

PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES SET SALARY = ? WHERE ID = ?");
pstmt.setBigDecimal(1, 153833.00)
pstmt.setInt(2, 110592)

将前面的综合案例修改为使用PreparedStatement对象来解决之前的问题

package com.jimihua;
import java.sql.*;
import java.util.Scanner;/***  实现注册和登录操作*  基于SQL注入的问题,在这里采用PreparedStatement来解决SQL注入问题。*/
public class Demo4 {public static void main(String[] args) throws Exception {// 因为注册驱动的操作,做一次就够了,他就是将Driver的对象扔到DriverManager的一个List集合中Class.forName("com.mysql.cj.jdbc.Driver");Scanner input = new Scanner(System.in);while(true){// 基于提示,做具体什么操作System.out.println("当前可以选择注册或者登录");System.out.println("注册操作输入 1");System.out.println("登录操作输入 2");int i = input.nextInt();// 因为无论是注册还是登录,都需要用户输入用户名和密码System.out.println("请输入用户名:");String username = input.next();System.out.println("请输入密码:");String password = input.next();// 根据i执行不同的逻辑if(i == 1){// 注册操作//1、获取链接Connection conn =DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc_test?characterEncoding=UTF-8", "root", "root");//2、准备注册的insert的SQLString sql = "insert into user (username,password) values (?,?)";//3.1、拿到statementPreparedStatement ps = conn.prepareStatement(sql);//3.2 给占位符?赋值ps.setString(1,username);ps.setString(2,password);//4、执行SQLint count = ps.executeUpdate();//5、根据返回结果基于提示if(count == 1){System.out.println("注册成功!!");}//6、释放资源ps.close();conn.close();}else {// 登录操作//1、获取链接Connection conn =DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc_test?characterEncoding=UTF-8", "root", "root");//2、准备登录的查询SQLString sql = "select * from user where username = ? and password = ?";//3.1、拿到statementPreparedStatement ps = conn.prepareStatement(sql);//3.2、给?赋值ps.setString(1,username);ps.setString(2,password);//4、执行SQLResultSet resultSet = ps.executeQuery();if (resultSet.next()){// 到这,说明用户名和密码正确,登录成功!System.out.println("用户名和密码正确,登录成功!");}else{// 到这,说明用户名和密码错误,登录失败!System.out.println("用户名和密码错误,登录失败!");}//5、释放资源resultSet.close();ps.close();conn.close();}}}
}

相关文章:

java程序员入行科目一之CRUD轻松入门教程(一)

之前在操作MySQL的时候,都是采用Navicat,或者cmd黑窗口。 无论使用什么方式和MySQL交互,大致步骤是这样的 建立连接,需要输入用户名和密码编写SQL语句,和数据库进行交互 这个连接方式不会变,但是现在需要 基…...

OpenHarmony鸿蒙开发( Beta5.0)智能油烟机开发实践

样例简介 本Demo是基于Hi3516开发板,使用开源OpenHarmony开发的应用。本应用主要功能有: 可以搜索本地指定目录的图片和视频文件,并可进行点击播放。 可以通过wifi接收来自手机的美食图片以及菜谱视频,让我们对美食可以边学边做…...

【GBase 8c V5_3.0.0 分布式数据库常用维护命令】

一、查看数据库状态/检查(gbase用户) 1.gha_ctl monitor 使用gha_ctl monitor查看节点运行情况(跟dcs的地址和端口) gha_ctl monitor -c gbase -l http://172.20.10.8:2379 -Hall |coordinator | datanode | gtm | server|dcs:必选字段。指定查看哪类集…...

破解AI生成检测:如何用ChatGPT降低论文的AIGC率

学境思源,一键生成论文初稿: AcademicIdeas - 学境思源AI论文写作 降低论文的“AIGC率”是个挑战,但有一些策略可以尝试。使用ChatGPT逐步调整和改进内容,使其更加自然和原创,降低AI检测工具识别出高“AIGC率”的概率…...

Python用MarkovRNN马尔可夫递归神经网络建模序列数据t-SNE可视化研究

原文链接:https://tecdat.cn/?p37634 本文聚焦于利用马尔可夫递归神经网络(MarkovRNN)结合树库展开建模工作。MarkovRNN 通过整合马尔可夫特性与离散随机变量来深入探索递归神经网络中的随机转换机制,旨在高效处理具有复杂潜在信…...

setup函数子传父普通写法

父组件 <template><div><p>接收的数据: {{ receivedData }}</p><Demo4Chiren2 custom-event"handleGetWeb" /></div> </template><script> import { ref } from vue; import Demo4Chiren2 from ./demo4Chiren2.vue…...

seafaring靶场漏洞测试攻略

步骤一&#xff1a;打开网页 一&#xff1a;sql注入漏洞 步骤一&#xff1a;测试回显点 -1 union select 1,2,3# 步骤二&#xff1a;查看数据库 -1 union select 1,2,database()# 步骤三&#xff1a;查看表名 -1 union select 1,2,group_concat(table_name) from informati…...

简单示例,搞懂PowerBI的ALL(),ALLEXCEPT()和ALLSELECTED()的区别

假设我们有如下数据&#xff0c;我们来统计下各班级的人数 我们在报表页里加上 班级’二班‘ 的筛选条件&#xff0c;此时PowerBI已经自动为我们显示了各班级人数&#xff1a;一班有3人&#xff0c;二班有1人。 根据我们的筛选条件&#xff0c;我们的统计人数应该是按照筛选器&…...

Collection

java.util.Collections:是集合工具类 作用&#xff1a;Collections不是集合&#xff0c;而是集合的工具类 常用API addAll package Collections;import java.util.ArrayList; import java.util.Collections;public class CollectionsDemo {public static void main(String[]…...

19章 泛型

1.修改程序清单19-1中的GenericStack类&#xff0c;使用数组而不是ArrayList来实现它。你应该在给栈添加新元素之前检查数组的大小如果数组满了&#xff0c;就创建一个新数组。该数组是当前数组大小的两倍&#xff0c;然后将当前数组的元素复制到新数组中。 public class Gene…...

基于python+django+mysql+Nanodet检测模型的水稻虫害检测系统

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序、Php和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…...

计算机网络27、28——Linux命令1、2

1、虚拟机网络前方路径内容 用户名机器名&#xff1a;/$ $表示普通用户&#xff0c;#表示root用户 2、Linux不分盘&#xff0c;都是绝对路径 /表示根目录&#xff0c;表示计算机文件夹下 ~是当前用户的家&#xff0c;表示home文件夹下自己的文件夹 3、bin文件夹下的是可执…...

【Python深度学习】逆强化学习(IRL):通俗揭开学习背后的奥秘

逆强化学习:揭开学习背后的奥秘 1. 引言 当我们谈论人工智能(AI)时,很多人第一时间会想到强化学习。强化学习是一种让智能体通过与环境的互动,逐渐学习到如何做出最优决策的学习方法。然而,有一种更加神奇的学习方式叫做 逆强化学习(Inverse Reinforcement Learning,…...

Linux:五种IO模型

1&#xff1a;五种IO模型 1&#xff1a;阻塞IO 阻塞IO: 在内核将数据准备好之前,系统调用会一直等待.所有的套接字,默认 都是阻塞方式。 2&#xff1a;非阻塞 IO 非阻塞 IO: 如果内核还未将数据准备好, 系统调用仍然会直接返回, 并且返回EWOULDBLOCK 错误码。 非阻塞 IO 往往需…...

ansible企业实战

ansible最佳实践 优化ansible速度 开启SSH长连接 修改 /etc/ansible/ansible.cfg里面的参数 ssh_args -C -o ControlMasterauto -o ControlPersist5d ControlPersist5d这个参数是设置整个长连接保持时间设置为5天&#xff0c;如果开启&#xff0c;通过SSH连接过的设备都会…...

面向对象程序设计之模板进阶(C++)

在之前我出过一篇博客介绍了模版的初阶:面向对象程序设计(C)模版初阶&#xff0c;接下来我们将进行模版的进阶学习&#xff0c;介绍关于更多模版的知识 1.非类型模版参数 模板参数分类类型形参与非类型形参 类型形参即&#xff1a;出现在模板参数列表中&#xff0c;跟在class或…...

电巢科技携Ecosmos元宇宙产品亮相第25届中国光博会

第25届中国国际光电博览会&#xff08;“CIOE中国光博会”&#xff09;今日在深圳国际会展中心盛大开幕。本届博览会以“光电引领未来&#xff0c;驱动应用创新”为主题&#xff0c;吸引了全球超过3700家优质光电企业参展&#xff0c;展示了光电产业的最新成果和前沿技术。 电…...

Redis 入门 - 收官

《Redis 入门》系列文章总算完成了&#xff0c;希望这个系列文章可以想入门或刚入门的同学提供帮助&#xff0c;希望能让你形成学习Redis系统性概念。 当时为什么要写这个系列文章&#xff0c;是因为我自己就是迷迷糊糊一路踩坑走过来的&#xff0c;我踩完的坑就踩完了&#x…...

Windows技术栈企业基础底座(1)-为基于Windows的Nginx安装证书

企业的基础环境是一个组织的信息化数字化底座。传统企业基础环境多种系统&#xff0c;应用交杂&#xff0c;多种技术栈使得深入运维成本极大&#xff0c;且人员知识技能较难复用&#xff0c;造成资源浪费。本系列旨在尝试推动这一理念, 建立Windows, 或linux聚焦的技术栈的企业…...

ThreeJS入门(002):学习思维路径

查看本专栏目录 - 本文是第 002篇入门文章 文章目录 如何使用这个思维导图 Three.js 学习思维导图可以帮助你系统地了解 Three.js 的各个组成部分及其关系。下面是一个简化的 Three.js 学习路径思维导图概述&#xff0c;它包含了学习 Three.js 的主要概念和组件。你可以根据这个…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

2023赣州旅游投资集团

单选题 1.“不登高山&#xff0c;不知天之高也&#xff1b;不临深溪&#xff0c;不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程

STM32F1 本教程使用零知标准板&#xff08;STM32F103RBT6&#xff09;通过I2C驱动ICM20948九轴传感器&#xff0c;实现姿态解算&#xff0c;并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化&#xff0c;适合嵌入式及物联网开发者。在基础驱动上新增…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关

在水泥厂的生产流程中&#xff0c;工业自动化网关起着至关重要的作用&#xff0c;尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关&#xff0c;为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多&#xff0c;其中不少设备采用Devicenet协议。Devicen…...