Day 14 JDBC

JDBC

  • 1、简单入门 Statement
  • 2、preparedStatement
  • 3、主键回显
  • 4、批量操作
  • 5、事务
  • 6、Druid
    • 6.1 工具类V1
    • 6.2 工具类V2
    • 6.3

在这里插入图片描述

1、简单入门 Statement

步骤:
1、注册驱动
2、创建连接
3、创建 Statement对象
4、编写sql语句 并且发送sql语句获得结果集
5、解析结果集
6、释放资源
注意事项 都在写下面代码里了

import com.mysql.cj.jdbc.Driver;

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

public class day1 {
    public static void main(String[] args) throws Exception {
        new test();
        new test();
        //注册驱动  不推荐 会注册两次 new Driver中有静态代码块
        //DriverManager.registerDriver(new Driver());
        //new Driver();//不推荐 不能显示出 是什么驱动 如果是8+ 则是com.mysql.cj.jdbc 如果是5+ 则是com.mysql.jdbc
        Class.forName("com.mysql.cj.jdbc.Driver");  //推荐 通过反射获得类加载
        //建立连接 3种方式 ①
//        Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "ckytest", "123456");
        // ②
        Properties properties=new Properties();
        properties.put("user","ckytest");
        properties.put("password","123456");
//        Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test",properties);
        //③
        Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?user=ckytest&password=123456");
        //创建 mql
        Statement statement = ckytest.createStatement();
        //mql 并发送 获取结果集
        String mysql="select * from u_ser";
        //  statement.executeUpdate();  非DML


        ResultSet resultSet = statement.executeQuery(mysql);
        while(resultSet.next()){
            int anInt = resultSet.getInt(1);
//            int id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            System.out.println(anInt+"---"+name);
        }
    }
}

2、preparedStatement

步骤:
1、注册驱动
2、创建连接
3、编写sql语句
4、创建preparedStatement 对象并且传入sql语句
5、占位符赋值
从左到右 索引从1开始
6、发送sql语句获得结果集
7、解析结果集
8、释放资源

import com.mysql.cj.jdbc.Driver;
import org.junit.Test;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class test {
    @Test
   public void testinsert() throws  Exception{
       Class.forName("com.mysql.cj.jdbc.Driver");
       Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "ckytest", "123456");
       String mysql="insert into u_ser(id,name) values(?,?);";
       PreparedStatement preparedStatement = ckytest.prepareStatement(mysql);
       preparedStatement.setObject(1,3);
       preparedStatement.setObject(2,"yue");
        int i = preparedStatement.executeUpdate();
        if (i>0)
           System.out.println("成功");
        preparedStatement.close();
        ckytest.close();
   }

    @Test
    public void testupdate() throws  Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "ckytest", "123456");
        String mysql="update u_ser set name=? where id=?;";
        PreparedStatement preparedStatement = ckytest.prepareStatement(mysql);
        preparedStatement.setObject(1,"cui");
        preparedStatement.setObject(2,3);
        int i = preparedStatement.executeUpdate();
        if (i>0)
            System.out.println("成功");
        preparedStatement.close();
        ckytest.close();
    }
    @Test
    public void testdelete() throws  Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "ckytest", "123456");
        String mysql="delete from u_ser where  id=?;";
        PreparedStatement preparedStatement = ckytest.prepareStatement(mysql);
        //preparedStatement.setObject(1,"cui");
        preparedStatement.setObject(1,3);
        int i = preparedStatement.executeUpdate();
        if (i>0)
            System.out.println("成功");
        preparedStatement.close();
        ckytest.close();
    }

    //查询u_ser表中所有的内容 并保存到 List<map>集合中 key-value
    @Test
    public void testquery() throws  Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "ckytest", "123456");
        String mysql="select * from u_ser;";
        PreparedStatement preparedStatement = ckytest.prepareStatement(mysql);
        ResultSet resultSet = preparedStatement.executeQuery();
        //得到表信息
        ResultSetMetaData metaData = resultSet.getMetaData();
        //得到列数量
        int columnCount = metaData.getColumnCount();
        List<Map> list=new ArrayList<>();
        while(resultSet.next()) {
            Map map = new HashMap();
            for (int i = 1; i <= columnCount; i++) {
                //获得结果
                Object object = resultSet.getObject(i);
                //获得列名
                String columnLabel = metaData.getColumnLabel(i);
                map.put(columnLabel, object);

            }
            list.add(map);
        }
        System.out.println(list);
        resultSet.close();
        preparedStatement.close();
        ckytest.close();
    }
}

String columnLabel = metaData.getColumnLabel(i);
getColumnLabel 有别名可以获得别名而getColumnName 不能获取别名。
getColumnCount 获取列的数量
getMetaData 获取列的信息

3、主键回显

  /**
     * 
     * 得到自增长的主键
     * 在创建prepareStatement,告知它拿回自增长的主键
     * getGeneratedKeys 得到一个自增长主键的结果 首先通过next 移动光标
     * 之后通过getxx 获取结果,插入一行 肯定只获取一个结果 所以是一行一列 索引为1 即使回显的主键
     */
    @Test
    public void testinsertkey() throws  Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "ckytest", "123456");
        String mysql="insert into u_ser(name) values(?);";
        PreparedStatement preparedStatement = ckytest.prepareStatement(mysql,Statement.RETURN_GENERATED_KEYS);
        preparedStatement.setObject(1,"yue1");
        int i = preparedStatement.executeUpdate();
        if (i>0)
            System.out.println("成功");
        ResultSet generatedKeys = preparedStatement.getGeneratedKeys();
        generatedKeys.next();
        Object id = generatedKeys.getObject(1);
        System.out.println("回显主键:"+id);
        preparedStatement.close();
        ckytest.close();
    }

4、批量操作

在url中添上rewriteBatchedStatements=true,允许批量操作。
sql语句不要加分号
preparedStatement.addBatch();
preparedStatement.executeBatch();

    @Test
    public void testinsert1() throws  Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?rewriteBatchedStatements=true", "ckytest", "123456");
        String mysql="insert into u_ser(name) values(?)";
        PreparedStatement preparedStatement = ckytest.prepareStatement(mysql,Statement.RETURN_GENERATED_KEYS);
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            preparedStatement.setObject(1,"yue1"+i);
             preparedStatement.executeUpdate();

        }
        long end = System.currentTimeMillis();
        System.out.println("时间为:"+(end-start)/1000+"s"); //14s
        preparedStatement.close();
        ckytest.close();
    }
    @Test
    public void testabatchinsert() throws  Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection ckytest = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?rewriteBatchedStatements=true", "ckytest", "123456");
        String mysql="insert into u_ser(name) values(?)";
        PreparedStatement preparedStatement = ckytest.prepareStatement(mysql);
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            preparedStatement.setObject(1,"yue"+i);
            preparedStatement.addBatch();
        }
        preparedStatement.executeBatch();
        long end = System.currentTimeMillis();
        System.out.println("时间为:"+(end-start)+"s");//0.77s
        preparedStatement.close();
        ckytest.close();
    }

5、事务

原子性 一致性 隔离性 持久性
事务的发生 必须是在同一个连接中。
对于事务,我们应该在业务层进行开启和关闭。mysql是自动提交业务,我们可以手动开启或者关闭。
比如转账业务,我们可以在业务层获取一个连接,之后将该连接传入加钱和转钱方法,这样可以确保是一个连接。
事务,我们一般使用try,catch,如果成功就提交,捕捉到错误就回滚。

6、Druid

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.alibaba.druid.pool.DruidPooledConnection;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;

public class DruidTest {
    public void druid1() throws  Exception{
        //创建连接池对象
        DruidDataSource druidDataSource=new DruidDataSource();
        //一些必要和不必要的选项 url,name,pwd,driver都是必须的 连接池数量这些不是必须的
        druidDataSource.setUrl("jdbc:mysql://127.0.0.1:3306/test");
        druidDataSource.setPassword("123456");
        druidDataSource.setUsername("ckytest");
        druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        druidDataSource.setInitialSize(5);
        druidDataSource.setMaxActive(10);
        //获得一个连接。
        DruidPooledConnection connection = druidDataSource.getConnection();
        //回收
        connection.close();//如果是连接池 则close代表 回收 而不是关闭连接。
    }
    public void druid2() throws  Exception{

        //读取配置文件
        Properties properties=new Properties();
        //只要在src下 就可以使用类加载器
        InputStream resourceAsStream = DruidTest.class.getClassLoader().getResourceAsStream("druid.properties");
        properties.load(resourceAsStream);//加载到properties中
        DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
        //获得一个连接。
        Connection connection = dataSource.getConnection();
        //回收
        connection.close();//如果是连接池 则close代表 回收 而不是关闭连接。
    }
}

Url=jdbc:mysql://127.0.0.1:3306/test
Password=123456
Username=ckytest
DriverClassName=com.mysql.cj.jdbc.Driver

6.1 工具类V1

每次都去初始化连接池太麻烦了,我们封装一个工具类,对外提供一个获取连接和回收连接的方法。

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
/*
*   工具类:内部包含一个连接池对象 对外提供连接和回收连接的方法
*  创建连接池对象 应该是一个单例模式 可以使用静态代码块来实现 只加载一次
 */
public class DruidUtils {
    //连接池
    private static DataSource dataSource=null;
    static {
        Properties properties=new Properties();
        InputStream resourceAsStream = DruidUtils.class.getClassLoader().getResourceAsStream("druid.properties");
        try {
            properties.load(resourceAsStream);

        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }


    }
    public Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
    public void closeConnection(Connection connection){
        try {
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

6.2 工具类V2

我们的工具类V1,只是单例模式了连接池,但是每次获取连接都是新的连接。
如果我们在Serve层获得一个连接,这个连接还需要传给Dao层来获取,能不能让同一个线程,Serve层和Dao层获取的都是同一个连接,而不用使用参数传递呢?可以使用线程局部变量。只要一个线程里边的属性就是通用的。

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
/*
*   工具类:内部包含一个连接池对象 对外提供连接和回收连接的方法
*  创建连接池对象 应该是一个单例模式 可以使用静态代码块来实现 只加载一次
 */
public class DruidUtils {
    //连接池
    private static DataSource dataSource=null;
    private static ThreadLocal<Connection> threadLocal=new ThreadLocal<>();
    static {
        Properties properties=new Properties();
        InputStream resourceAsStream = DruidUtils.class.getClassLoader().getResourceAsStream("druid.properties");
        try {
            properties.load(resourceAsStream);

        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }


    }
    public Connection getConnection() throws SQLException {
        Connection connection=threadLocal.get();
        if (connection==null){
            connection = dataSource.getConnection();
            threadLocal.set(connection);
        }
        return connection;
    }
    public void closeConnection() throws Exception{
        Connection connection = threadLocal.get();
        if (connection!=null){
            threadLocal.remove();
            connection.setAutoCommit(true);
            connection.close();
        }
    }
}

6.3

对于Dao层的封装,写一个基础BaseDao,对语句进行封装,可以分为DQL和非DQl两种。

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class A {

    public static int  executUpdate(String sql,Object ... args) throws Exception{
        Connection connection = DruidUtils.getConnection();
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        for (int i = 0; i <args.length ; i++) {
            preparedStatement.setObject(i+1,args[i]);
        }
        int i = preparedStatement.executeUpdate();
        if (connection.getAutoCommit()){
            //没有开启事务
            DruidUtils.closeConnection();
        }
        return i;
    }
    public static  <T>  List<T> executQuery(Class<T> tClass,String sql, Object ... args) throws Exception{
        Connection connection = DruidUtils.getConnection();
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        if(args!=null&&args.length>0)
        {
            for (int i = 0; i <args.length ; i++) {
                preparedStatement.setObject(i+1,args[i]);
            }
        }
        ResultSet resultSet = preparedStatement.executeQuery();
        //得到表信息
        ResultSetMetaData metaData = resultSet.getMetaData();
        //得到列数量
        int columnCount = metaData.getColumnCount();
        List<T> list=new ArrayList<>();
        while(resultSet.next()) {
            Constructor<T> constructor = tClass.getConstructor();
            T t = constructor.newInstance();
            for (int i = 1; i <= columnCount; i++) {
                //获得结果
                Object object = resultSet.getObject(i);
                //获得列名
                String columnLabel = metaData.getColumnLabel(i);
                Field declaredField = tClass.getDeclaredField(columnLabel);
                declaredField.set(t,object);
            }
            list.add(t);
        }
        if (connection.getAutoCommit()){
            //没有开启事务
            DruidUtils.closeConnection();
        }
        return list;
    }
}

数据库每个表都对应java中的一个实体类,查询时我们返回的是一个装有实体类的集合。

封装过工具类之后的增删改查 简化了很多。

import com.mysql.cj.jdbc.Driver;
import org.junit.Test;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class test {
    @Test
   public void testinsert() throws  Exception{

       String mysql="insert into u_ser(id,name) values(?,?);";
        int a = A.executUpdate(mysql, 50001, "a");
        System.out.println(a);
   }

    @Test
    public void testupdate() throws  Exception{

        String mysql="update u_ser set name=? where id=?;";
        int a = A.executUpdate(mysql, "cui", 1);
        System.out.println(a);
    }
    @Test
    public void testdelete() throws  Exception{

        String mysql="delete from u_ser where  id=?;";
        int a = A.executUpdate(mysql, 1);
        System.out.println(a);
    }

    //查询u_ser表中所有的内容 并保存到 List<map>集合中 key-value
    @Test
    public void testquery() throws  Exception{
        String mysql="select * from u_ser;";
        List<User> users = A.executQuery(User.class, mysql);
        System.out.println(users);
    }


  
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

1、Dev软件的安装

预先善其事,必先利其器,想要学习编程语言的第一步就是学会使用编译软件,在这里我们所使用的编译软件为 Dev-cpp 5.11 ,在这一章节,我们将讲述如何下载并安 Dev-cpp 5.11。 一、下载 首先,我们要先学会下载 Dev-cpp 5.11,这里我们点击:Dev-cpp 5.11,即可完成下载,注…

Appium —— 移动应用自动化测试开源工具!

Appium介绍 Appium是一个用于自动化移动应用程序的开源工具&#xff0c;它支持iOS和Android平台。通过Appium&#xff0c;开发人员可以使用各种编程语言&#xff08;如Java、Python、Ruby等&#xff09;编写测试脚本&#xff0c;以自动化测试移动应用程序的功能和用户界面。Ap…

pytest运行结果解析及其改造

简介&#xff1a;场景假设 - 当运行pytest完成后&#xff0c;需要针对运行的结果进行即时的反馈&#xff0c;打印 PASS 或者 FAIL&#xff0c;及其运行失败的原因&#xff0c;最后将结果推送给消息机器人。 历史攻略&#xff1a; pytestallure安装和使用 pytest&#xff1a;…

C# 对App.config、Web.config的appSettings节点数据进行加密

appSettings加密原因&#xff0c;就是因为容易暴露服务器账号和密码&#xff0c;而且客户也不允许 使用ASP.NET提供的命令工具aspnet_regiis来创建加密命令&#xff1b;aspnet_regiis是提供了直接对配置文件加密的功能的&#xff1b;并且使用aspnet_regiis加密的配置节点在读取…

贪吃蛇(C语言超详细版)

目录 前言&#xff1a; 总览&#xff1a; API&#xff1a; 控制台程序&#xff08;Console&#xff09;&#xff1a; 设置坐标&#xff1a; COORD&#xff1a; GetStdHandle&#xff1a; STD_OUTPUT_HANDLE参数&#xff1a; SetConsoleCursorPosition&#xff1a; …

Springboot测试找不到bean

1.没有加注解 service类上需要加注解 2.Test类引用错误 3.测试类与我们使用的包名不同&#xff0c;两个都是com.travel才可以&#xff0c;否则扫描不到 4.引入的启动类错误 5.不是很确定&#xff0c;但是也是我犯的错误 6.没有配置好XML文件 有的话再补充

【并发编程】锁相关公平锁和非公平锁?可重入锁锁的升级乐观锁和悲观锁版本号机制CAS 算法乐观锁有哪些问题?

目录 ​编辑 锁相关 公平锁和非公平锁&#xff1f; 可重入锁 锁的升级 乐观锁和悲观锁 版本号机制 CAS 算法 乐观锁有哪些问题&#xff1f; 锁相关 公平锁和非公平锁&#xff1f; 公平锁 : 锁被释放之后&#xff0c;先申请的线程先得到锁。性能较差一些&#xff0c;因…

Nacos介绍和统一配置管理

Nacos&#xff08;全称为 Alibaba Cloud Nacos&#xff0c;或简称为 Nacos&#xff09;是一个开源的分布式服务发现和配置管理系统。它由阿里巴巴集团开发并开源&#xff0c;旨在帮助开发人员简化微服务架构下的服务注册、发现和配置管理。 一、Nacos 提供了以下主要功能&…

Deconstructing Denoising Diffusion Models for Self-Supervised Learning

开头说点题外话&#xff1a;这篇可谓是大咖云集啊&#xff0c;刘壮、谢赛宁、何凯明这些耳熟能详的名字&#xff0c;并且这篇论文一些人也觉得分析特别到位&#xff0c;不愧是大佬视角&#xff0c;配得上“解构”两个字&#xff1b;很巧的是&#xff0c;本科阶段的团队导师也是…

什么是虚拟继承

由于C支持多继承&#xff0c;除了public、protected和private三种继承方式外&#xff0c;还支持虚拟&#xff08;virtual&#xff09;继承&#xff0c;举个例子&#xff1a; #include <iostream> using namespace std;class A {}; class B : virtual public A {}; class…

大学形势与政策~秋试题及答案,分享几个实用搜题和学习工具 #媒体#笔记

大学生必备&#xff0c;这条笔记大数据一定定要推给刚上大学的学弟学妹&#xff01;&#xff01; 1.白鸽搜题 这个是公众号 超强题库资源&#xff0c;涵盖行业单位、学历提升等各类考试。解题更轻松&#xff0c;学习更高效。 下方附上一些测试的试题及答案 1、外部招募的主…

【数据库】聚合函数

系列文章目录 &#x1f308;座右铭&#x1f308;&#xff1a;人的一生这么长、你凭什么用短短的几年去衡量自己的一生&#xff01; &#x1f495;个人主页:清灵白羽 漾情天殇_计算机底层原理,深度解析C,自顶向下看Java-CSDN博客 ❤️相关文章❤️&#xff1a;清灵白羽 漾情天…

虚拟机Ubuntu无法识别U盘

1. 现象 虚拟机插入U盘后&#xff0c;无反应。系统中也找不到U盘。 2. 原因 VMware USB Arbitration Service服务别关闭了&#xff0c;任务管理器中找不到该任务。 服务中也没有运行&#xff08;services.msc&#xff09; 3. 解决 打开服务设置窗口&#xff08;services.…

温湿度项目设计V1.0——PCB布线及打板

PCB布线 画好原理图之后&#xff0c;通过工具——标注所有器件&#xff0c;当前原理图上的器件编号会被自动标注号。点击设置——Update PCB Document文件名&#xff0c;弹出的界面先点击生效变更&#xff0c;然后点击执行变更。界面会跳转到PCB界面。如果生效变更有问题&…

城管智慧执法系统源码,基于微服务+java+springboot+vue开发

城管智慧执法系统源码&#xff0c;基于微服务javaspringbootvue开发 城管智慧执法系统源码有演示&#xff0c;自主研发&#xff0c;功能完善&#xff0c;正版授权&#xff0c;可商用上项目。 一套数字化的城管综合执法办案系统源码&#xff0c;提供了案件在线办理、当事人信用…

开学考核复现

不要尝试爆破哟!(misc) 下载图片&#xff0c;解析图片 拿到密码&#xff0c;解压压缩包&#xff0c;生成图片 扫描二维码 留个后门(misc) D盾扫描 打开文件寻找 师姐的旅游照片(misc) 随波逐流&#xff0c;然后base64解码 修改后缀为zip&#xff0c;解压 修改高度 Fuck! (C…

「媒体宣传」企业活动发布会邀请媒体报道的好处与优势?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 企业活动发布会邀请媒体报道具有多种好处与优势&#xff0c;这些都有助于提升企业的知名度、形象和影响力。以下是一些主要的好处与优势&#xff1a; 提升品牌知名度&#xff1a;媒体报道…

MATLAB环境下基于离散小波变换和主成分平均的医学图像融合方法

随着计算机技术和生物影像工程的日趋成熟&#xff0c;医学图像为医疗诊断提供的信息越来越丰富。目前&#xff0c;由于医学成像的设备种类繁多&#xff0c;导致医生获得的图像信息差异较大。如何把这些信息进行整合供医生使用成为当务之急。基于此&#xff0c;医学图像融合技术…

Windows下安装QT,遇到下载组件中没有指定版本(提供解决方式) + 5.15详细安装步骤版

Windows下安装QT 5.15详细安装问题详解 前情提要一、QT 5.15及之后版本的下载问题二、QT 5.15及之后版本的下载方式&#xff1a;下载QT(在线安装版本)三、详细安装步骤遇到<下载组件>中没有指定版本的解决方式 前情提要 嵌入式设备搭载的QT版本是5.15&#xff0c;所以PC…

【C语言】预处理编译链接调试技巧详解

主页&#xff1a;醋溜马桶圈-CSDN博客 专栏&#xff1a;C语言_醋溜马桶圈的博客-CSDN博客 gitee&#xff1a;mnxcc (mnxcc) - Gitee.com 目录 1.预处理 1.1 预定义符号 1.2 #define 1.2.1 #define 定义标识符 1.2.2 #define 定义宏 1.2.3 #define 替换规则 1.2.4 #和## …