java程序员入行科目一之CRUD轻松入门教程(二)
封装工具类
封装获取连接&释放资源操作
在实际使用JDBC的时候,很多操作都是固定的,没有必要每次都去注册驱动,获取链接对象等等。
同样,释放资源的close操作也可以封装一下
下面是封装好的具体工具类
package com.jimihua.utils;import java.sql.*;/*** 数据库操作的一个通用的内容*/
public class DatabaseUtils {// 注册驱动的操作static{try {Class.forName("com.mysql.cj.jdbc.Driver");} catch (ClassNotFoundException e) {throw new RuntimeException(e);}}/*** 获取Connection对象方法* @return*/public static Connection getConnection() {try {Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc_test?characterEncoding=utf-8", "root", "root");return connection;} catch (SQLException e) {e.printStackTrace();throw new RuntimeException("获取Connection出错!");}}/*** 针对查询操作的释放资源* @param connection* @param statement* @param resultSet*/public static void closeAll(Connection connection, Statement statement, ResultSet resultSet) {if(resultSet == null || statement == null || connection == null){throw new NullPointerException("参数传递的connection,statement,resultSet不允许为NULL");}try {resultSet.close();statement.close();connection.close();} catch (SQLException e) {throw new RuntimeException(e);}}/*** 针对写操作的释放资源* @param connection* @param statement*/public static void closeAll(Connection connection, Statement statement) {if( statement == null || connection == null){throw new NullPointerException("参数传递的connection,statement,resultSet不允许为NULL");}try {statement.close();connection.close();} catch (SQLException e) {throw new RuntimeException(e);}}}
再次迭代之前的Demo4为Demo5。
package com.jimihua;import com.jimihua.utils.DatabaseUtils;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Scanner;/*** 实现注册和登录操作* 基于SQL注入的问题,在这里采用PreparedStatement来解决SQL注入问题。*/
public class Demo5 {public static void main(String[] args) throws Exception {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 = DatabaseUtils.getConnection();//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、释放资源DatabaseUtils.closeAll(conn,ps);}else {// 登录操作//1、获取链接Connection conn = DatabaseUtils.getConnection();//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、释放资源DatabaseUtils.closeAll(conn,ps,resultSet);}}}
}
跨平台方案
现在将连接数据库的url,username,password都是写死在Java代码中的。
正常运行的项目需要编译成.class文件运行,编译过后再想修改url,username,password就挺难的。
咱们利用Hashtable的子类,Properties,将连接数据库的信息卸载外部的.properties文件中,在Java代码里,通过Properties类,将外部的.properties文件的内容加载到内存里使用。
分成几步准备
- 第一步,外部声明好一个database.properties文件,编写好连接数据库的信息
- 第二步,在Java的DatabaseUtils的工具类中,加载database.properties文件,读取连接信息
package com.jimihua.utils;import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;/*** 数据库操作的一个通用的内容*/
public class DatabaseUtils {private static final Properties PROP = new Properties();public static void main(String[] args) {DatabaseUtils db = new DatabaseUtils();}// 注册驱动的操作static{try {// 优先通过PROP对象,加载database.properties文件InputStream is = DatabaseUtils.class.getResourceAsStream("/database.properties");PROP.load(is);Class.forName(PROP.getProperty("jdbc.driver"));} catch (Exception e) {throw new RuntimeException(e);}}/*** 获取Connection对象方法* @return*/public static Connection getConnection() {try {Connection connection = DriverManager.getConnection(PROP.getProperty("jdbc.url"),PROP.getProperty("jdbc.username"),PROP.getProperty("jdbc.password"));return connection;} catch (SQLException e) {e.printStackTrace();throw new RuntimeException("获取Connection出错!");}}// 省略释放资源代码!!!!}
ORM
所谓的ORM,其实就是Object Relational Mapping,也就是对象关系映射。
O就代表你Java中的实体类,R就是你数据库中的具体表。
M就是让O和R建立一个联系。
本质的意愿,咱们在操作数据库时,需要用到SQL语句。ORM的愿景是希望使用面向对象的思维来和数据库交互,不需要了解SQL到底是什么。这种咱们成为 完整的ORM框架 能够提供的一个效果。
User findById(1); --- select * from user where id = 1; int save(User); --- insert into user (id,username,password) values (?,?,?);
但是,这种完整的ORM框架会让咱们程序员对SQL的把控很低,现在国内主流的是一款 半自动化的ORM框架 ,这种ORM框架依然需要咱们写SQL语句。
而咱们不能直接干一个框架出来,现在的目的:
- 准备好对应jdbc-test库中的user表的一个实体类,User类。
- 在查询User表时,将查询到的结果封装到User类中操作。
准备好实体类User:
package com.jimihua.entity;/*** 当前是一个实体类,目的是和数据库中的关系表产生映射关系*/
public class User {// 全部的基本数据类型,采用包装类,因为包装类可以多存储一个NULL,从而尽可能的避免出现NullPointException/** 主键Id */private Long id;/** 用户名 */private String username;/** 密码 */private String password;public User() {}public User(Long id, String username, String password) {this.id = id;this.username = username;this.password = password;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", password='" + password + '\'' +'}';}public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}
}
将查询数据库表User的结果,映射到User实体类中
package com.jimihua;import com.jimihua.entity.User;
import com.jimihua.utils.DatabaseUtils;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;/*** 是为了完成查询user表后,将user表的ResultSet结果封装到User对象中*/
public class Demo6 {public static void main(String[] args) throws SQLException {//1、获取连接对象Connection conn = DatabaseUtils.getConnection();//2、准备查询user信息的SQLString sql = "select * from user where id = ?";//3、获取PreparedStatement,传入SQLPreparedStatement ps = conn.prepareStatement(sql);//4、给占位符赋值ps.setLong(1,1);//5、执行SQL,获取ResultSet返回结果ResultSet rs = ps.executeQuery();//6、遍历ResultSet结果,封装到Userwhile(rs.next()){User user = new User();user.setId(rs.getLong("id"));user.setUsername(rs.getString("username"));user.setPassword(rs.getString("password"));System.out.println("查询到的user表信息:" + user);}//7、释放资源DatabaseUtils.closeAll(conn, ps, rs);}
}
DAO数据访问对象层
DAO层专门实现和数据库交互的操作,不参与任何逻辑。
DAO层单独封装出来的目的是为了达到解耦的效果,也就是让咱们的程序达到一个低耦合的效果。
- 对同一张表的增删改查操作都封装到一个XxxDao类中。
- 针对这个XxxDao类里提供对应的增删改查操作(insert、update、delete、findById、findAll)
现在就需要将XxxDaoImpl实现出来,如下图:
准备一个案例操作。
准备关系表
创建一张person表,提供下述字段:
- id:int类型,主键自增
- name:varchar类型,非空
- age:int类型,非空
- born_date:date类型,非空
- email:varchar类型
- address:varchar类型
create table person(id int primary key auto_increment comment '主键',name varchar(16) not null comment '名字',age int not null comment '年龄',born_date date not null comment '出生日期',email varchar(64) comment 'email',address varchar(256) comment '地址' );
自己再准备几条测试数据
准备实体类
准备Person类映射前面构建好的person表
package com.jimihua.entity;import java.util.Date;/*** 映射jdbc_test库中的person表*/
public class Person {private Integer id;private String name;private Integer age;private Date bornDate;private String email;private String address;// 省略 无参,有参,toString,get/set
}
准备DAO接口与实现类
先准备到PersonDao接口,提供抽象方法,对外提供哪些功能
package com.jimihua.dao;import com.jimihua.entity.Person;import java.util.List;/*** 构建与Person表交互的DAO层接口*/
public interface PersonDao {/*** 插入一条Person数据* @param person* @return*/int insert(Person person);/*** 根据Id修改person信息* @param person* @return*/int updateById(Person person);/*** 根据id删除一条person* @param id* @return*/int deleteById(Integer id);/*** 根据id查询一条person信息* @param id* @return*/Person findById(Integer id);/*** 查询全部person信息* @return*/List<Person> findAll();}
提供Dao层对应的实现类。
package com.jimihua.dao.impl;import com.jimihua.dao.PersonDao;
import com.jimihua.entity.Person;
import com.jimihua.utils.DatabaseUtils;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;/*** 实现PersonDao接口,实现内5个方法。*/
public class PersonDaoImpl implements PersonDao {@Overridepublic int insert(Person person) throws SQLException {//1、获取连接Connection conn = DatabaseUtils.getConnection();//2、编写SQL语句String sql = "insert into person (name,age,born_date,email,address) values (?,?,?,?,?)";//3、获取PreparedStatement,传入SQLPreparedStatement ps = conn.prepareStatement(sql);//4、给占位符赋值ps.setString(1, person.getName());ps.setInt(2, person.getAge());ps.setDate(3,new java.sql.Date(person.getBornDate().getTime()));ps.setString(4,person.getEmail());ps.setString(5, person.getAddress());//5、执行SQL,获取结果int count = ps.executeUpdate();//6、释放资源DatabaseUtils.closeAll(conn,ps);//7、返回结果return count;}@Overridepublic int updateById(Person person) throws SQLException {//1、获取连接Connection conn = DatabaseUtils.getConnection();//2、编写SQL语句String sql = "update person set name=?,age=?,born_date=?,email=?,address = ?where id=?";//3、获取PreparedStatement,传入SQLPreparedStatement ps = conn.prepareStatement(sql);//4、给占位符赋值ps.setString(1, person.getName());ps.setInt(2, person.getAge());ps.setDate(3, new java.sql.Date(person.getBornDate().getTime()));ps.setString(4, person.getEmail());ps.setString(5, person.getAddress());ps.setInt(6, person.getId());//5、执行SQL,获取结果int count = ps.executeUpdate();//6、释放资源DatabaseUtils.closeAll(conn,ps);//7、返回结果return count;}@Overridepublic int deleteById(Integer id) throws SQLException {//1、获取连接Connection conn = DatabaseUtils.getConnection();//2、编写SQL语句String sql = "delete from person where id = ?";//3、获取PreparedStatement,传入SQLPreparedStatement ps = conn.prepareStatement(sql);//4、给占位符赋值ps.setInt(1,id);//5、执行SQL,获取结果int count = ps.executeUpdate();//6、释放资源DatabaseUtils.closeAll(conn,ps);//7、返回结果return count;}@Overridepublic Person findById(Integer id) throws SQLException {//1、获取连接Connection conn = DatabaseUtils.getConnection();//2、编写SQL语句String sql = "select * from person where id = ?";//3、获取PreparedStatement,传入SQLPreparedStatement ps = conn.prepareStatement(sql);//4、给占位符赋值ps.setInt(1,id);//5、执行SQL,获取结果集ResultSetResultSet resultSet = ps.executeQuery();//6、处理结果集封装数据Person person = null;if(resultSet.next()){person = new Person();person.setId(resultSet.getInt("id"));person.setName(resultSet.getString("name"));person.setAge(resultSet.getInt("age"));person.setBornDate(resultSet.getDate("born_date"));person.setEmail(resultSet.getString("email"));person.setAddress(resultSet.getString("address"));}//7、释放资源DatabaseUtils.closeAll(conn,ps,resultSet);//8、返回结果return person;}@Overridepublic List<Person> findAll() throws SQLException {//1、获取连接Connection conn = DatabaseUtils.getConnection();//2、编写SQL语句String sql = "select * from person";//3、获取PreparedStatement,传入SQLPreparedStatement ps = conn.prepareStatement(sql);//4、执行SQL,获取结果集ResultSetResultSet rs = ps.executeQuery();//5、处理结果集封装数据List<Person> personList = new ArrayList<Person>();while (rs.next()){Person person = new Person();person.setId(rs.getInt("id"));person.setName(rs.getString("name"));person.setAge(rs.getInt("age"));person.setBornDate(rs.getDate("born_date"));person.setEmail(rs.getString("email"));person.setAddress(rs.getString("address"));// 记得封装完person,add到前面构建好的List集合中!personList.add(person);}//6、释放资源DatabaseUtils.closeAll(conn,ps,rs);//7、返回结果return personList;}
}
在main方法中测试
package com.jimihua;import java.sql.SQLException;/*** 为了测试DAO层的对象功能是否可以正常使用*/
public class Demo7 {public static void main(String[] args) throws SQLException {/*// 测试插入数据到Person表Person person = new Person();person.setName("赵六");person.setAge(26);person.setBornDate(new Date());person.setEmail("jimihua@gmail.com");person.setAddress("北京市海淀区北清路aaaa");// 准备Dao层对象PersonDao personDao = new PersonDaoImpl();int count = personDao.insert(person);System.out.println(count);*//*// 测试修改Person表中的数据Person person = new Person();person.setId(4);person.setName("赵六六");person.setAge(266);person.setBornDate(new Date());person.setEmail("jimihua@126.com");person.setAddress("北京市海淀区苏州街tttt");// 准备Dao层对象PersonDao personDao = new PersonDaoImpl();int count = personDao.updateById(person);System.out.println(count);*//*// 测试删除Person表中的数据Integer id = 4;// 准备Dao层对象PersonDao personDao = new PersonDaoImpl();int count = personDao.deleteById(id);System.out.println(count);*//*// 测试根据Id查询Person信息Integer id = 3;// 准备Dao层对象PersonDao personDao = new PersonDaoImpl();Person person = personDao.findById(id);System.out.println(person);*//*// 测试查询全部数据PersonDao personDao = new PersonDaoImpl();List<Person> list = personDao.findAll();for (Person person : list) {System.out.println(person);}*/}}
时间类型处理
现在MySQL驱动是8.0.33,MySQL驱动的版本如果是8.0.23之前的版本,会和现在有一些区别!
在上面操作增删改查时,咱们发现了一个问题。
基于PreparedStatement去给占位符设置时间类型时,他需要的是java.sql.Date类型,咱们不能直接基于java.util.Date,因为
所以,在基于ResultSet获取了一个时间类型时,才会发现,返回的是java.util.Date,但是我可以用java.util.Date去接收,明显是一个多态的效果,这个是没有问题的。
咱们针对处理这些时间类型,完整的来个小例子:
在MySQL端,咱们常用的有三种时间类型:date,datetime,timestamp。
在Java端,常用的时间类型,基本就是java.util.Date,java.time.LocalDateTime,偶尔可能也会使用字符串类型来接收时间java.lang.String
接收时间类型数据
MySQL端的时间类型,采用date类型,只有年月日。对应到Java中,如何接收上述的三种类型。
- java.util.Date: 因为ResultSet返回时,可以直接基于getDate获取到java.sql.Date,再加上之前聊到的这两个类的关系,所以可以直接接收。
- java.lang.String: ResultSet支持将时间类型直接以String的方式返回,getString可以直接拿到时间的字符串,如果你想再次转换,SimpleDateFormat就可以来转换。
- java.time.LocalDate: 在使用getObject方法那MySQL中date类型时,他返回的是java.sql.Date,所以想获取LocalDate类型,需要使用java.sql.Date提供的API,也就是toLocalDate方法直接转换。
MySQL端的时间类型,采用datetime类型,年月日时分秒。对应到Java中,如何接收上述的三种类型。
- java.sql.Date: 此时就不推荐使用getDate去获取MySQL中的datetime类型了,发现即便datetime中有时分秒,但是getDate返回的java.sql.Date拿不到时分秒。直接PASS……
- java.lang.String: 这个木有问题,依然可以正常的返回字符串类型,而且年月日,时分秒都可以正常的获取到。
- java.time.LocalDateTime: 这个很舒服,可以直接基于getObject方法获取到,返回的类型直接就是默认的java.time.LocalDateTime,不需要额外转换。但是需要记住,MySQL驱动的版本需要8.0.23以上才可以。
MySQL端的时间类型,采用timestamp类型,年月日时分秒。对应到Java中,如何接收上述的三种类型。
- java.sql.Date: 此时,依然不推荐使用getDate去获取时间戳,因为依然无法拿到时分秒…………
- java.lang.String: 这个木有问题,和datetime效果一样,很舒服。
- java.time.LocalDateTime: 这个不成,在getObject方法中,返回的依然是java.sql.Timestamp时间戳类型,但是咱们可以手动的基于toLocalDateTime方法直接转换为LocalDateTime类型。
传入时间类型数据
在给占位符赋值时,有的占位符需要赋值时间类型的字段,此时,Java中可以采用setDate,setString,setObject等等方式去给占位符赋值,此时是否有一些需要注意的点。
Java端,采用setDate(java.sql.Date)的方式去设置时间,对应MySQL端的三种时间类型,需要注意什么?
- date: 只传年月日,没问题,他只显示年月日~~
- datetime: 不成,因为java.sql.Date无法传递时分秒的信息,PASS……
- timestamp: 不成,因为java.sql.Date无法传递时分秒的信息,PASS……
Java端,采用setString(java.lang.String)的方式去设置时间,对应MySQL端的三种时间类型,需要注意什么?
- date: 没问题,正常传递字符串,只要满足格式即可 yyyy-MM-dd
- datetime: 没问题,正常传递字符串,只要满足格式即可 yyyy-MM-dd HH:mm:ss
- timestamp: 没问题,正常传递字符串,只要满足格式即可 yyyy-MM-dd HH:mm:ss
Java端,采用setObject(java.lang.Object)的方式去设置时间,可以传递字符串,可以传递java.util.Date,也可以传递java.time.LocalDateTime。
- date: 没问题,基本所有时间类型和字符串都认!!
- datetime: 没问题,基本所有时间类型和字符串都认!!
- timestamp: 没问题,基本所有时间类型和字符串都认!!
相关文章:

java程序员入行科目一之CRUD轻松入门教程(二)
封装工具类 封装获取连接&释放资源操作 在实际使用JDBC的时候,很多操作都是固定的,没有必要每次都去注册驱动,获取链接对象等等。 同样,释放资源的close操作也可以封装一下 下面是封装好的具体工具类 package com.jimihua.u…...

(不用互三)解密AI创作:提升Prompt提示词的提问技巧
文章目录 🍊AI创作的核心:提示词 Prompt 的重要性1. 什么是提示词工程?1.1 提示词的工作原理1.2 高薪提示词工程师的现实1.3 谁能胜任提示词工程师? 2. 提示词编写技巧3. 常见的提示词框架3.1 CO-STAR 框架3.2 BORKE 框架 4. 提示…...

Python 错误 ValueError 解析,实际错误实例详解 (二)
文章目录 前言Python 中错误 ValueError: Not Enough Values to UnpackPython 中的 ValueError 是什么修复Python字典中 ValueError:ValueError: not enough values to unpack修复Python中 ValueError:not enough values to unpackPython 中错误 ValueError: Setting an Arra…...

会员计次卡渲染技术-—SAAS本地化及未来之窗行业应用跨平台架构
一、计次卡应用 1. 健身中心:会员购买一定次数的健身课程或使用健身房设施的权限。 2. 美容美发店:提供一定次数的理发、美容护理等服务。 3. 洗车店:车主购买若干次的洗车服务。 4. 儿童游乐场:家长为孩子购买固定次数的入场游…...

Redis网络模型、通信协议、内存回收
Redis网络模型 一、用户空间和内核空间(前提)问题来了:为啥要区分用户空间和内核空间呢?我们来看看两个空间以及硬件是如何操作的 二、Linux中五种IO模型1、 阻塞IO2、非阻塞IO3、IO多路复用3.1、SELECT3.2、poll3.3、epoll 4、信…...

闯关leetcode——21. Merge Two Sorted Lists
大纲 题目地址内容 解题代码地址 题目 地址 https://leetcode.com/problems/merge-two-sorted-lists/description/ 内容 You are given the heads of two sorted linked lists list1 and list2. Merge the two lists into one sorted list. The list should be made by sp…...

Notepad++中提升编码效率的关键快捷键
基本操作 Ctrl N:新建文件。Ctrl O:打开文件。Ctrl S:保存文件。Ctrl Shift S:另存为。Ctrl W:关闭当前文件。 文件和标签管理 Ctrl Tab:切换到下一个标签。Ctrl Shift Tab:切换到上…...

ai智能语电销机器人有哪些功能?
近几年火爆的AI语音机器人,已经可以成熟的服务于金融贷款、理财、房地产、电商、汽车等行业,成熟的适用于电话销售、客服服务、售后管理等等基础岗位,那么ai智能语电销机器人有哪些功能?我们来看一看。 顾名思义,智能…...

ctfshow-PHP反序列化
web254 源码 <?php/* # -*- coding: utf-8 -*- # Author: h1xa # Date: 2020-12-02 17:44:47 # Last Modified by: h1xa # Last Modified time: 2020-12-02 19:29:02 # email: h1xactfer.com # link: https://ctfer.com //mytime 2023-12-4 0:22 */ error_reporting(0)…...

BEV学习---LSS-2
前言一、相关参数设置二、LSS算法前向过程 1.整体步骤2.创建视锥3.坐标变换4.视锥点云特征5.VoxelPooling 5.1 cumsum_trick(池化累积求和技巧):5.2 VoxelPooling总结 前言 目前在自动驾驶领域,比较火的一类研究方向是基于采集到的环视图像信息去构建BEV视角下的特征…...

PhpStudy下载安装使用学习
一、官网下载 官网地址:Windows版phpstudy下载 - 小皮面板(phpstudy)https://old.xp.cn/download.html 【首页】选择Windows版,进行下载 下载完成是一个压缩包的形式,解压得到一个.exe的执行文件,点击执行安装程序(注…...

在Excel中通过Python运行公式和函数实现数据计算
目录 一、引言 1.1 背景介绍 1.2 Python in Excel 的意义 二、环境准备 2.1 安装必要的软件 2.2 配置 Excel 三、基础操作 3.1 输入 Python 代码 3.2 调用 Python 库 四、案例分析 4.1 数据读取与处理 4.1.1 读取 Excel 数据 4.1.2 数据处理 4.2 数据可视化 4.2…...

基于SpringBoot+Vue的美妆购物系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的…...

uniapp uni-table合并单元格
视图层 <uni-table border stripe emptyText"暂无更多数据" class"table_x"><!-- 表头行 --><uni-tr><uni-th align"center">患者姓名</uni-th><uni-th align"center">透析方式</uni-th>&…...

MySQL 创建数据库和表全攻略
一、MySQL 创建数据库与表的重要性 MySQL 作为广泛应用的关系型数据库管理系统,创建数据库和表具有至关重要的意义。 在数据存储方面,数据库就如同一个巨大的仓库,为各类数据提供了安全、有序的存储环境。通过创建数据库,可以将相…...

大数据-126 - Flink State 03篇 状态原理和原理剖析:状态存储 Part1
点一下关注吧!!!非常感谢!!持续更新!!! 目前已经更新到了: Hadoop(已更完)HDFS(已更完)MapReduce(已更完&am…...

RFID射频模块(MFRC522 STM32)
目录 一、介绍 二、传感器原理 1.原理图 2.引脚描述 3.工作原理介绍 三、程序设计 main.c文件 MFRC522.h文件 MFRC522.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 RC522 RFID射频模块是一款广泛应用于非接触式RFID系统中的核心组件,由NXP&…...

【JavaSE】--方法的使用
文章目录 1. 方法概念及使用1.1 什么是方法1.2 方法定义1.3 方法调用的执行过程1.4 实参和形参的关系(重要)1.5 没有返回值的方法 2. 方法重载2.1 方法重载概念2.2 方法签名 3. 递归3.1 递归的概念3.2 递归执行过程分析3.3 递归练习 1. 方法概念及使用 1…...

wireshark打开时空白|没有接口,卸载重装可以解决
解决方法:卸载wireshark,全选卸载干净,重新安装旧版的wireshark4.2.7, 甚至cmd下运行net start npf时显示服务名无效,但打开wireshark仍有多个接口 错误描述: 一开始下载的是wireshark的最新版,win11 x64 在安装wir…...

单值二叉树--(C语言)
题目如下: 如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。 只有给定的树是单值二叉树时,才返回 true;否则返回 false。 示例 1: 输入:[1,1,1,1,1,null,1] 输出:true示例 2&a…...

Linux云计算 |【第三阶段】PROJECT1-DAY2
主要内容: 网站架构演变、LNPMariadb数据库分离、Web服务器集群(部署Nginx后端web服务器、部署NFS共享存储服务器、部署Haproxy代理服务器、部署DNS域名解析服务器) 一、网站架构演变: 随着网站访问量和业务复杂度的增加&#x…...

Claude Prompt 汉语新解
感谢刚哥! ;; 作者: 李继刚 ;; 版本: 0.3 ;; 模型: Claude Sonnet ;; 用途: 将一个汉语词汇进行全新角度的解释 ;; 设定如下内容为你的 *System Prompt* (defun 新汉语老师 () "你是年轻人,批判现实,思考深刻,语言风趣" (风格 . ("Oscar Wilde&q…...

【运维监控】influxdb 2.0+grafana 监控java 虚拟机以及方法耗时情况(2)
运维监控系列文章入口:【运维监控】系列文章汇总索引 文章目录 四、grafana集成influxdb监控java 虚拟机以及方法耗时情况1、添加grafana数据源2、添加grafana的dashboard1)、选择新建dashboard方式2)、导入dashboard 3、验证 关于java应用的…...

怎么看待伦敦银交易的风险与收益?
伦敦银交易的风险与收益,在宣传材料中,伦敦银是一种潜在收益很高,潜在风险不大的品种。然而在实践中我们发现,伦敦银交易好像并不如宣传材料说的那样容易做。那么,具体伦敦银交易的风险和收益是怎么样的?那…...

如何通俗易懂的解释TON的智能合约
文章目录 一、小故事一则二、Ton的智能合约在小故事中三、python代码模拟 一、小故事一则 在一个遥远的国度里,有一个被魔法笼罩的小镇,这个小镇每年都会举办一场盛大的戏剧节。这个戏剧节不仅是演员们展示才华的舞台,更是他们交流心得、共同…...

针对Docker容器的可视化管理工具—DockerUI
目录 ⛳️推荐 前言 1. 安装部署DockerUI 2. 安装cpolar内网穿透 3. 配置DockerUI公网访问地址 4. 公网远程访问DockerUI 5. 固定DockerUI公网地址 ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下…...

五大注入攻击网络安全类型介绍
1. SQL注入(SQL Injection) SQL注入流程 1.1. 概述 SQL注入是最常见的注入攻击类型之一,攻击者通过在输入字段中插入恶意的SQL代码来改变原本的SQL逻辑或执行额外的SQL语句,来操控数据库执行未授权的操作(如拖库、获取…...

linux-L9.linux中对文件 按照时间排序 显示100 个
find . -type f -exec stat --format %Y %n {} | sort -nr | head -n 100解释: • find . -type f:在当前目录下查找所有文件。 • -exec stat --format ‘%Y %n’ {} :对每个找到的文件执行stat命令,以获取文件的修改时间&#…...

springboot从分层到解耦
注释很详细,直接上代码 三层架构 项目结构 源码: HelloController package com.amoorzheyu.controller;import com.amoorzheyu.pojo.User; import com.amoorzheyu.service.HelloService; import com.amoorzheyu.service.impl.HelloServiceA; import o…...

网络视频流解码显示后花屏问题的分析
问题描述 rtp打包的ps视频流发送到客户端后显示花屏。 数据分析过程 1、用tcpdump抓包 tcpdump -i eth0 -vnn -w rtp.pcap 2、用wireshark提取rtp的payload 保存为record.h264文件 3、用vlc播放器播放 显示花屏 4、提取关键帧 用xxd命令将h264文件转为txt文件 xxd -p…...