7.java程序员必知必会类库之数据库连接池

news2024/12/22 22:12:13

前言

在java中,“池”化的设计思想随处可见,池化的最终目的是为了对象复用,降低系统创建、销毁对象的成本,提升资源的可管理性
尤其是一些大对象,创建销毁比较消耗资源的对象,池化可以极大提高效率,减少系统响应时间,提高系统并发度
常见的有线程池,实例池(spring容器),连接池等。本节我们介绍连接池里面的数据库连接池。

1. 有无连接池管理图示

1.1 没有连接池管理的时候

没有数据库连接池管理的话,每次外部请求过来,请求到我们web层,dao层为每个请求都会创建连接,执行脚本,释放连接,其中dao层和数据库建立连接,底层都是TCP请求,每次都要三次握手,四次挥手。如下如所示:
在这里插入图片描述

1.2 交给连接池管理

在交给连接池管理连接后,dao层和数据库交互的时候,直接从连接池获取连接。不再自己手动创建销毁连接,如下图所示:
在这里插入图片描述

1.3 手动创建连接代码demo

1.3.1 pom坐标引入

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.15</version>
    <scope>runtime</scope>
</dependency>

1.3.2 测试demo

@Test
public void test() throws Exception{
    StopWatch stopWatch=new StopWatch();
    stopWatch.start();
    for (int i = 0; i < 10000; i++) {
        //步骤
        //1  获取数据库连接的URL mysql8 必须要给一个时区  serverTimezone=UTC
        String url="jdbc:mysql://xx.xx.xx.xx:3306/openplatform?serverTimezone=UTC";
        //2 获取数据库连接的用户名和密码
        String username="xxxlatformopr";
        String password="xxx";
        //3 加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        //4 获取数据库连接对象  DriverManager依据数据库的不同,管理JDBC驱动
        Connection connection= DriverManager.getConnection(url,username,password);
        //5 获取操作数据库的Statement对象
        Statement statement=connection.createStatement();
        //6向数据库发送sql
        String sql="select * from t_cust_info limit 1";
        //7 通过statement对象 发送查询请求 拿回结果集
        ResultSet resultSet = statement.executeQuery(sql);
        //8遍历结果集 做一系列操作
        while (resultSet.next()){
            Object id = resultSet.getObject("cust_id");
            //System.out.println(id);
            Object uname = resultSet.getObject("cust_name");
            //System.out.println(uname);
            Object idNo = resultSet.getObject("id_no");
            //System.out.println(idNo);
           // System.out.println("==============");
        }
        //关闭资源
        resultSet.close();
        statement.close();
        connection.close();
   }
    stopWatch.stop();
    double totalTimeSeconds = stopWatch.getTotalTimeSeconds();
    System.out.println(totalTimeSeconds);
    //5.644
}

1.4 性能分析

在上面的代码中,循环遍历了10000次,每次都会重新创建连接,查询,销毁链接。本地测试100次,平均每次耗时44.09秒中间甚至偶发的报错,tcp连接超过限制

2. C3p0

2.1 介绍

C3PO是一个开源的JDBC连接池,它能够自动维护和回收数据库连接使用C3PO,可以设置最大连接数、最小连接数、最大空闲时间等参数从而对连接进行有效控制。同时,C3PO还提供了丰富的监控功能,可以帮助我们追踪和排除数据库连接问题

2.2 使用

2.2.1 pom坐标引入

<dependency>
    <groupId>com.mchange</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.5.2</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.15</version>
    <scope>runtime</scope>
</dependency>

2.2.2 代码demo

2.2.2.1 连接工具类

public class C3p0Util {

    private static DataSource dataSource = null;

    static{
    	//与配置文件的配置名字 named-config需要保持一致
        dataSource = new ComboPooledDataSource("mysqlapp");
    }

    //从连接池中获取连接
    public static Connection getConnection(){
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();        }
        return null;
    }

    //释放连接回连接池
    public static void release(Connection conn, Statement stmt, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            rs = null;
        }
        if (stmt != null) {
            try {
                stmt.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            stmt = null;
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            conn = null;
        }
    }
}

2.2.2.2 c3p0-config.xml模板

放到项目resource下面


<c3p0-config>
    <named-config name="mysqlapp">
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://x.x.x.x:3306/openplatform</property>
        <property name="user">formopr</property>
        <property name="password">xxxxx</property>

        <!-- 进行数据库连接池管理的基本信息 -->
        <!-- 当数据库连接池中的连接数不够时,c3p0一次性向数据库服务器申请的连接数 -->
        <property name="acquireIncrement">5</property>
        <!-- c3p0数据库连接池中初始化时的连接数 -->
        <property name="initialPoolSize">10</property>
        <!-- c3p0数据库连接池维护的最少连接数 -->
        <property name="minPoolSize">10</property>
        <!-- c3p0数据库连接池维护的最多的连接数 -->
        <property name="maxPoolSize">200</property>
        <!-- c3p0数据库连接池最多维护的Statement的个数 -->
        <property name="maxStatements">50</property>
        <!-- 每个连接中可以最多使用的Statement的个数 -->
        <property name="maxStatementsPerConnection">2</property>

    </named-config>
</c3p0-config>

2.2.2.3 测试demo

@Test
public void testC3p0() throws Exception{
    StopWatch stopWatch=new StopWatch();
    stopWatch.start();
    for (int i = 0; i < 10000; i++) {
        //步骤
        //4 获取数据库连接对象  DriverManager依据数据库的不同,管理JDBC驱动
        Connection connection = C3p0Util.getConnection();
        //5 获取操作数据库的Statement对象
        Statement statement=connection.createStatement();
        //6向数据库发送sql
        String sql="select * from t_cust_info limit 1";
        //7 通过statement对象 发送查询请求 拿回结果集
        ResultSet resultSet = statement.executeQuery(sql);
        //8遍历结果集 做一系列操作
        while (resultSet.next()){
            Object id = resultSet.getObject("cust_id");
            //System.out.println(id);
            Object uname = resultSet.getObject("cust_name");
            //System.out.println(uname);
            Object idNo = resultSet.getObject("id_no");
            //System.out.println(idNo);
            // System.out.println("==============");
        }
        C3p0Util.release(connection,statement,resultSet);
    }
    stopWatch.stop();
    double totalTimeSeconds = stopWatch.getTotalTimeSeconds();
    System.out.println(totalTimeSeconds);
}

2.3 性能测试

上面的代码,本地测试100次,平均每次运行耗时:5.671s,可以看到相对自己手动创建链接,时间大幅减少

2.4 常用参数配置

<c3p0-config>   
    <default-config>   
    <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->   
    <property name="acquireIncrement">3</property>   
 
    <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->   
    <property name="acquireRetryAttempts">30</property>   
       
    <!--两次连接中间隔时间,单位毫秒。Default: 1000 -->   
    <property name="acquireRetryDelay">1000</property>   
       
    <!--连接关闭时默认将所有未提交的操作回滚。Default: false -->   
    <property name="autoCommitOnClose">false</property>   
       
    <!--c3p0将建一张名为Test的空表,并使用其自带的查询语句进行测试。如果定义了这个参数那么   
    属性preferredTestQuery将被忽略。你不能在这张Test表上进行任何操作,它将只供c3p0测试   
    使用。Default: null-->   
    <property name="automaticTestTable">Test</property>   
       
    <!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效   
    保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试   
    获取连接失败后该数据源将申明已断开并永久关闭。Default: false-->   
    <property name="breakAfterAcquireFailure">false</property>   
       
    <!--当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出   
    SQLException,如设为0则无限期等待。单位毫秒。Default: 0 -->   
    <property name="checkoutTimeout">100</property>   
       
    <!--通过实现ConnectionTester或QueryConnectionTester的类来测试连接。类名需制定全路径。   
    Default: com.mchange.v2.c3p0.impl.DefaultConnectionTester-->   
    <property name="connectionTesterClassName"></property>   
       
    <!--指定c3p0 libraries的路径,如果(通常都是这样)在本地即可获得那么无需设置,默认null即可   
    Default: null-->   
    <property name="factoryClassLocation">null</property>   
       
    <!--强烈不建议使用该方法,将这个设置为true可能会导致一些微妙而奇怪的bug-->   
    <property name="forceIgnoreUnresolvedTransactions">false</property>   
       
    <!--每60秒检查所有连接池中的空闲连接。Default: 0 -->   
    <property name="idleConnectionTestPeriod">60</property>   
       
    <!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->   
    <property name="initialPoolSize">3</property>   
       
    <!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->   
    <property name="maxIdleTime">60</property>   
       
    <!--连接池中保留的最大连接数。Default: 15 -->   
    <property name="maxPoolSize">15</property>   
       
    <!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements   
    属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。   
    如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0-->   
    <property name="maxStatements">100</property>   
       
    <!--maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。Default: 0 -->   
    <property name="maxStatementsPerConnection"></property>   
       
    <!--c3p0是异步操作的,缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能   
    通过多线程实现多个操作同时被执行。Default: 3-->   
    <property name="numHelperThreads">3</property>   
       
    <!--当用户调用getConnection()时使root用户成为去获取连接的用户。主要用于连接池连接非c3p0   
    的数据源时。Default: null-->   
    <property name="overrideDefaultUser">root</property>   
       
    <!--与overrideDefaultUser参数对应使用的一个参数。Default: null-->   
    <property name="overrideDefaultPassword">password</property>   
       
    <!--密码。Default: null-->   
    <property name="password"></property>   
       
    <!--定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个一显著提高测试速度。注意:   
    测试的表必须在初始数据源的时候就存在。Default: null-->   
    <property name="preferredTestQuery">select id from test where id=1</property>   
       
    <!--用户修改系统配置参数执行前最多等待300秒。Default: 300 -->   
    <property name="propertyCycle">300</property>   
       
    <!--因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的   
    时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable   
    等方法来提升连接测试的性能。Default: false -->   
    <property name="testConnectionOnCheckout">false</property>   
       
    <!--如果设为true那么在取得连接的同时将校验连接的有效性。Default: false -->   
    <property name="testConnectionOnCheckin">true</property>   
       
    <!--用户名。Default: null-->   
    <property name="user">root</property>   
       
    <!--早期的c3p0版本对JDBC接口采用动态反射代理。在早期版本用途广泛的情况下这个参数   
    允许用户恢复到动态反射代理以解决不稳定的故障。最新的非反射代理更快并且已经开始   
    广泛的被使用,所以这个参数未必有用。现在原先的动态反射与新的非反射代理同时受到   
    支持,但今后可能的版本可能不支持动态反射代理。Default: false-->   
    <property name="usesTraditionalReflectiveProxies">false</property> 
    </default-config>      
</c3p0-config>

3 DBCP

3.1 介绍

DBCP是Apache软件基金会下的一个开源项目,也是一个JDBC连接池。与 C3PO类似,DBCP 也能够自动维护和回收数据库连接。同时,DBCP还支持连接池配置文件的读取,这样就可以通过修改配置文件来改变连接池的参数

3.2 使用

3.2.1 pom坐标引入

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.15</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>commons-dbcp</groupId>
    <artifactId>commons-dbcp</artifactId>
    <version>1.4</version>
</dependency>
<dependency>
    <groupId>commons-pool</groupId>
    <artifactId>commons-pool</artifactId>
    <version>1.6</version>
</dependency>

3.2.2 代码demo

3.2.2.1 连接工具类

public class JDbcConfigReadUtil {
    private static DataSource dataSource = null;
    static {
        Properties props = new Properties();
        try {
            File file = new File("E:\\weixinData\\WeChat Files\\wxid_gv8xbkloz0wc22\\FileStorage\\File\\2023-03\\test\\src\\main\\resources\\dbcp\\jdbc.properties");//获取文件
            InputStream inputStream = new FileInputStream(file);//获取输入流
            props.load(inputStream);//props需要通过输入流读取一个.Properties文件
            dataSource = BasicDataSourceFactory.createDataSource(props);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //从连接池中获取连接
    public static Connection getConnection() {
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    //释放连接回连接池
    public static void release(Connection conn, Statement stmt, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            rs = null;
        }
        if (stmt != null) {
            try {
                stmt.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            stmt = null;
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            conn = null;
        }
    }
}

3.2.2.2 配置properties文件

driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://x.x.x.x:3306/openplatform
username=xx
password=xxx

3.2.2.3 测试demo

@Test
public void testDbcp() throws Exception{

    StopWatch stopWatch=new StopWatch();
    stopWatch.start();
    for (int i = 0; i < 10000; i++) {
        //4 获取数据库连接对象  DriverManager依据数据库的不同,管理JDBC驱动
        Connection connection = JDbcConfigReadUtil.getConnection();
        //5 获取操作数据库的Statement对象
        Statement statement=connection.createStatement();
        //6向数据库发送sql
        String sql="select * from t_cust_info limit 1";
        //7 通过statement对象 发送查询请求 拿回结果集
        ResultSet resultSet = statement.executeQuery(sql);
        //8遍历结果集 做一系列操作
        while (resultSet.next()){
            Object id = resultSet.getObject("cust_id");
            //System.out.println(id);
            Object uname = resultSet.getObject("cust_name");
            //System.out.println(uname);
            Object idNo = resultSet.getObject("id_no");
            //System.out.println(idNo);
            // System.out.println("==============");
        }
        C3p0Util.release(connection,statement,resultSet);
    }
    stopWatch.stop();
    double totalTimeSeconds = stopWatch.getTotalTimeSeconds();
    System.out.println(totalTimeSeconds);

}

3.3 性能测试

上面的代码,本地测试100次,平均每次运行耗时:5.191,可以看到相对自己手动创建链接,时间大幅减少

3.4 常用参数配置

<!--初始化连接:连接池启动时创建的初始化连接数量-->
initialSize=5
<!--maxActive: 最大连接数量-->    
maxActive=30
<!-- 连接在池中保持空闲而不被空闲连接回收器线程-->  
minEvictableIdleTimeMillis=1800000
<!--maxIdle: 最大空闲连接-->
maxIdle=5
<!--minIdle: 最小空闲连接--> 
minIdle=2
<!--maxWait: 超时等待时间以毫秒为单位 1000等于60-->
maxWait=1000
<!--对于事务是否 autoCommit-->
defaultAutoCommit=true
<!-- 在空闲连接回收器线程运行期间休眠的时间值,以毫秒为单位. --> 
timeBetweenEvictionRunsMillis=600000
 <!--  在每次空闲连接回收器线程(如果有)运行时检查的连接数量 -->
numTestsPerEvictionRun=3
<!--是否自动回收超时连接-->  
removeAbandoned=true
<!--超时时间(以秒数为单位)--> 
removeAbandonedTimeout=180
<!-- 连接被泄露时是否打印 -->
logAbandoned=true
<!--连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除.设置为true后如果要生效,validationQuery参数必须设置为非空字符串-->
testWhileIdle=true
validationQuery=select 1
<!--是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个.-->
testOnBorrow=true
<!--是否在归还到池中前进行检验-->
testOnReturn=false

4 Druid

4.1 介绍

Druid 是阿里巴巴开源的一个数据库连接池。Druid 具有数据源监控SQL监控、容器集成支持、数据源防火墙等特性,可以帮助我们更好地管理数据库连接。同时,Druid 还提供了很多性能优化功能,如预编译语句缓存、分布式ID生成器等

4.2 使用

4.2.1 pom坐标引入

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.16</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.15</version>
</dependency>

4.2.2 代码demo

4.2.2.1 连接工具类

public class DruidUtil {
    private static DataSource dataSource = null;
    static {
        Properties props = new Properties();
        try {
            File file = new File("E:\\weixinData\\WeChat Files\\wxid_gv8xbkloz0wc22\\FileStorage\\File\\2023-03\\test\\src\\main\\resources\\druid\\druid.properties");//获取文件
            InputStream inputStream = new FileInputStream(file);//获取输入流
            props.load(inputStream);//props需要通过输入流读取一个.Properties文件
            dataSource=DruidDataSourceFactory.createDataSource(props);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //从连接池中获取连接
    public static Connection getConnection() {
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    //释放连接回连接池
    public static void release(Connection conn, Statement stmt, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            rs = null;
        }
        if (stmt != null) {
            try {
                stmt.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            stmt = null;
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            conn = null;
        }
    }
}

4.2.2.2 配置文件

driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://x.x.x.x:3306/openplatform
username=xx
password=xxx

4.2.2.3 测试demo

@Test
public void testDruid() throws Exception{
    StopWatch stopWatch=new StopWatch();
    stopWatch.start();
    for (int i = 0; i < 10000; i++) {
        //4 获取数据库连接对象  DriverManager依据数据库的不同,管理JDBC驱动
        Connection connection = DruidUtil.getConnection();
        //5 获取操作数据库的Statement对象
        Statement statement=connection.createStatement();
        //6向数据库发送sql
        String sql="select * from t_cust_info limit 1";
        //7 通过statement对象 发送查询请求 拿回结果集
        ResultSet resultSet = statement.executeQuery(sql);
        //8遍历结果集 做一系列操作
        while (resultSet.next()){
            Object id = resultSet.getObject("cust_id");
            //System.out.println(id);
            Object uname = resultSet.getObject("cust_name");
            //System.out.println(uname);
            Object idNo = resultSet.getObject("id_no");
            //System.out.println(idNo);
            // System.out.println("==============");
        }
        C3p0Util.release(connection,statement,resultSet);
    }
    stopWatch.stop();
    double totalTimeSeconds = stopWatch.getTotalTimeSeconds();
    System.out.println(totalTimeSeconds);

}

4.3 性能测试

上面的代码,本地测试100次,平均每次运行耗时:5.58s,可以看到相对自己手动创建链接,时间大幅减少

4.4 常用参数配置

druid github 属性介绍

5. 注意事项:

  1. 上面演示代码连接池都是项目启动的时候,自己在工具类维护的,真实生产环境中,一般都是交给spring管理的
  2. 上面几个测试案例的时间响应,测试场景不完善,只是能直观上比对出来,使用连接池会比手动连接效率高很多,但是几个连接池的响应时间比较,不具有参考意义
  3. 关于数据库连接池配置参数多少合理,这是老生常谈的问题,与具体环境使用相关性很大,客户的并发量等都强相关,没有一套参数放到四海皆准的道理
  4. 如果点到具体的配置类源码里,可以看到其实jar包做的都是从配置文件读固定属性,来组装一个连接池配置类,这个连接池配置类有很多默认属性。
  5. 所以如果哪个属性失效了,需要第一时间看是不是配置的参数没有生效。举一反三,也可以想到,连接池的配置方式可以有xml格式,propertis格式等各种自定义格式,只要保证配置文件正常读取,读取的参数值正常封装就行
  6. 如果和springboot结合,可以看看有没有对应的自动装配类,将连接池的参数配置交给springboot自己装配
  7. 关于几个连接池,公司应该选择哪一个连接池?主要要看具体的业务场景和性能要求。如果需要丰富的管理和监控功能,可以选择 Druid 这样的连接池。如果需要简单易用,可以选择C3PO或DBCP 这样的常规连接池。笔者公司选择的是Druid连接池。

参考文献:
C3p0使用详解

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

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

相关文章

EMQX vs Mosquitto | 2023 MQTT Broker 对比

引言 物联网开发者需要为自己的物联网项目选择合适的 MQTT 消息产品或服务&#xff0c;从而构建可靠高效的基础数据层&#xff0c;保障上层物联网业务。目前市面上有很多开源的 MQTT 产品&#xff0c;在性能功能等方面各有优点。本文将选取目前最为流行的两个开源 MQTT Broker…

最新!芯片行业有哪些知名企业?

01、芯片设计 芯片设计是产业链中重要的一环&#xff0c;影响后续芯片产品的功能、性能和成本&#xff0c;对研发实力要求较高。根据不同的下游应用&#xff0c;可分为四类&#xff1a; &#xff08;一&#xff09;集成电路&#xff1a;存储器、逻辑芯片&#xff08;CPU、GPU&…

进击的 Java !

编者按&#xff1a;近几年&#xff0c;随着云原生时代的到来&#xff0c;Java 遭受了诸多质疑。国际形势和行业格局的变化&#xff0c;大家一定充分感受到了云原生这个话题的热度&#xff0c;难道 Java 真的已过巅峰时期&#xff0c;要走向末路了吗&#xff1f;龙蜥社区 Java 语…

【Auto-GPT】会自主完成任务的 AI!安整的安装&使用教学

ChatGPT 需要我们不停的输入指令,引导 AI 的回答方向才能得到期待的结果;而 Auto-GPT 之所以爆红,就是因为他能够“自我反思”,只要给他任务,他就会不停地自问自答,不需要人为插手。 听起来是不是棒呆了?就让笔者透过这篇文章带大家了解如何安装 Auto-GPT,以及如何使用…

深入 Pinia:从代码出发探索 Vue 状态管理的奥秘

目录 一、 &#x1f3de;️创建源码分析环境1. 创建一个 vue 项目2. Pinia 源码入口3. 复制 Pinia 源码 & 在 main.ts 中初始化 Pinia 插件4. 添加必要仓库依赖5. 添加必要环境变量6. 环境测试 二、&#x1f9d0;源码分析&#xff08;1&#xff09;——执行流程三、&#x…

图像修复(Image Restoration)前沿

背景与现状 图像修复是一个长期存在的低层次视觉问题&#xff0c;旨在从损坏的输入图像中获取高质量图像&#xff0c;例如去模糊、去噪、去雾、去雨以及超分辨等。 L D ( H ) γ \mathbf{L} \mathbf{D}(\mathbf{H}) \gamma LD(H)γ 其中&#xff0c;L是低质量图像&#x…

电脑突然变成绿屏错误代码无法使用怎么办?

电脑突然变成绿屏错误代码无法使用怎么办&#xff1f;有用户使用电脑的时候&#xff0c;电脑桌面变成了绿屏的显示&#xff0c;所有的操作无法继续进行。遇到这个问题要怎么去进行解决呢&#xff1f;来看看详细的解决方法教学吧。 准备工作&#xff1a; 1、U盘一个&#xff08;…

Unity打包google play最新要求的aab文件的方法

很久不搞打包了&#xff0c;没想到google又整出新的花活了&#xff0c;apk变成了aab&#xff0c;这里分享一下。 首先有几个网址很重要&#xff0c;这里说一下&#xff1a; GitHub - google/play-unity-plugins: The Google Play Plugins for Unity provide C# APIs for acce…

第八届中国航天日 数字文创助推航天新国潮

2023年&#xff0c;正值中国空间站应用与发展新阶段开局之年&#xff0c;距离地球400公里外的天宫见证我国载人航天工程“三步走”发展战略从构想成为现实&#xff0c;中国空间站常态化运行之旅正式起航。 回首半个世纪前的酒泉戈壁&#xff0c;中国首枚运载火箭托举东方红一号…

MyBatisPlus代码生成器使用

MybatisPlus特点 无侵入&#xff1a;只做增强不做改变&#xff0c;引入它不会对现有工程产生影响&#xff0c;如丝般顺滑 损耗小&#xff1a;启动即会自动注入基本 CURD&#xff0c;性能基本无损耗&#xff0c;直接面向对象操作 强大的 CRUD 操作&#xff1a;内置通用 Mappe…

使用FME 批量OSGB转FBX(OBJ) (亲测)

首先感谢这个UP主&#xff1a;OSGB单体模型批量转FBX&#xff0c;并保留原有文件目录_哔哩哔哩_bilibili 吐槽&#xff1a;刚开始使用了OpenSceneGraph 去转换&#xff0c;发现贴图有黑斑。而且没有找到批量转换的方法。于是花费几个小时时间去查阅相关资料&#xff0c;最后确定…

“上海升级”后 以太坊抛压为何没来?

关联加密资产市场的Web3重新进入市场上升期&#xff0c;而被普遍视作Web3主流基建的以太坊区块链也在近日经历了一场重要升级。 此次升级被命名为“上海升级”&#xff0c;源于社区期望以太坊能够如上海一般多元化地发展和繁荣。上海升级带来的最大改变是&#xff0c;验证者可…

操作指南|如何在Moonriver上使用Polkassembly参与OpenGov

Polkassembly是一个开源平台&#xff0c;任何人都可以探索并参与Moonbeam的链上治理。Polkassembly完全支持OpenGov&#xff08;也称为Gov2&#xff09;。OpenGov目前在Moonriver上运行&#xff0c;并很快就会在Moonbeam上运行。 Polkassembly让参与治理变得容易。您可以打开讨…

一次「找回」TraceId的问题分析与过程思考

用好中间件是每一个开发人员的基本功&#xff0c;一个专业的开发人员&#xff0c;追求的不仅是中间件的日常使用&#xff0c;还要探究这背后的设计初衷和底层逻辑&#xff0c;进而保证我们的系统运行更加稳定&#xff0c;让开发工作更加高效。 结合这一主题&#xff0c;本文从一…

掌握这些移动测试技巧,棘手的问题也能游刃有余解决了

目录&#xff1a;导读 引言 一、测试的程序 二、功能测试点 三、移动端安卓环境变量 性能测试 四、实操通过USB连接到手机设备 五、adb操作命令 写在最后 引言 你是否曾经遇到过打开一个移动应用后出现各种问题&#xff0c;比如卡顿、闪退等&#xff1f; 这些问题可能会…

【HDCTF2023】wp

【HDCTF2023】wp 文章目录 【HDCTF2023】wpwebWelcome To HDCTF 2023SearchMasterYamiYamiLoginMaster mischardMiscMasterMiscExtremeMiscSuperMisc web Welcome To HDCTF 2023 在源码的 game.js中找到了flag 在控制台输出 console.log(seeeeeeeecret)得flag SearchMaster …

一文解析:低代码开发平台和零代码平台有什么区别?以及如何选?

随着数字化转型的加速&#xff0c;企业和组织对于快速开发和部署应用程序的需求也越来越迫切。 为了满足这一需求&#xff0c;低代码和零代码平台应运而生。这两种平台都提供了快速构建应用程序的方法&#xff0c;但它们之间的区别是什么呢&#xff1f;本篇就来为大家解答一下…

Linux常用命令(二)

目录 VI/VIM编辑器 Linux的root用户 用户和用户组管理 getent命令 查看权限控制信息 修改权限控制 chmod 修改权限控制 chown VI/VIM编辑器 vim是vi的加强版&#xff0c;兼容vi的所有指令。可编辑文本、shell程序&#xff0c;能以不同颜色字体来辨别语法正确性。3种工作…

软件研发的项目经理都在用哪些好的设计和管理的软件工具?

软件研发是一个复杂而又有趣的过程&#xff0c;它涉及到多个阶段&#xff0c;如需求分析、设计、编码、测试、部署、维护等。在这个过程中&#xff0c;我们需要使用各种工具来帮助我们提高效率、保证质量、协作沟通、解决问题等。工具化是指将一些重复性或者困难的任务封装成可…

Python-pyppeteer解决微软Microsoft的登录机器人验证(8)

前言 本文是该专栏的第8篇,结合优质项目案例,让你精通使用Pyppeteer,后面会持续分享Pyppeteer的干货知识,记得关注。 在注册微软Microsoft账号或者注册outlook邮箱账号的时候,会遇到如下机器人验证: 是的,你可能第一眼看到这个验证页面,首先会想到是定位它的页面元素N…