day44_jdbc

今日内容

0 复习昨日
1 讲作业
2 数据库连接池(druid)
3 反射
4 改造DBUtil
5 完成CRUD练习

0 复习昨日

1 sql注入

2 预处理语句

3 事务操作

4 DBUtil

1 作业【重要】

利用ORM完成,以下的几个方法非常重要,将来写项目就是这些操作


写项目步骤

  • 搭建环境
    • 创建项目
    • 导入依赖
    • 工具类
    • 数据库对应实体类
  • 开发数据库层的代码
    • 数据库层代码,一般称为dao (data access object)
    • 操作的是User表,所以类UserDao
CREATE TABLE `tb_user` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户编号',`username` varchar(10) DEFAULT NULL COMMENT '用户名',`password` varchar(10) DEFAULT NULL COMMENT '密码',`phone` varchar(11) DEFAULT NULL COMMENT '手机号',`createTime` date DEFAULT NULL COMMENT '注册时间',`money` double(10,2) DEFAULT NULL COMMENT '账户余额',`sex` int(1) DEFAULT NULL COMMENT '性别 1男2女',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

1 根据id从数据库查询出用户信息
public User findUserById(int id)

2 向数据库插入一个用户,返回是否插入成功
public boolean addUser(User user)

3 通过id删除用户数据,返回boolean
public boolean deleteById(int id)
4 设计方法,查询全部数据,返回值是List集合,集合中是全部用户数据
publicList findAll()
5 通过id更改用户数据
public boolean updateById(User user)
注意:根据id更新,即参数User对象中一定有id属性值
更新user表的数据,根据User对象的属性更新,如果属性值是null则不跟更新,不为null就更新对应的字段
返回值是受影响的行数

package com.qf.dao;import com.qf.model.User;
import com.qf.util.DBUtil;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;/*** --- 天道酬勤 ---** @author QiuShiju* @desc*/
public class UserDao {/*** 根据id查用户** @param id* @return*/public User findUserById(int id) {Connection conn = DBUtil.getConnection( );PreparedStatement ps = null;ResultSet rs = null;User user = null;try {ps = conn.prepareStatement("select * from tb_user where id = ?");ps.setInt(1, id);rs = ps.executeQuery( );if (rs.next( )) {user = new User( );user.setId(rs.getInt("id"));user.setPhone(rs.getString("phone"));user.setUsername(rs.getString("username"));user.setSex(rs.getInt("sex"));user.setMoney(rs.getDouble("money"));user.setPassword(rs.getString("password"));user.setCreateTime(rs.getDate("createTime"));}} catch (Exception e) {e.printStackTrace( );} finally {DBUtil.closeAll(conn, ps, rs);}return user;}/*** 查询全部数据,返回值是List集合,集合中是全部用户数据*/public List<User> findAll() {Connection conn = DBUtil.getConnection( );PreparedStatement ps = null;ResultSet rs = null;User user = null;ArrayList<User> list = new ArrayList<>( );try {ps = conn.prepareStatement("select * from tb_user");rs = ps.executeQuery( );while (rs.next( )) {// 每一行数据都需要创建新对象user = new User( );user.setId(rs.getInt("id"));user.setPhone(rs.getString("phone"));user.setUsername(rs.getString("username"));user.setSex(rs.getInt("sex"));user.setMoney(rs.getDouble("money"));user.setPassword(rs.getString("password"));user.setCreateTime(rs.getDate("createTime"));// 将每个对象装入集合list.add(user);}} catch (Exception e) {e.printStackTrace( );} finally {DBUtil.closeAll(conn, ps, rs);}return list;}/*** 插入数据*/public boolean addUser(User user) {Connection conn = DBUtil.getConnection( );PreparedStatement ps = null;int num = 0;try {String sql = "insert into tb_user (id,username,password,phone,createTime,money,sex) values (?,?,?,?,?,?,?)";ps = conn.prepareStatement(sql);ps.setInt(1, user.getId( ));ps.setString(2, user.getUsername( ));ps.setString(3, user.getPassword( ));ps.setString(4, user.getPhone( ));ps.setDate(5, new java.sql.Date(user.getCreateTime( ).getTime( )));ps.setDouble(6, user.getMoney( ));ps.setInt(7, user.getSex( ));num = ps.executeUpdate( );} catch (Exception e) {e.printStackTrace( );} finally {DBUtil.closeAll(conn, ps);}return num > 0 ? true : false;}/*** 删除数据*/public boolean deleteById(int id) {Connection conn = DBUtil.getConnection( );PreparedStatement ps = null;int num = 0;try {String sql = "delete from tb_user where id = ?";ps = conn.prepareStatement(sql);ps.setInt(1, id);num = ps.executeUpdate( );} catch (Exception e) {e.printStackTrace( );} finally {DBUtil.closeAll(conn, ps);}return num > 0 ? true : false;}/*** 根据id更新用户* 更新user表的数据,根据User对象的属性更新,* 如果属性值是null则不更新,不为null就更新对应的字段* ---------------------------------------* update tb_user set username= ?,password = ?,phone = ? ,,,,* -------------------------------------------* 因为值为空不为空情况不一样,那么每次更新的sql语句也不太一样,* 解决方案* 1) 方案一: (更新全部字段)* 在传给updateById()的user对象中,属性全部赋值,没有null* 属性值跟原表一样的,更新了也跟原表没变化* 属性值跟原表不一样的,就会更新成新值* 2) 方案二: (更新部分字段)* 根据传给updateById()的user对象中的属性值判断* 属性有值,就更新,属性没有值就不更新* 即SQL语句要动态拼接*/// 方案一public boolean updateById1(User user) {Connection conn = DBUtil.getConnection( );PreparedStatement ps = null;int num = 0;try {String sql = "update tb_user set username = ?,password = ?," +"phone = ?,createTime = ?,money = ? ," +"sex = ? where id = ?";ps = conn.prepareStatement(sql);ps.setString(1, user.getUsername( ));ps.setString(2, user.getPassword( ));ps.setString(3, user.getPhone( ));ps.setDate(4, new java.sql.Date(user.getCreateTime( ).getTime( )));ps.setDouble(5, user.getMoney( ));ps.setInt(6, user.getSex( ));ps.setInt(7, user.getId( ));num = ps.executeUpdate( );} catch (Exception e) {e.printStackTrace( );} finally {DBUtil.closeAll(conn, ps);}return num > 0 ? true : false;}// 方案二public boolean updateById2(User user) {Connection conn = DBUtil.getConnection( );Statement statement = null;int num = 0;try {String sql = "update tb_user set ";if (user.getUsername( ) != null) {sql += "username = '" + user.getUsername( ) + "',";}if (user.getPassword( ) != null) {sql += "password = '" + user.getPassword( ) + "' ,";}if (user.getPhone( ) != null) {sql += "phone = '" + user.getPhone( ) + "' ,";}// ...继续拼接其他字段,我在此省略System.out.println("字段拼接完的sql " + sql);// update tb_user set username= 'aaa',password = '111',// 截取最后一个,int index = sql.lastIndexOf(",");String newSql = sql.substring(0, index);System.out.println("截取,后的sql  " + newSql);// 最后拼接条件newSql += " where id = " + user.getId( );System.out.println("最终的sql  " + newSql);statement = conn.createStatement( );num = statement.executeUpdate(newSql);} catch (Exception e) {e.printStackTrace( );} finally {DBUtil.closeAll(conn,statement);}return num > 0 ? true : false;}
}

测试

package com.qf.test;import com.qf.dao.UserDao;
import com.qf.model.User;import java.util.Date;
import java.util.List;/*** --- 天道酬勤 ---** @author QiuShiju* @desc*/
public class TestUserDao {public static void main(String[] args) {UserDao userDao = new UserDao( );// User user = userDao.findUserById(2);// System.out.println(user );// List<User> list = userDao.findAll( );// list.forEach(e -> System.out.println(e ));// User user = new User( );// user.setId(8);// user.setUsername("博文");// user.setPassword("123456");// user.setCreateTime(new Date());// boolean isOk = userDao.addUser(user);// System.out.println("插入是否成功?" + isOk );// boolean isOk = userDao.deleteById(4);// System.out.println("删除是否成功 " + isOk );// User user = new User( );// user.setId(1);// user.setUsername("aaaa");// user.setPassword("123456");// user.setPhone("11110000");// user.setMoney(1000);// user.setSex(1);// user.setCreateTime(new Date(122,10,21));// boolean isOk = userDao.updateById1(user);// System.out.println(isOk );User user = new User( );user.setId(2);user.setUsername("ROOT");user.setPassword("654321");boolean isOk = userDao.updateById2(user);System.out.println(isOk );}
}

小结

1 DAO是什么
2 关于数据库操作的类,应该放在什么包,什么类中
3 要将数据封装成对象(ORM)
4 学会在编码时通过输出语句确定结果是否符合预期
5 学会DEBUG
6 记住以上5个CRUD思路

2 数据库连接池

目前数据库连接是使用是建立连接,用完直接关闭连接.即需要不断创建和销毁连接.就会消耗系统资源.借鉴线程池的思想,设计出数据库连接池.

在程序初始时,预先创建好指定数量的数据库连接对象,存储连接池。需要用时就去取,用完就放回去即可。就会不会频繁创建和销毁,从而节省系统资源。

使用上的线程池有很多

  • druid (德鲁伊)
  • c3p0
  • dbcp

2.1 Druid数据库连接池

Druid是阿里开源技术,性能很好

使用步骤

  • 导入依赖druid.jar包

  • 创建一个jdbc.properties

    driverClass=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/java2217?useSSL=false
    username=root
    password=123456
    # ----- 加入druid的一些连接配置
    #<!-- 初始化连接 -->
    initialSize=10
    #最大连接数量
    maxActive=50
    #<!-- 最小空闲连接 -->
    minIdle=5
    #<!-- 超时等待时间以毫秒为单位 60000毫秒/1000等于60秒 -->
    maxWait=5000
    
  • 修改之前的DBUtil

    public class DBUtil {// 创建Properties类对象,专用于操作properties文件private static final Properties properties = new Properties();// 声明Druid连接池的连接池对象// 数据连接,一般称作数据源 dataSourceprivate static DruidDataSource dataSource;
  static {try {InputStream inputStream = DBUtil.class.getResourceAsStream("/jdbc.properties");properties.load(inputStream);// 不需要由我们加载驱动// 需要给dataSource赋值dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);} catch (Exception e) {System.out.println("加载驱动异常!!" );e.printStackTrace( );}}public static Connection getConnection() {Connection conn = null;try{// 不需要我们获得连接// 而是通过Druid获得conn = dataSource.getConnection();} catch (Exception e) {System.out.println("获得连接出异常!!!" );e.printStackTrace();}return conn;}// 后续正常...跟之前一样

}

  • 开始使用

  • 跟之前一样使用

3 反射(reflect)

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对 象,都能够调用它的任意一个方法和属性

这种动态获取的信息以及动态调用对象的方法的功能称为java 语言的反射机制。

反射是在程序运行过程中拿到类的字节码文件,进而获得类中的属性,方法等.

3.1 获得类的字节码文件

  • Object类的方法 getClass()
  • 类的静态属性 Xxx.class
  • Class类的静态方法Class.forName(“xxx”)
   /*** 演示获取字节码文件*/public static void getClassFile() throws ClassNotFoundException {// 方式1Class<?> clazz = Class.forName("com.qf.model.User");// 方式2Class<User> clazz2 = User.class;// 方式3User user = new User( );Class<? extends User> clazz3 = user.getClass( );if (clazz.equals(clazz2) && clazz2.equals(clazz3)) {System.out.println("是同一个字节码文件" );} else {System.out.println("不是" );}}

3.2 获得并设置属性(Field)

在这里插入图片描述

    /*** 获得字节码中的属性并操作*/public static void getAndSetFields() throws Exception {Class<User> clazz = User.class;/*** Filed getField(String name)*       通过属性名获得属性对象(只能获得public修饰的属性的属性对象)* Filed getDeclaredField()*       通过属性名获得属性对象(获得任意修饰符修饰的属性对象)*/// Field id = clazz.getField("id");// System.out.println(id );Field id1 = clazz.getDeclaredField("id");System.out.println(id1 );/*** Filed[]  getFields( ) 获得public修饰所有属性对象,返回数组* Filed[] getDeclaredFields( )  获得所有属性对象,返回数组*/Field[] fields = clazz.getFields( );System.out.println(fields.length );Field[] declaredFields = clazz.getDeclaredFields( );System.out.println(declaredFields.length );// =============================================// 获得属性名String name = id1.getName( );System.out.println("name = "+ name );// 获得属性访问修饰符int modifiers = id1.getModifiers( );System.out.println("访问修饰符: " + modifiers );// 获得属性值// 获得哪个对象的该属性值// 但是不能获得私有属性的值// 可以通过设置,就可以访问,id1.setAccessible(true);User user = new User( );int value = id1.getInt(user);System.out.println("id = " + value );// 设置属性值// 设置哪个对象的该属性值id1.setInt( user,11);System.out.println(user );}

3.3 获得并设置方法(Method)

在这里插入图片描述

    /***  获得字节码中的方法*/public static void getAndSeMethod() throws Exception {Class<User> clazz = User.class;// 方法有重载,需要通过参数来确定获得哪个方法Method m1 = clazz.getMethod("m1"); // 获得无参的m1方法Method m1_ = clazz.getMethod("m1",int.class); // 获得有参的m1(int)方法// 获得关于方法的所有信息int count = m1.getParameterCount( );// 参数个数int count_ = m1_.getParameterCount( );// 参数个数// 操作方法,让方法执行// 参数1: 哪个对象的该方法执行// 参数2: 该方法执行时的参数Object ret = m1.invoke(new User( ));System.out.println("m1()执行后的返回值:" + ret );m1_.invoke(new User(),222);}

3.4 获得并设置构造方法(Constructor)

在这里插入图片描述

    /***  获得字节码中的构造方法*/public static void getAndSeConstructor() throws Exception {Class<User> clazz = User.class;// 通过参数来获得有参还是无参构造Constructor<User> constructor = clazz.getConstructor( );// 构造方法执行,创建对象User user = constructor.newInstance( );System.out.println(user );// 创建字节码的对象,还有另外方法// 可以通过字节码,直接创建User user1 = clazz.newInstance( );}

4 使用反射封装DBUtil

package com.qf.util;import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;/*** --- 天道酬勤 ---** @author QiuShiju* @desc*/
public class DBUtil {// 创建Properties类对象,专用于操作properties文件private static final Properties properties = new Properties( );// 声明Druid连接池的连接池对象// 数据连接,一般称作数据源 dataSourceprivate static DruidDataSource dataSource;static {try {InputStream inputStream = DBUtil.class.getResourceAsStream("/jdbc.properties");properties.load(inputStream);// 不需要由我们加载驱动// 需要给dataSource赋值dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);} catch (Exception e) {System.out.println("加载驱动异常!!");e.printStackTrace( );}}public static Connection getConnection() {Connection conn = null;try {// 不需要我们获得连接// 而是通过Druid获得conn = dataSource.getConnection( );} catch (Exception e) {System.out.println("获得连接出异常!!!");e.printStackTrace( );}return conn;}/*** 关闭所有流*/public static void closeAll(Connection conn, Statement s) {if (conn != null) {try {conn.close( );} catch (SQLException throwables) {throwables.printStackTrace( );}}if (s != null) {try {s.close( );} catch (SQLException throwables) {throwables.printStackTrace( );}}}public static void closeAll(Connection conn, Statement s, ResultSet rs) {if (conn != null) {try {conn.close( );} catch (SQLException throwables) {throwables.printStackTrace( );}}if (s != null) {try {s.close( );} catch (SQLException throwables) {throwables.printStackTrace( );}}if (rs != null) {try {rs.close( );} catch (SQLException throwables) {throwables.printStackTrace( );}}}/*** 封装查询方法,返回一个对象* 参数1 执行查询的SQL,预处理的,条件用?占位* select * from tb_user where id = ? and username = ? and password = ?* 参数2 结果要封装的类* 参数3 给?赋值,不定长参数,是数组* 1,admin,123456*/public static <T> T selectOne(String sql, Class<T> t, Object... args) {Connection conn = getConnection( );PreparedStatement ps = null;ResultSet rs = null;T target = null;try {ps = conn.prepareStatement(sql);for (int i = 0; args != null && i < args.length; i++) {ps.setObject(i + 1, args[i]);}rs = ps.executeQuery( );/*** 创建对象* 从数据库取出数据,并设置对象属性*/while (rs.next( )) {target = t.newInstance( );Field[] declaredFields = t.getDeclaredFields( );for (int i = 0; i < declaredFields.length; i++) {Field field = declaredFields[i];Object value = rs.getObject(field.getName( ));// 破解私有field.setAccessible(true);// 给对象的该字段赋值field.set(target, value);}}} catch (Exception e) {e.printStackTrace( );} finally {closeAll(conn, ps, rs);}return target;}public static <T> List<T> selectAll(String sql, Class<T> t, Object... args) {Connection conn = getConnection( );PreparedStatement ps = null;ResultSet rs = null;T target = null;ArrayList<T> list = new ArrayList<>( );try {ps = conn.prepareStatement(sql);for (int i = 0; args != null && i < args.length; i++) {ps.setObject(i + 1, args[i]);}rs = ps.executeQuery( );/*** 创建对象* 从数据库取出数据,并设置对象属性*/while (rs.next( )) {target = t.newInstance( );Field[] declaredFields = t.getDeclaredFields( );for (int i = 0; i < declaredFields.length; i++) {Field field = declaredFields[i];Object value = rs.getObject(field.getName( ));// 破解私有field.setAccessible(true);// 给对象的该字段赋值field.set(target, value);}list.add(target);}} catch (Exception e) {e.printStackTrace( );} finally {closeAll(conn, ps, rs);}return list;}/*** 增删改方法一样*/public static boolean update(String sql, Object... args) {Connection conn = getConnection( );PreparedStatement ps = null;int num = 0;try {ps = conn.prepareStatement(sql);for (int i = 0; args != null && i < args.length; i++) {ps.setObject(i + 1, args[i]);}num = ps.executeUpdate( );} catch (Exception e) {e.printStackTrace( );} finally {closeAll(conn, ps);}return num > 0 ? true : false;}
}

5 作业

1 上午5道题,按照格式(包名,类名,到封装)写一遍
2 重复一遍反射代码
3 封装DBUtil理解
4 DBUtil再次写那5道题
5 昨天sql题,写个2道

finally {
closeAll(conn, ps, rs);
}
return list;
}

/*** 增删改方法一样*/
public static boolean update(String sql, Object... args) {Connection conn = getConnection( );PreparedStatement ps = null;int num = 0;try {ps = conn.prepareStatement(sql);for (int i = 0; args != null && i < args.length; i++) {ps.setObject(i + 1, args[i]);}num = ps.executeUpdate( );} catch (Exception e) {e.printStackTrace( );} finally {closeAll(conn, ps);}return num > 0 ? true : false;
}

}

# 5 作业

1 上午5道题,按照格式(包名,类名,到封装)写一遍
2 重复一遍反射代码
3 封装DBUtil理解
4 DBUtil再次写那5道题
5 昨天sql题,写个2道

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

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

相关文章

Oracle笔记-为表空间新增磁盘(ORA-01691)

如下报错&#xff1a; 原因是Oracle表空间满了&#xff0c;最好是新增一个存储盘。 #查XXX命名空间目前占用了多大的空间 select FILE_NAME,BYTES/1024/1024 from dba_data_files where tablespace_name XXXX #这里的FILE_NAME能查到DBF的存储位置#将对应的datafile设置为30g…

ffmpeg命令生成器

FFmpeg 快速入门&#xff1a;命令行详解、工具、教程、电子书 – 码中人的博客FFmpeg 是一个强大的命令行工具&#xff0c;可以用来处理音频、视频、字幕等多媒体文件。本文介绍了 FFmpeg 的基本用法、一些常用的命令行参数&#xff0c;以及常用的可视化工具。https://blog.mzh…

Golang与Erlang有什么差异

Golang和Erlang是两种备受关注的编程语言&#xff0c;它们各自具有独特的特点和优势。下面我将简单的探讨一下Golang和Erlang之间的差异&#xff0c;并且分析它们在并发模型、运行环境、函数式编程和领域特性等多个方面的不同之处。 并发模型 Golang使用goroutines和channels…

Java设计模式大全:23种常见的设计模式详解(二)

本系列文章简介&#xff1a; 设计模式是在软件开发过程中&#xff0c;经过实践和总结得到的一套解决特定问题的可复用的模板。它是一种在特定情境中经过验证的经验和技巧的集合&#xff0c;可以帮助开发人员设计出高效、可维护、可扩展和可复用的软件系统。设计模式提供了一种在…

计算机是如何工作的

计算机工作 计算机发展史CPU基本工作流程编程语言程序&#xff08;Program&#xff09;编程语言的发展 操作系统进程/任务进程控制块CPU分配&#xff08;进程调度&#xff09;内存分配&#xff08;内存管理&#xff09;进程间通信 计算机发展史 四个发展阶段&#xff1a; 第一…

python创建udf函数步骤

一、目标 实现一个函数&#xff0c;传入两个datetime类型的参数&#xff0c;返回double类型的工作日天数 二、思路 如何计算差值&#xff1f; 如果开始时间和结束时间在同一天&#xff1a;实现同 datediff(end, start, ‘ss’) / 86400.0 如果开始时间和结束时间在不同天&am…

3. ⼤语⾔模型深度学习背景知识

1. LLM⼤语⾔模型⼀般训练过程 #mermaid-svg-8kci1fjEPiVolPue {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-8kci1fjEPiVolPue .error-icon{fill:#552222;}#mermaid-svg-8kci1fjEPiVolPue .error-text{fill:#5522…

QML用ListView实现带section的GridView

QML自带的GridView只能定义delegate&#xff0c;没有section&#xff0c;类似手机相册带时间分组标签的样式就没法做。最简单的方式就是组合ListViewGridView&#xff0c;或者ListViewFlow&#xff0c;但是嵌套View时&#xff0c;子级View一般是完全展开的&#xff0c;只显示该…

Mybatis中的sql-xml延迟加载机制

Mybatis中的sql-xml延迟加载机制 hi&#xff0c;我是阿昌&#xff0c;今天记录一下关于Mybatis中的sql-xml延迟加载机制 一、前言 首先mybatis技术本身就不多介绍&#xff0c;说延迟加载机制之前&#xff0c;那要先知道2个概念&#xff1a; 主查询对象关联对象 假设咱们现…

OpenCV 笔记(20):霍夫圆检测

1. 霍夫圆变换 霍夫圆变换(Hough Circle Transform)是一种数字图像处理中的特征提取技术&#xff0c;用于在图像中检测圆形。它将二维图像空间中一个圆转换为该圆半径、圆心横纵坐标所确定的三维参数空间中一个点的过程。因此&#xff0c;圆周上任意三点所确定的圆&#xff0c…

ElasticSearch查询语句用法

查询用法包括&#xff1a;match、match_phrase、multi_match、query_string、term 1.match 1.1 不同字段权重 如果需要为不同字段设置不同权重&#xff0c;可以考虑使用bool查询的should子句来组合多个match查询&#xff0c;并为每个match查询设置不同的权重 {"query&…

二叉树的详解

二叉树 【本节目标】 掌握树的基本概念掌握二叉树概念及特性掌握二叉树的基本操作完成二叉树相关的面试题练习 树型结构&#xff08;了解&#xff09; 概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。…

JS-本地文件上传

由于不需要原上传文件的样式&#xff0c;所以自己书写了一个按钮触发文件上传&#xff0c;并将原本的样式隐藏 <!doctype html> <html><head><meta charset"utf-8"><title>文件传输</title> </head><body><inpu…

工业笔记本丨行业三防笔记本丨亿道加固笔记本定制丨极端温度优势

工业笔记本是专为在恶劣环境条件下工作而设计的高度耐用的计算机设备。与传统消费者级笔记本电脑相比&#xff0c;工业笔记本在极端温度下展现出了许多优势。本文将探讨工业笔记本在极端温度环境中的表现&#xff0c;并介绍其优势。 耐高温性能: 工业笔记本具有更高的耐高温性…

安卓动态链接库文件体积优化探索实践

背景介绍 应用安装包的体积影响着用户下载量、安装时长、用户磁盘占用量等多个方面&#xff0c;据Google Play统计&#xff0c;应用体积每增加6MB&#xff0c;安装的转化率将下降1%。 安装包的体积受诸多方面影响&#xff0c;针对dex、资源文件、so文件都有不同的优化策略&…

【极数系列】Flink集成KafkaSource 实时消费数据(10)

文章目录 01 引言02 连接器依赖2.1 kafka连接器依赖2.2 base基础依赖 03 连接器使用方法04 消息订阅4.1 主题订阅4.2 正则表达式订阅4.3 Partition 列分区订阅 05 消息解析06 起始消费位点07 有界 / 无界模式7.1 流式7.2 批式 08 其他属性8.1 KafkaSource 配置项&#xff08;1&…

如何训练自己的模型

无论数据类型或目标如何&#xff0c;用于训练和使用 AutoML 模型的工作流都是相同的&#xff1a; 准备训练数据。 我们需要将需要训练的数据准备为jsonl格式&#xff0c;这种格式的特点就是每一行都是json的格式 {"prompt": "<prompt text>", "…

【初识爬虫+requests模块】

爬虫又称网络蜘蛛、网络机器人。本质就是程序模拟人使用浏览器访问网站&#xff0c;并将需要的数据抓取下来。爬虫不仅能够使用在搜索引擎领域&#xff0c;在数据分析、商业领域都得到了大规模的应用。 URL 每一个URL指向一个资源&#xff0c;可以是一个html页面&#xff0c;一…

配置git环境与项目创建

项目设计 名称&#xff1a;KOB 项目包含的模块 PK模块&#xff1a;匹配界面&#xff08;微服务&#xff09;、实况直播界面&#xff08;WebSocket协议&#xff09; 对局列表模块&#xff1a;对局列表界面、对局录像界面 排行榜模块&#xff1a;Bot排行榜界面 用户中心模块&…

从Kafka系统中读取消息数据——消费

从Kafka系统中读取消息数据——消费 消费 Kafka 集群中的主题消息检查消费者是不是单线程主题如何自动获取分区和手动分配分区subscribe实现订阅&#xff08;自动获取分区&#xff09;assign&#xff08;手动分配分区&#xff09; 反序列化主题消息反序列化一个类.演示 Kafka 自…