mybatis模拟04

news2024/11/15 8:59:47

create SqlSession Class

package com.wsd.core;

/**
 * @description: 执行sql
 * @author: Mr.Wang
 * @create: 2023-06-24 16:55
 **/
public class SqlSession {
}

SqlSessionFactory 中创建 openSqlSession method to get a sql session instance

 /**
     * @description Get sql session instance
     * @param null        
     * @return 
     */
    public SqlSession openSqlSession(){
        return null;
    }
package com.wsd.core;

import java.util.Map;

/**
 * @program: spring_learn
 * @description:
 * @author: Mr.Wang
 * @create: 2023-06-22 21:39
 **/
public class SqlSessionFactory {


    /**
     * @description 事务管理器 transactionManager
     * 根据配置的不同而使用不同的实现类
     */
    private Transaction transaction;

    /**
     * @description
     * map 的 key 为 sql标签的 id , value 为MappedStatement 对象
     * The key of the map is the id of the SQL tag, and the value is the MappedStatement object
     */
    private Map<String,MappedStatement> mappedStatementMap;

    public SqlSessionFactory(Transaction transaction, Map<String, MappedStatement> mappedStatementMap) {
        this.transaction = transaction;
        this.mappedStatementMap = mappedStatementMap;
    }

    /**
     * @description Get sql session instance
     * @param null
     * @return
     */
    public SqlSession openSqlSession(){
        return null;
    }
}

SqlSessionFactory 中创建 openSqlSession method to get a sql session instance

获取 sql session instance,需要先有一个connection

 /**
     * @description Get sql session instance
     * @param null
     * @return
     */
    public SqlSession openSqlSession(){
        //创建connection
        this.transaction.openConnection();

        return null;
    }

 //创建SqlSession instance,将 this 作为参数传给SqlSession instance ,sqlSession 就可以使用 SqlSessionFactory 的属性

SqlSession sqlSession = new SqlSession(this);

 /**
     * @description Get sql session instance
     * @param null
     * @return
     */
    public SqlSession openSqlSession(){
        //创建connection
        this.transaction.openConnection();

        //创建SqlSession instance
        SqlSession sqlSession = new SqlSession(this);

        return sqlSession;
    }

 SqlSession 添加属性和构造方法

package com.wsd.core;

/**
 * @description: 执行sql
 * @author: Mr.Wang
 * @create: 2023-06-24 16:55
 **/
public class SqlSession {
    
    private SqlSessionFactory sqlSessionFactory;

    public SqlSession(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }
}

 添加 insert 方法,执行 insert sql语句

/**
 * @description 执行 inert ,向数据库表中插入数据
 * @param sqlId:sql 语句的 id
 * @param data:所需要的数据
 * @return 成功插入的记录数量
 */
public int insert(String sqlId, Object data){
    return 0;
}
package com.wsd.core;

/**
 * @description: 执行sql
 * @author: Mr.Wang
 * @create: 2023-06-24 16:55
 **/
public class SqlSession {

    private SqlSessionFactory sqlSessionFactory;

    public SqlSession(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }

    /**
     * @description 执行 inert ,向数据库表中插入数据
     * @param sqlId:sql 语句的 id
     * @param data:所需要的数据
     * @return 成功插入的记录数量
     */
    public int insert(String sqlId, Object data){
        return 0;
    }
}

SqlSessionFactory 添加获取 属性的get方法
public Transaction getTransaction() {
    return transaction;
}

public Map<String, MappedStatement> getMappedStatementMap() {
    return mappedStatementMap;
}
package com.wsd.core;

import java.util.Map;

/**
 * @program: spring_learn
 * @description:
 * @author: Mr.Wang
 * @create: 2023-06-22 21:39
 **/
public class SqlSessionFactory {


    /**
     * @description 事务管理器 transactionManager
     * 根据配置的不同而使用不同的实现类
     */
    private Transaction transaction;

    /**
     * @description
     * map 的 key 为 sql标签的 id , value 为MappedStatement 对象
     * The key of the map is the id of the SQL tag, and the value is the MappedStatement object
     */
    private Map<String,MappedStatement> mappedStatementMap;

    public SqlSessionFactory(Transaction transaction, Map<String, MappedStatement> mappedStatementMap) {
        this.transaction = transaction;
        this.mappedStatementMap = mappedStatementMap;
    }

    /**
     * @description Get sql session instance
     * @param null
     * @return
     */
    public SqlSession openSqlSession(){
        //创建connection
        this.transaction.openConnection();

        //创建SqlSession instance
        SqlSession sqlSession = new SqlSession(this);

        return sqlSession;
    }

    public Transaction getTransaction() {
        return transaction;
    }

    public Map<String, MappedStatement> getMappedStatementMap() {
        return mappedStatementMap;
    }
}

SqlSession 添加以下方法
/**
 * @description commit transaction
 * @param null        
 * @return 
 */
public void commit(){
    this.sqlSessionFactory.getTransaction().commit();
}

/**
 * @description rollback transaction 
 * @param null        
 * @return 
 */
public void rollback(){
    this.sqlSessionFactory.getTransaction().rollback();
}

/**
 * @description close connection
 * @param null        
 * @return 
 */
public void close(){
    this.sqlSessionFactory.getTransaction().close();
}
package com.wsd.core;

/**
 * @description: 执行sql
 * @author: Mr.Wang
 * @create: 2023-06-24 16:55
 **/
public class SqlSession {

    private SqlSessionFactory sqlSessionFactory;

    public SqlSession(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }

    /**
     * @description 执行 inert ,向数据库表中插入数据
     * @param sqlId:sql 语句的 id
     * @param data:所需要的数据
     * @return 成功插入的记录数量
     */
    public int insert(String sqlId, Object data){
        return 0;
    }

    /**
     * @description commit transaction
     * @param null
     * @return
     */
    public void commit(){
        this.sqlSessionFactory.getTransaction().commit();
    }

    /**
     * @description rollback transaction
     * @param null
     * @return
     */
    public void rollback(){
        this.sqlSessionFactory.getTransaction().rollback();
    }

    /**
     * @description close connection
     * @param null
     * @return
     */
    public void close(){
        this.sqlSessionFactory.getTransaction().close();
    }
}

 实现 insert method of  SqlSession 

/**
 * @description 执行 inert ,向数据库表中插入数据
 * @param sqlId:sql 语句的 id
 * @param data:所需要的数据
 * @return 成功插入的记录数量
 */
public int insert(String sqlId, Object data){
    
    try {
        //Get connection
        Connection connection = this.sqlSessionFactory.getTransaction().getConnection();
        String sql = this.sqlSessionFactory.getMappedStatementMap().get(sqlId).getSql();

        //将 #{} 替换为 ?,"#\\{[0-9A-Za-z_$]*}" 是匹配 #{} 的正则表达式
        String preSql = sql.replaceAll("#\\{[0-9A-Za-z_$]*}", "?");
        PreparedStatement preparedStatement = connection.prepareStatement(preSql);
        //给 ?占位符传递参数
        

    } catch (SQLException e) {
        e.printStackTrace();
    }
    return 0;
}

给 ?占位符传递参数 如何实现?

尝试获取 #{value} 中的 value
public static void main(String[] args) {
    String sql = "insert into t_car (id,car_num,brand,guide_price,produce_time,car_type) values (null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})";
    // 按 #{ 分割 
    String[] sqlArray = sql.split("#\\{");
    //分割后sqlArray[0]没有需要的内容,需要的内容再 #{ 之后,所以 从 sqlArray[0] 开始
    for(int i = 1; i < sqlArray.length; i++){
        //找到 } 的位置
        int index = sqlArray[i].indexOf("}");
        // } 之前的内容就是目标
        String value = sqlArray[i].substring(0,index);
        System.out.println(value);
    }
}

 继续实现 insert 方法,给 ?占位符传递参数

/**
 * @description 执行 inert ,向数据库表中插入数据
 * @param sqlId:sql 语句的 id
 * @param data:所需要的数据
 * @return 成功插入的记录数量
 */
public int insert(String sqlId, Object data){

    int count = 0;
    
    try {
        //Get connection
        Connection connection = this.sqlSessionFactory.getTransaction().getConnection();
        String sql = this.sqlSessionFactory.getMappedStatementMap().get(sqlId).getSql();

        //将 #{} 替换为 ?,"#\\{[0-9A-Za-z_$]*}" 是匹配 #{} 的正则表达式
        String preSql = sql.replaceAll("#\\{[0-9A-Za-z_$]*}", "?");
        PreparedStatement preparedStatement = connection.prepareStatement(preSql);

        //获取 #{value} 中的 value
        String[] sqlArray = sql.split("#\\{");
        for(int i = 1; i < sqlArray.length; i++){
            int index = sqlArray[i].indexOf("}");
            String value = sqlArray[i].substring(0,index);
            //给 ?占位符传递参数
            //通过 get 方法 获取对应的属性值
            //获取get 方法的 method name
            String methodName = "get" + value.toUpperCase().charAt(0) + value.substring(1);
            //获取 getter method 
            Method getterdMethod = data.getClass().getDeclaredMethod(methodName);
            //调用 getter method 获取 属性值
            Object propertyValue =  getterdMethod.invoke(data);
            //给 ?占位符传值
            preparedStatement.setString(i,propertyValue.toString());
        }
        //执行 sql
        count = preparedStatement.executeUpdate();

    } catch (Exception e) {
        e.printStackTrace();
    }

    return count;

}
package com.wsd.core;

import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;

/**
 * @description: 执行sql
 * @author: Mr.Wang
 * @create: 2023-06-24 16:55
 **/
public class SqlSession {

    private SqlSessionFactory sqlSessionFactory;

    public SqlSession(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }

    

    /**
     * @description 执行 inert ,向数据库表中插入数据
     * @param sqlId:sql 语句的 id
     * @param data:所需要的数据
     * @return 成功插入的记录数量
     */
    public int insert(String sqlId, Object data){

        int count = 0;
        
        try {
            //Get connection
            Connection connection = this.sqlSessionFactory.getTransaction().getConnection();
            String sql = this.sqlSessionFactory.getMappedStatementMap().get(sqlId).getSql();

            //将 #{} 替换为 ?,"#\\{[0-9A-Za-z_$]*}" 是匹配 #{} 的正则表达式
            String preSql = sql.replaceAll("#\\{[0-9A-Za-z_$]*}", "?");
            PreparedStatement preparedStatement = connection.prepareStatement(preSql);

            //获取 #{value} 中的 value
            String[] sqlArray = sql.split("#\\{");
            for(int i = 1; i < sqlArray.length; i++){
                int index = sqlArray[i].indexOf("}");
                String value = sqlArray[i].substring(0,index);
                //给 ?占位符传递参数
                //通过 get 方法 获取对应的属性值
                //获取get 方法的 method name
                String methodName = "get" + value.toUpperCase().charAt(0) + value.substring(1);
                //获取 getter method 
                Method getterdMethod = data.getClass().getDeclaredMethod(methodName);
                //调用 getter method 获取 属性值
                Object propertyValue =  getterdMethod.invoke(data);
                //给 ?占位符传值
                preparedStatement.setString(i,propertyValue.toString());
            }
            //执行 sql
            count = preparedStatement.executeUpdate();

        } catch (Exception e) {
            e.printStackTrace();
        }

        return count;

    }



    /**
     * @description commit transaction
     * @param null
     * @return
     */
    public void commit(){
        this.sqlSessionFactory.getTransaction().commit();
    }

    /**
     * @description rollback transaction
     * @param null
     * @return
     */
    public void rollback(){
        this.sqlSessionFactory.getTransaction().rollback();
    }

    /**
     * @description close connection
     * @param null
     * @return
     */
    public void close(){
        this.sqlSessionFactory.getTransaction().close();
    }
}

 test insert method  

package com.wsd.core;

import com.wsd.core.util.Resources;
import com.wsd.pojo.Car;
import org.junit.Test;

/**
 * @description: test
 * @author: Mr.Wang
 * @create: 2023-06-24 15:40
 **/
public class TestMyBatis {

    @Test
    public void testInsert(){

        try {
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourcesAsStream("mybatis-config.xml"));
            SqlSession sqlSession = sqlSessionFactory.openSqlSession();
            Car car = new Car();
            car.setBrand("轮回");
            car.setCarType("新能源");
            sqlSession.insert("car.insertCar",car);
            sqlSession.commit();
            sqlSession.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

 CarMapper.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="car">
    <!--insert sql:保存一个汽车信息-->
    <insert id="insertCar">
        insert into t_car
            (id,brand,car_type)
        values
            (null,#{brand},#{carType})
    </insert>

    <delete id="deleteByCarNum">
        delete from t_car where car_num = #{carNum}
    </delete>

    <update id="updateCarById">
        update t_car set
            car_num = #{carNum},
            brand = #{brand},
            guide_price = #{guidePrice},
            produce_time = #{produceTime},
            car_type = #{carType}
        where id = #{id}
    </update>

    <select id="selectCarById" resultType="com.wsd.pojo.Car">
        select id,car_num as carNum,brand,guide_price as guidePrice,produce_time as produceTime,car_type as carType
        from t_car
        where id = #{id}
    </select>

    <!--虽然结果是List集合,但是resultType属性需要指定的是List集合中元素的类型。-->
    <select id="selectCarAll" resultType="com.wsd.pojo.Car">
        <!--记得使用as起别名,让查询结果的字段名和java类的属性名对应上。-->
        select
        id, car_num as carNum, brand, guide_price as guidePrice, produce_time as produceTime, car_type as carType
        from
        t_car
    </select>
</mapper>

Car Class

package com.wsd.core;

import com.wsd.core.util.Resources;
import com.wsd.pojo.Car;
import org.junit.Test;

/**
 * @description: test
 * @author: Mr.Wang
 * @create: 2023-06-24 15:40
 **/
public class TestMyBatis {

    @Test
    public void testInsert(){

        try {
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourcesAsStream("mybatis-config.xml"));
            SqlSession sqlSession = sqlSessionFactory.openSqlSession();
            Car car = new Car();
            car.setBrand("蓝雨");
            car.setCarType("新能源");
            sqlSession.insert("car.insertCar",car);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

修改:

创建connection and 开启 事务

this.connection.setAutoCommit(this.autoCommit);

public void openConnection() {
    if(this.connection == null){
        try {
            this.connection = this.dataSource.getConnection();
            //开启 事务
            this.connection.setAutoCommit(this.autoCommit);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

package com.wsd.core;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

/**
 * @description: Jdbc Transaction
 * @author: Mr.Wang
 * @create: 2023-06-23 09:49
 **/
public class JdbcTransaction implements Transaction {

    private DataSource dataSource;

    private Connection connection;

    //true:自动提交
    private Boolean autoCommit;

    @Override
    public void commit() {
        try {
            this.connection.commit();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void rollback() {
        try {
            this.connection.rollback();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void close() {
        try {
            this.connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public JdbcTransaction(DataSource dataSource, Boolean autoCommit) {
        this.dataSource = dataSource;
        this.autoCommit = autoCommit;
    }

    /**
     * @description
     * 获取连接对象,为connection属性赋值,避免重复获取(commit,rollback 等操作需要使用同一个 connection)
     * @return void
     */
    @Override
    public void openConnection() {
        if(this.connection == null){
            try {
                this.connection = this.dataSource.getConnection();
                //开启 事务
                this.connection.setAutoCommit(this.autoCommit);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public Connection getConnection() {
        return this.connection;
    }
}

test result :

 修改

输出返回值(插入成功的记录数量)

int count = sqlSession.insert("car.insertCar",car);

System.out.println(count);

@Test
public void testInsert(){

    try {
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourcesAsStream("mybatis-config.xml"));
        SqlSession sqlSession = sqlSessionFactory.openSqlSession();
        Car car = new Car();
        car.setBrand("兴欣");
        car.setCarType("新能源");
        int count = sqlSession.insert("car.insertCar",car);
        System.out.println(count);
        sqlSession.commit();
        sqlSession.close();
    } catch (Exception e) {
        e.printStackTrace();
    }

}
package com.wsd.core;

import com.wsd.core.util.Resources;
import com.wsd.pojo.Car;
import org.junit.Test;

/**
 * @description: test
 * @author: Mr.Wang
 * @create: 2023-06-24 15:40
 **/
public class TestMyBatis {

    @Test
    public void testInsert(){

        try {
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourcesAsStream("mybatis-config.xml"));
            SqlSession sqlSession = sqlSessionFactory.openSqlSession();
            Car car = new Car();
            car.setBrand("兴欣");
            car.setCarType("新能源");
            int count = sqlSession.insert("car.insertCar",car);
            System.out.println(count);
            sqlSession.commit();
            sqlSession.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

 result :

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

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

相关文章

中国人民大学与加拿大女王大学金融硕士——在职读研让能力加速提升

不管你是初入职场的小白&#xff0c;还是久经沙场的元老&#xff0c;想要在职场有所作为&#xff0c;就不要忽略自我能力提升。决定一个人当前职场价值不是他拥有了什么&#xff0c;而是他将来能够创造什么。如果你只盯着工作&#xff0c;那么你的眼界和薪资将会被工作所决定&a…

LeetCode动态规划(一)之动规思想概述基础题目

文章目录 动态规划开撸——基础题目1. lc509 斐波那契数2. lc746 使用最小花费爬楼梯3. lc63 不同路径II4. lc343 整数拆分 动态规划 记住动归5部曲&#xff1a; 1.确定dp数组&#xff08;dp table&#xff09;以及下标的含义 2.确定递推公式 3.dp数组如何初始化 4.确定遍历…

MySQL——变量与游标

今天我们来一起学习MySQL中的变量&#xff08;系统变量与用户变量&#xff09;&#xff0c;以及什么是游标&#xff0c;游标如何使用&#xff1f; 1. 变量 在 MySQL 数据库的存储过程和函数中&#xff0c;可以使用变量来存储查询或计算的中间结果数据&#xff0c;或者输出最终…

2、动手学深度学习——线性神经网络:softmax回归的实现(从零实现+内置函数实现)

1、softmax回归 为了估计所有可能类别的条件概率&#xff0c;我们需要一个有多个输出的模型&#xff0c;每个类别对应一个输出。 为了解决线性模型的分类问题&#xff0c;我们需要和输出一样多的仿射函数&#xff08;affine function&#xff09;。 每个输出对应于它自己的仿射…

css基础知识八:如何实现两栏布局,右侧自适应?三栏布局中间自适应呢?

一、背景 在日常布局中&#xff0c;无论是两栏布局还是三栏布局&#xff0c;使用的频率都非常高 两栏布局 两栏布局实现效果就是将页面分割成左右宽度不等的两列&#xff0c;宽度较小的列设置为固定宽度&#xff0c;剩余宽度由另一列撑满&#xff0c; 比如 Ant Design 文档…

计算机网络 期末复习大总结 + 例题【全部复习】

计算机网络 期末复习大总结 例题 第 1 章 概 述TCP/IP 和 ARPANET端系统的通信方式互联网的核心部分 - 分组转发电路交换分组交换报文交换计算机网络的 性能指标 第二章 物理层信号 和 码元信道基带信号 和 调制常用的编码方式奈氏准则信噪比香农公式信道复用 第三章 数 据 链…

三阶魔方公式

1. 术语&#xff1a;上、下&#xff0c;左、右、前、后 2. 魔方实物图 上&#xff1a;黄色 下&#xff1a;白色 左&#xff1a;蓝色 右&#xff1a;绿色 前&#xff1a;红色 后&#xff1a;橙色 3. 转法 上加&#xff1a;上面顺时针转90 上减&#xff1a;下面逆时针转90 上2&…

Django项目之mysql数据库连接和表的创建

数据库连接 首先&#xff0c;确保我们已经生成了一个基本的Django项目文件&#xff0c;目录结构如下&#xff1a; 具体搭建流程参考链接&#xff1a;https://blog.csdn.net/David_house/article/details/131188889?spm1001.2014.3001.5502找到项目下的settings文件&#xff…

人工智能系统的业务架构

一、人工智能系统的业务架构&#xff1a;三大能力 二大业务方向 三大业务能力&#xff1a;交互能力、思考能力、服务能力两大应用方向&#xff1a;智能语音、机器视觉 ​ 首先在智能语音方面&#xff0c;人工智能三大业务能力对应的应用层面输出在交互能力里包括语音采集、语…

积分图估计法线方法

两种法线估计方法的比较 pcl::NormalEstimation和pcl::IntegralImageNormalEstimation是两种常见的法线估计方法&#xff0c;它们的区别主要在于计算法线的方式和适用场景。 pcl::NormalEstimation&#xff1a; 计算方式&#xff1a;基于K近邻搜索的方法&#xff0c;通过寻找点…

【后端面经-Java】HashMap详解

【后端面经-Java】HashMap详解 1. HashMap的家族定位2. HashMap的数据结构2.1 Hash表的基本概念2.2 Hash冲突2.3 HashMap数据结构 3. HashMap的重要变量3.1 常量3.2 变量3.3 辨析size、capacity、threshold 4. HashMap重要方法和源码解析4.1 构造方法4.2 resize方法4.3 hash方法…

机器学习之基于LDA的人脸识别

目录 LDA降维 思想 matlab代码 fisherface 思想 matlab代码 人脸识别 思想 matlab代码 LDA降维 思想 首先&#xff0c;代码通过使用dir函数获取指定路径下所有以".bmp"结尾的文件&#xff0c;并存储在变量pictures中。 然后&#xff0c;定义了一些参数&a…

SSMP整合案例(6) 业务service层逻辑编写

之前呢 我们就还是将数据层的结构搭好了 那么 接下来就是业务层 可能有些开发人员会存在一定的误区 将业务层和数据层的函数命名混为一谈 例如 我们有个 users 表 那么 我们要做一个登录功能 那么 业务层的接口毋庸置疑叫 login 接收两个参数 userName userPassword 然后 数据…

FAQ常见问题如何从本地转为全线上版?

随着互联网的发展&#xff0c;越来越多的企业开始将常见问题FAQ从本地转移到全线上版&#xff0c;以提高用户体验和减少企业成本。本文将从以下几个方面进行阐述&#xff0c;如何将FAQ从本地转为全线上版。 一、整理FAQ 首先&#xff0c;企业需要对已有的FAQ进行整理&#xf…

极致呈现系列之:Echarts平行坐标系的多维度分析

目录 平行坐标系简介平行坐标系的常用配置项Vue3中创建平行坐标系美化平行坐标系样式美化 平行坐标系简介 平行坐标系是一种将多个维度的数值以平行的直线绘制在坐标系上的可视化方式。通过绘制多条平行直线&#xff0c;并将数据点映射到这些直线上&#xff0c;我们可以直观地…

【小沐学Web】Node.js搭建HTTPS 服务器

文章目录 1、简介1.1 HTTPS协议1.2 Node.js中的HTTPS 2、生成自签名证书2.1 key文件2.2 csr文件2.3 crt文件 4、代码测试4.1 Node.js简介4.2 Node.js的http模块4.3 Node.js的Express模块4.4 Node.js的https模块4.5 Node.js的httpsexpress模块 结语 1、简介 1.1 HTTPS协议 HTTP…

QT6之多线程控制——互斥量和信号量

在程序中,通常竞争使用临界资源&#xff0c;但如果不加限制就很可能出现异常或未达到预期的结果。 临界资源一次仅允许被一个线程使用&#xff0c;它可以是一块内存、一个数据结构、一个文件或者任何其他具有排他性使用的东西。 这些必须互斥执行的代码段称为“临界区(Critical…

使用VmWare安装黑苹果系统

目录 1.介绍2.破解安装VMware3.unlocker解锁虚拟机3.1 关闭VMware相关的进程3.2 执行安装命令 4.VmWare创建虚拟机5. 下载并配置镜像以及虚拟机设置5.1 修改镜像5.2 修改虚拟机安装路径文件内容 6. 选择镜像启动虚拟机7.安装macOS系统7.1 开启此虚拟机7.2 选择语言->简体中文…

TEC半导体热电温控技术在复合相变材料储热性能测试中的应用

摘要&#xff1a;针对定形相变复合材料热性能测试中ASTM C1784动态热流计法和ASTM C518稳态热流计法的高精度可编程快速温度控制问题&#xff0c;本文提出了采用单独两路TEC半导体热电加热制冷模组作为执行机构的解决方案。解决方案中还配备了不同加热功率的TEC控制电源模块、高…

Netty 聊天室项目案例

1. 登入 在连接建立好之后&#xff0c;客户端发送登入&#xff0c;将登入消息封装为LoginRequestMessage这个类的对象&#xff0c; ctx.writeAndFlush(loginRequestMessage);&#xff09;使用ctx发送&#xff0c;注意入站处理器调用写相关方法&#xff0c;会触发出站处理器&am…