day30_jdbc

news2024/9/23 19:26:03

·今日内容

零、 复习昨日
一、作业
二、SQL注入
三、PreparedStatement
四、事务
五、DBUtil

零、 复习昨日

见晨考

一、作业

package com.qf.homework;

import com.qf.entity.User;

import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc
 */
public class CRUD {

    public static void main(String[] args) throws ClassNotFoundException {
        User user = new User( );
        user.setId(4);
        user.setUsername("xiaoli");
        user.setPassword("123456");
        user.setSex("男");
        user.setAge(19);
        user.setMoney(1000);
        user.setBirthday(new Date());

        // 注册
        //addUser(user);

        // 删除
        //int i = deleteById(4);
        //System.out.println(i > 0 ?"OK":"ERROR" );

        // 根据id查询
        // User u = getUserById(20);
        // System.out.println(u );

        // 查全部
        //List<User> list = findAll( );
        // for (User user1 : list) {
        //
        // }
        //list.forEach(e -> System.out.println(e ));


        // 更新
        User user2 = new User( );
        user2.setId(4);
        user2.setUsername("小李子");
        user2.setPassword("666666");
         // user2.setSex("男");
         // user2.setAge(19);
        // user2.setMoney(1000);
        // user2.setBirthday(new Date());
        int i = updateById2(user2);
        System.out.println(i > 0 ?"OK":"ERROR" );


    }
    /**
     * 方案2: 动态更新
     *      根据对象属性值是否为空,动态的拼接sql
     *      update tb  set username= 1 where  id = 1
     *      update tb  set password = 1 where  id = 1
     *      update tb  set username= 1 , password = 1 where  id = 1
     *      update tb  set a = 1 ,b= 1 , c = 1where  id = 1
     */
    public static int updateById2(User user) {
        Connection conn = null;
        Statement statement = null;
        int num = 0;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/java2307?useSSL=false", "root", "123456");
            statement = conn.createStatement( );

            String sql = "update tb_user set ";
            if (user.getUsername() != null) {
                sql += "username = '" + user.getUsername()+"',";
            }
            if (user.getPassword() != null) {
                sql += "password = '" + user.getPassword()+"',";
            }
            if (user.getSex() != null) {
                sql += "sex = '" + user.getSex()+"',";
            }
            if (user.getAge() != 0) {
                sql += "age = " + user.getAge()+",";
            }
            if (user.getBirthday() != null) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                String format = sdf.format(user.getBirthday( ));
                sql += "birthday = '" +format+"',";
            }
            if (user.getMoney() != 0.0) {
                sql += "money = " + user.getMoney()+",  ";
            }
            // 找到最后一个逗号位置
            int index = sql.lastIndexOf(",");
            String sql2 = sql.substring(0, index);
            sql2 += " where id = " + user.getId();
            System.out.println("sql --> " + sql2 );
            num = statement.executeUpdate(sql2);
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                statement.close( );
                conn.close( );
            }catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return num;
    }
    //通过id更改用户数据
    /**
     * 注意:根据id更新,即参数User对象中一定有id属性值
     * 更新有2种方案:
     * 方案1: 全表更新
     *      接收全部字段的数据(要求user对象的属性全部有值),更新全部字段
     */
    public static int updateById(User user) {
        Connection conn = null;
        Statement statement = null;
        int num = 0;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/java2307?useSSL=false", "root", "123456");
            statement = conn.createStatement( );

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String format = sdf.format(user.getBirthday( ));

            String sql = "update tb_user set username = '"+user.getUsername()+"' , " +
                    "password = '"+user.getPassword()+"'," +
                    "sex = '"+user.getSex()+"'," +
                    "age = "+user.getAge()+"," +
                    "birthday = '"+format+"'," +
                    "money = "+user.getMoney()+" " +
                    "where id = "+user.getId();
            System.out.println("sql --> " + sql );
            num = statement.executeUpdate(sql);
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                statement.close( );
                conn.close( );
            }catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return num;
    }


    // 设计方法,查询全部数据,返回值是List集合,集合中是全部用户数据
    public static List<User> findAll(){
        Connection conn = null;
        Statement statement = null;
        User user = null;
        // 创建集合,存储所有对象
        ArrayList<User> list = new ArrayList<>( );
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/java2307?useSSL=false", "root", "123456");
            statement = conn.createStatement( );

            ResultSet rs = statement.executeQuery("select * from tb_user");

            while(rs.next()) { // 判断成功,说明查到数据
                // 取出数据
                int id = rs.getInt("id");
                String username1 = rs.getString("username");
                String password1 = rs.getString("password");
                String sex = rs.getString("sex");
                int age = rs.getInt("age");
                java.sql.Date birthday = rs.getDate("birthday");
                double money = rs.getDouble("money");
                // 创建对象
                user = new User( );
                // 封装数据
                user.setId(id);
                user.setUsername(username1);
                user.setPassword(password1);
                user.setSex(sex);
                user.setAge(age);
                user.setBirthday(birthday);
                user.setMoney(money);
                // 将每个对象存储到集合
                list.add(user);
            }
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                statement.close( );
                conn.close( );
            }catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return list;
    }

    // 根据id从数据库查询出用户信息
    public static User getUserById(int id) {
        Connection conn = null;
        Statement statement = null;
        User user = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/java2307?useSSL=false", "root", "123456");
            statement = conn.createStatement( );

            ResultSet rs = statement.executeQuery("select * from tb_user where id = " + id);

            if(rs.next()) { // 判断成功,说明查到数据
                // 取出数据
                String username1 = rs.getString("username");
                String password1 = rs.getString("password");
                String sex = rs.getString("sex");
                int age = rs.getInt("age");
                java.sql.Date birthday = rs.getDate("birthday");
                double money = rs.getDouble("money");
                // 创建对象
                user = new User( );
                // 封装数据
                user.setId(id);
                user.setUsername(username1);
                user.setPassword(password1);
                user.setSex(sex);
                user.setAge(age);
                user.setBirthday(birthday);
                user.setMoney(money);
            }
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                statement.close( );
                conn.close( );
            }catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return user;
    }

    // 通过id删除用户数据,返回受影响行数
    // delete from tb_user where id =
    // TODO: 思考题 批量删除
    public static int deleteById(int id) {
        Connection conn = null;
        Statement statement = null;
        int num = 0;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/java2307?useSSL=false", "root", "123456");
            statement = conn.createStatement( );

            num = statement.executeUpdate("delete from tb_user where id = " + id);

        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                statement.close( );
                conn.close( );
            }catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return num;
    }

    // 向数据库插入一个用户,返回是否插入成功
    public static boolean addUser(User user) {
        Connection conn = null;
        Statement statement = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/java2307?useSSL=false", "root", "123456");
            statement = conn.createStatement( );

            // 因为new Date() 形式是Tue May 09 17:01:55 CST 2023
            // 插入时不识别,所以需要将这个日期格式改造成yyyy-MM-dd
            // 即格式化
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String format = sdf.format(user.getBirthday( ));

            String sql = "insert into tb_user values" +
                    " ("+user.getId()+",'"+user.getUsername()+"'," +
                    "'"+user.getPassword()+"','"+user.getSex()+"'," +
                    ""+user.getAge()+",'"+format+"'," +
                    ""+user.getMoney()+")";
            // 拼接完SQL要打印一下,确定SQL如何
            System.out.println(sql );

            int i = statement.executeUpdate(sql);
            if (i > 0) {
                return true;
            }

        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                statement.close( );
                conn.close( );
            }catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return false;
    }
}

二、SQL注入

2.1 什么是SQL注入

select * from tb_user where username = ‘111’ and password = ‘111

select * from tb_user where username = ‘111’ and password = ‘111' or '1=1

用户输入的数据中有SQL关键词,导致在执行SQL语句时出现一些不正常的情况.这就是SQL注入!


出现SQL注入是很危险

image-20230322084643699

2.2 避免SQL注入

问题出现在用户输入数据时,里面有关键词,再配合字符串拼接导致出现SQL注入.所以为了避免SQL注入,可以在用户输入数据到SQL之前,先把SQL语句预编译,预处理后,JDBC就会知道此SQL需要几个参数,后续再将用户输入的数据给参数填充.

这就是PreparedStatement

三、PreparedStatement【重点】

PreparedStatement是Statement的子接口,用来预处理SQL语句

PreparedStatement使用

  • 先写SQL语句,SQL语句中的参数不能直接拼接,而是使用?占位
  • 使用ps预处理SQL语句,处理的?号,ps内部就会知道此SQL语句需要几个参数
  • 再动态给?处填充值

image-20230322084657336

package com.qf.jdbc;

import java.sql.*;
import java.util.Scanner;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc 登录-使用预处理语句完成
 */
public class Demo2_LoginPlus {

    public static void main(String[] args) throws Exception {

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入用户名:" );
        String username = scanner.nextLine( );

        System.out.println("请输入密码:" );
        String password = scanner.nextLine( );

        Class.forName("com.mysql.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/java2217?useSSL=false", "root", "123456");

        // 改造SQL,将拼接变量,变成?占位
        String sql = "select * from tb_user where username = ? and password = ?";
        System.out.println("处理前:  " + sql);

        // 由之前的Statement换成PreparedStatement
        // 将改造好的SQL,传入方法
        PreparedStatement ps = conn.prepareStatement(sql);
        System.out.println("处理后: " + ps );

        // 给处理好的占位参数赋值
        // ps.setXxx() 给指定Xxx类型赋值
        // 第一个?,下标是1
        ps.setString(1,username);
        ps.setString(2,password);

        System.out.println("填充后: " + ps );

        //【特别注意!!!!】 此处executeQuery不需要再传入SQL参数!!!
        ResultSet rs = ps.executeQuery();

        if (rs.next()) {
            System.out.println("登录成功!!" );
        } else {
            System.out.println("用户名或密码错误!" );
        }

        rs.close();
        ps.close();
        conn.close();
    }
}
请输入用户名:
111
请输入密码:
111' or '1=1
处理前:  select * from tb_user where username = ? and password = ?
处理后: select * from tb_user where username = ** NOT SPECIFIED ** and password = ** NOT SPECIFIED **
填充后: select * from tb_user where username = '111' and password = '111\' or \'1=1'
用户名或密码错误!

四、预处理语句完成CRUD

4.1 插入


    // 向数据库插入一个用户,返回是否插入成功
    public static boolean addUser(User user) throws Exception {
        // 1 注册驱动
        Class.forName("com.mysql.Driver");
        // 2 获得连接
        String url = "jdbc:mysql://localhost:3306/java2301?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false";
        String username = "root";
        String password = "123456";
        Connection conn = DriverManager.getConnection(url, username, password);

        // 3.1 写sql,参数拼接,变?
        String sql = "insert into tb_user (username,password,phone,createTime,money,sex) " +
                "values (?,?,?,?,?,?)";

        // 3.2 处理?问
        PreparedStatement ps = conn.prepareStatement(sql);

        // 3.3 ?赋值
        ps.setString(1,user.getUsername());
        ps.setString(2,user.getPassword());
        ps.setString(3,user.getPhone());

        // 日期需要转换成java.sql.Date才能赋值
        java.sql.Date date = new java.sql.Date(user.getCreateTime( ).getTime( ));
        ps.setDate(4,date);

        ps.setDouble(5,user.getMoney());
        ps.setInt(6,user.getSex());

        // 4 执行
        int i = ps.executeUpdate( );

        return i > 0 ? true:false;
    }

4.2 更新

    public static int updateById(User user) throws Exception {
        // 1 注册驱动
        Class.forName("com.mysql.Driver");
        // 2 获得连接
        String url = "jdbc:mysql://localhost:3306/java2301?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false";
        String username = "root";
        String password = "123456";
        Connection conn = DriverManager.getConnection(url, username, password);

        // 3.1 写sql,参数变?号
        String sql = "update tb_user set username = ?," +
                "password = ?," +
                "phone = ?," +
                "createTime = ?," +
                "money = ?," +
                "sex = ? " +
                "where id = ?";
        // 3.2 处理?问
        PreparedStatement ps = conn.prepareStatement(sql);

        // 3.3 ?赋值
        ps.setString(1,user.getUsername());
        ps.setString(2,user.getPassword());
        ps.setString(3,user.getPhone());

        // 日期需要转换成java.sql.Date才能赋值
        java.sql.Date date = new java.sql.Date(user.getCreateTime( ).getTime( ));
        ps.setDate(4,date);

        ps.setDouble(5,user.getMoney());
        ps.setInt(6,user.getSex());
        ps.setInt(7,user.getId());

        // 4 执行
        int i = ps.executeUpdate( );

        ps.close();
        conn.close();

        return i;
    }

4.3 删除


    /// 通过id删除用户数据,返回受影响行数
    public static int deleteById(int id) throws Exception{
        // 1 注册驱动
        Class.forName("com.mysql.Driver");
        // 2 获得连接
        String url = "jdbc:mysql://localhost:3306/java2301?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false";
        String username = "root";
        String password = "123456";
        Connection conn = DriverManager.getConnection(url, username, password);

        // 3.1 写sql,参数写?
        String sql = "delete from tb_user where id = ?";
        // 3.2 处理?
        PreparedStatement ps = conn.prepareStatement(sql);
        // 3.3 给?赋值
        ps.setInt(1,id);

        // 4 执行
        int i = ps.executeUpdate( );

        return i;
    }

4.4 查询

// 根据id从数据库查询出用户信息
    public static User getUserById(int id) throws Exception {
        // 1 注册驱动
        Class.forName("com.mysql.Driver");
        // 2 获得连接
        String url = "jdbc:mysql://localhost:3306/java2301?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false";
        String username = "root";
        String password = "123456";
        Connection conn = DriverManager.getConnection(url, username, password);
        User user = null;
        // 3 预处理
        // 3.1 写sql,参数用?占位
        String sql = "select  * from tb_user where id = ?";
        // 3.2 预处理?号
        PreparedStatement ps = conn.prepareStatement(sql);
        // 3.3 给?赋值
        ps.setInt(1,id);

        // 4 执行sql
        ResultSet rs = ps.executeQuery( );

        if(rs.next()) {
            // 取出数据
            String username1 = rs.getString("username");
            String password1 = rs.getString("password");
            String phone = rs.getString("phone");
            Date createTime = rs.getDate("createTime");
            double money = rs.getDouble("money");
            int sex = rs.getInt("sex");

            // 封装数据
            user = new User();
            user.setId(id);
            user.setUsername(username1);
            user.setPassword(password1);
            user.setPhone(phone);
            user.setCreateTime(createTime);
            user.setMoney(money);
            user.setSex(sex);
        }

        return user;
    }
 // 设计方法,查询全部数据,返回值是List集合,集合中是全部用户数据
    public static List<User> findAll() throws Exception{
        // 1 注册驱动
        Class.forName("com.mysql.Driver");
        // 2 获得连接
        String url = "jdbc:mysql://localhost:3306/java2301?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false";
        String username = "root";
        String password = "123456";
        Connection conn = DriverManager.getConnection(url, username, password);
        ArrayList<User> list = new ArrayList<>( );
        User user = null;
        // 3.1 写sql
        String sql = "select * from tb_user";
        // 3.2 处理sql
        PreparedStatement ps = conn.prepareStatement(sql);

        // 4 执行
        ResultSet rs = ps.executeQuery( );


        while(rs.next()) {
            // 取出数据
            int id = rs.getInt("id");
            String username1 = rs.getString("username");
            String password1 = rs.getString("password");
            String phone = rs.getString("phone");
            Date createTime = rs.getDate("createTime");
            double money = rs.getDouble("money");
            int sex = rs.getInt("sex");

            // 封装数据
            user = new User();
            user.setId(id);
            user.setUsername(username1);
            user.setPassword(password1);
            user.setPhone(phone);
            user.setCreateTime(createTime);
            user.setMoney(money);
            user.setSex(sex);

            // 【重点】 将对象存储入集合
            list.add(user);
        }

        return list;
    }

五、事务处理【了解】

事务是逻辑一组操作,要么全部成功,要么全部失败!


使用mysql客户端操作事务

  • 因为mysql支持事务,且每句话都在事务内,且自动提交
  • 所以关闭自动提交事务,手动开启事务 start transaction
  • 正常写sql/执行sql
  • 一切正常,提交事务 commit
  • 如果不正常,要回滚 rollback

JDBC也可以完成事务操作

  • conn.setAutoCommit(false) 关闭自动提交,就相当于是开启手动管理
  • 正常的处理sql
  • 一切正常,提交事务 conn.commit()
  • 如果不正常,回滚 conn.rollback()

演示: 以转账案例演示

package com.qf.tx;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc 以转账为案例演示
 * --------------------
 * Statement语句和PreparedStatement语句
 * 与事务操作没有影响
 */
public class Demo6_TX {

    // 张三转账给李四
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement ps1 = null;
        PreparedStatement ps2 = null;
        try {
            Class.forName("com.mysql.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/java2217?useSSL=false", "root", "123456");

            // 【1 开启事务】
            conn.setAutoCommit(false);

            // 张三的钱减少100
            String sql1 = "update account set money = money - 100 where id = 1";
            ps1 = conn.prepareStatement(sql1);
            int num = ps1.executeUpdate( );
            if (num > 0) {
                System.out.println("张三转账(-100)完成!");
            }

            System.out.println(1/0 ); // 模拟在转账中,出现异常,后续不执行

            // 李四的钱要增加100
            String sql2 = "update account set money = money + 100 where id = 2";
            ps2 = conn.prepareStatement(sql2);
            int num2 = ps2.executeUpdate( );
            if (num2 > 0) {
                System.out.println("李四转账(+100)完成!");
            }

            // 【2 一切顺利,提交事务】
            conn.commit();

        } catch (Exception e) {
            try{
                // 【3 不顺利,中间有异常,回滚事务】
                conn.rollback();
            }catch (Exception e2) {
                System.out.println("回滚事务异常!!" );
                e2.printStackTrace();
            }
            System.out.println("SQL异常!!!");
            e.printStackTrace( );
        } finally {
            try {
                ps1.close( );
                ps2.close( );
                conn.close( );
            } catch (Exception e) {
                System.out.println("关流时有异常!!");
                e.printStackTrace( );
            }
        }
    }
}

另外发现: 建立与Mysql连接后,关流之前,可以执行很多次SQL语句

六、DBUtil【理解,会用】

DBUtil操作数据库的工具类,因为发现每次操作数据库,JDBC的步骤第1,2,5步完全重复的,即加载驱动,获得连接对象,已经最后的关流是每次都要写但每次都是一样的!!!


现在设计工具类,简化第1,2,5步

  • 设计个方法,调用直接获得连接对象
  • 设计个方法,调用直接关闭全部的流对象
package com.qf.util;

import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc
 */
public class DBUtil {

    // 创建Properties类对象,专用于操作properties文件
    private static final Properties properties = new Properties();

    /**
     * 加载驱动的目的是为了在JVM中有sql运行的环境
     * 该环境有一份就行了,不用重复加载
     * ------------------------------------
     * static 静态代码块
     * 1) 保证内存中只有一份
     * 2) 保证随着类加载而加载,即该代码块会执行
     */
    static {

        // 通过反射的技术获得字节码文件
        // 再通过字节码文件将配置文件读取成输入流
        InputStream inputStream = DBUtil.class.getResourceAsStream("/db.properties");
        try {
            // 再通过流获得其中数据
            properties.load(inputStream);
            // 从properties对象取值
            Class.forName(properties.getProperty("driverClass"));
        } catch (Exception e) {
            System.out.println("加载驱动异常!!" );
            e.printStackTrace( );
        }
    }

    /**
     * 一般会将关于JDBC配置信息,抽取出来,形成一个配置文件,方便维护
     * 文件类型是properties文件,该文件类似map,键值对类型
     * 名字 properties
     * 位置 src/properties
     * 内容
     */
    public static Connection getConnection() {
        Connection conn = null;
        try{
            conn = DriverManager.getConnection(properties.getProperty("url"),properties.getProperty("username") ,properties.getProperty("password") );
        } 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( );
            }
        }
    }
}

在src下创建db.properties文件

driverClass=com.mysql.Driver
url=jdbc:mysql://localhost:3306/java2217?useSSL=false
username=root
password=123456

image-20230321170200023

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

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

相关文章

Selenium技术在CentOS6.8系统的腾讯云服务器上的相关使用(Linux环境下)

目录 一、解释说明二、操作过程中Linux相关命令1、下载谷歌浏览器2、查看谷歌浏览器的版本3、下载对应版本的谷歌驱动&#xff08;或者本地上传&#xff09;4、解压下载的文件5、移动下载文件6、给予文件执行权限7、更新pip3到最高版本8、下载Selenium第三方库9、正式测试10、最…

Rust 快速入门60分① 看完这篇就能写代码了

Rust 一门赋予每个人构建可靠且高效软件能力的语言https://hannyang.blog.csdn.net/article/details/130467813?spm1001.2014.3001.5502关于Rust安装等内容请参考上文链接&#xff0c;写完上文就在考虑写点关于Rust的入门文章&#xff0c;本专辑将直接从Rust基础入门内容开始讲…

如何预测药品市场规模

药品市场规模预测是一个非常关键的步骤&#xff0c;可以帮助判断该项目是否值得投资或开发。以下是一些常见的方法&#xff1a; 药品市场规模可以细分为治疗领域市场规模、药品种类市场规模、区域市场规模、渠道市场规模、品牌市场规模、性质市场规模等。这些规模的了解是一个非…

【Hello Algorithm】异或法

作者&#xff1a;小萌新 专栏&#xff1a;算法 作者简介&#xff1a;大二学生 希望能和大家一起进步 本篇博客简介&#xff1a;介绍算法中的异或法 异或法 异或的概念异或的两个性质题目一 不使用额外变量交换两个数字题目二 出现奇数次的数字题目三 如何从一个整型数字中提取出…

石油化工行业室内外高精度人员定位系统解决方案

石油化工行业是高危行业&#xff0c;很容易发生安全事故&#xff0c;对于石化企业来说&#xff0c;加强人员的安全管控非常有必要。我们可以通过人员定位技术&#xff0c;提升石化企业安全管理水平。下面给大家分享石油化工行业室内外高精度人员定位系统解决方案。 方案概述 石…

BERT原理Fine TuningBert变种

文章目录 BERT原理训练时的任务任务一任务二任务二的改进 模型的输入 BERT - Fine Tuning单个句子的预测类序列标注类Q&A类seq2seq&#xff1f; BERT 变种Transformer-XLXLNetAutoregressive Language ModelDenoising Auto-Encoder乱序Two-Stream Attention与Transformer-X…

RocketMQ双主双从环境搭建

环境要求 64位操作系统&#xff0c;推荐 Linux/Unix/macOS 64位 JDK 1.8 服务器准备 准备4台服务器两台master两台slave&#xff0c;如果服务器紧凑&#xff0c;则至少需要两台服务器相互master-slave IP HOSTS 172.*******.120 rocketmq-nameserver1 rocketmq-master1 …

ElasticSearch小计

1、ElasticSearch简介 1.1、ElasticSearch&#xff08;简称ES&#xff09; Elasticsearch是用Java开发并且是当前最流行的开源的企业级搜索引擎。能够达到近实时搜索&#xff0c;稳定&#xff0c;可靠&#xff0c;快速&#xff0c;安装使用方便。客户端支持Java、.NET&#x…

Class 00 - 学习编程的方法不同职业所使用的编程语言

Class 00 - 学习编程的方法&不同职业所使用的编程语言 学习编程的方法什么是编程&#xff1f;不同职业所使用的编程语言数据分析网页设计移动应用开发Web应用开发游戏开发 Tips&#xff1a;学习编程语言的技巧 从电子表格到 SQL 再到 R电子表格、SQL和R:一个比较 学习编程的…

根据端口查询该程序占用的内存 gpu

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 系列文章目录前言一、如何根据端口号查询该程序的占用内存…

JavaScript语法基础

js学习路线 数据判度 1&#xff0c;类型分类undefined,Null,Number,String,Boolean 2,类型判断typeof操作符 var sTemp “tesst” 例如alert(typeos sTemp); //输出String alert(typeof 23);//输出number 3&#xff0c;instanceof操作符&#xff1a;用于判断一个引用类型属于…

【C++】C++中的继承

目录 一.继承的概念和定义1.继承的概念2.继承定义2.1定义格式2.2继承关系和访问限定符2.3继承基类成员访问方式的变化 二.基类和派生类对象赋值转换三.继承中的作用域四.派生类的默认成员函数五.继承和友元六.继承与静态成员七.复杂的菱形继承及菱形虚拟继承1.单继承2.多继承3.…

React 中 TypeScript 和装饰器及 Hooks

概念 TypeScript 是强类型语言&#xff0c;相对于JavaScript 弱类型语言&#xff0c;它具有类型检测的功能&#xff0c;扩展了JavaScript 的语法。 TS的安装与执行&#xff1a; //全局安装typescript npm install typescript -g// 第二个因为 本来的node是不可能支持 ts那种民…

2023网络安全学习路线 非常详细 推荐学习

前言&#xff1a;首先咱们聊聊&#xff0c;学习网络安全方向通常会有哪些问题 目录&#xff1a; 1、打基础时间太长 学基础花费很长时间&#xff0c;光语言都有几门&#xff0c;有些人会倒在学习 linux 系统及命令的路上&#xff0c;更多的人会倒在学习语言上&#xff1b; …

SSD系列1——网络结构

SSD系列&#xff1a; SSD系列1——网络结构 SSD系列2——PriorBox SSD系列3——损失计算 SSD网络结构概述 SSD在VGGNet的基础上&#xff0c;增加了4个卷积模块&#xff0c;这些卷积模块获得的特征图具有不同的感受野&#xff0c;可以较好地检测不同尺度的目标。 VGG16 SSD网络…

springboot 断点上传、续传、秒传实现

文章目录 前言一、实现思路二、数据库表对象二、业务入参对象三、本地上传实现三、minio上传实现总结 前言 springboot 断点上传、续传、秒传实现。 保存方式提供本地上传&#xff08;单机&#xff09;和minio上传&#xff08;可集群&#xff09; 本文主要是后端实现方案&…

AI绘画:Lora模型训练完整流程!

关于AI绘画(基于Stable Diffusion Webui)&#xff0c;我之前已经写过三篇文章&#xff0c;分别是 软件安装&#xff0c;基本的使用方法&#xff0c;微调模型LoRA的使用。 整体来说还是比简单的&#xff0c;搞个别人的模型&#xff0c;搞个提示词就出图了。今天来一个有些难度…

推荐11个好用的prompt工具网站(附链接+论文)

同学们&#xff0c;你们prompt是自己苦哈哈码的吗&#xff1f;可别了&#xff0c;有现成的工具为啥不用&#xff1f; 今天我就和大家分享一些好用的prompt工具网站&#xff0c;用熟了ChatGPT、midjourney、stable diffusion能玩起来更爽&#xff01;搜罗了有十几个&#xff0c…

智能汽车实验二(视觉传感器标定)

实验二 视觉传感器标定&#xff08;实验报告&#xff09; 【实验目的】 1、了解开源图像处理库OpenCV的结构&#xff0c;掌握OpenCV的基本使用方法。 2、了解开源图像处理库OpenCV的基本模块功能&#xff0c;掌握常用图像处理方法。 3、掌握摄像机标定算法&#xff0c;学会使用…

Xilinx 7系列FPGA内置ADC

Xilinx 7系列FPGA全系内置了一个ADC&#xff0c;称之为XADC。这个XADC&#xff0c;内部是两个1mbps的ADC&#xff0c;可以采集模拟信号转为数字信号送给FPGA内部使用。 XADC内部可以直接获取芯片结温和FPGA的若干供电电压&#xff08;7系列不包括VCCO&#xff09;&#xff0c;用…