QT QxOrm CRUD增删改查mysql数据库操作

news2024/9/20 0:28:11

QT QxOrm CRUD增删改查mysql数据库操作
QxOrm 是一个 C++ 库,旨在为 C++ 用户提供对象关系映射 (ORM) 功能。
基于每个类的简单 C++ 设置函数(如 Java 中的 Hibernate XML 映射文件),QxOrm 库提供以下功能:
持久性: 支持最常见的数据库,如 SQLite、MySQL、PostgreSQL、Oracle、MS SQL Server、MongoDB(具有 1-1、1-n、n-1 和 n-n 关系)
序列化: JSON、二进制和 XML 格式;
反射(或自省): 动态访问类定义、检索属性和调用类方法
HTTP Web 服务器: 独立的多线程 HTTP 1.1 Web 服务器(支持 SSL/TLS、持久连接、cookie、会话、分块响应、URL 调度程序/路由)

by txwtech
JSON API: 与 C++/Qt 以外的其他技术(REST Web 服务、QML 应用程序、脚本语言)的互操作性。
QxOrm 依赖于 Qt(从 4.5.0 版开始)和 boost(从 1.38 版开始,默认情况下只需要头文件 *.hpp)

下载源码

 参考:

https://www.cnblogs.com/txwtech/p/18361998

打开pro文件 


 

编译完成后生成dll:

 

新建qxormtest项目测试程序

 

配置pro文件,对应QxOrm1.5存放路径进行相应修改

QT += core gui
QT += core gui sql
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++17
QMAKE_PROJECT_DEPTH = 0
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    book.cpp \
    main.cpp \
    mainwindow.cpp

HEADERS += \
    book.h \
    export.h \
    mainwindow.h \
    precompiled.h

FORMS += \
    mainwindow.ui
DEFINES += _BUILDING_QX_BOOK #通过它可以知道项目是否正在编译
#include(./QxOrm/QxOrm.pri)
#include(D:/QT_Project/QxOrm-master/QxOrm/QxOrm.pri)
include(D:/QT_Project/QxOrm_1.5.0/QxOrm-master/QxOrm.pri)
# 设置好QxOrm链接库目录和文件包含
INCLUDEPATH += D:/QT_Project/QxOrm_1.5.0/QxOrm-master/include
LIBS += -LD:\QT_Project\QxOrm_1.5.0\QxOrm-master\lib

# 设置好QxOrm对应的动态链接库
 CONFIG(debug, debug|release) {
 TARGET = qxormtest
 LIBS += -l"QxOrmd"
 } else {
 TARGET = qxormtest
 LIBS += -l"QxOrm"
 })
# 定义好预编译文件
!contains(DEFINES, _QX_NO_PRECOMPILED_HEADER) {
PRECOMPILED_HEADER = ./precompiled.h
} # !contains(DEFINES, _QX_NO_PRECOMPILED_HEADER)


# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target


 cpp文件:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QList>
#include "book.h"
#include <QDebug>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
//#include "precompiled.h"
//#pragma execution_character_set("utf-8")
#pragma execution_character_set("utf-8")


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);


    /**********************************************
* @projectName   %{CurrentProject:Name}
* @brief         获取现在可用的数据库驱动
* @param         void
* @return        void
* @author        cdtxw@foxmail.com/ by txwtech
* @date          2024-08-27
**********************************************/

    qDebug() << "Available drivers:";
    QStringList drivers = QSqlDatabase::drivers();  //
    foreach(QString driver, drivers)
        qDebug() << driver;
   // connect_mysql();


    /**********************************************
* @projectName   %{CurrentProject:Name}
* @brief         连接数据库
* @param         void
* @return        void
* @author        cdtxw@foxmail.com/ by txwtech
* @date          2024-08-27
**********************************************/

    qx::QxSqlDatabase::getSingleton()->setDriverName("QMYSQL");			//这里可以是任意支持的数据库驱动
    qx::QxSqlDatabase::getSingleton()->setDatabaseName("book_store_db");
    qx::QxSqlDatabase::getSingleton()->setHostName("localhost");
    qx::QxSqlDatabase::getSingleton()->setUserName("root");
    qx::QxSqlDatabase::getSingleton()->setPassword("87958868");
    qx::QxSqlDatabase::getSingleton()->setPort(3306);
    qx::QxSqlDatabase::getSingleton()->setFormatSqlQueryBeforeLogging(true);
    qx::QxSqlDatabase::getSingleton()->setDisplayTimerDetails(true);

    QSqlError sqlError;
    QSqlDatabase db = qx::QxSqlDatabase::getDatabase();
    // 检查连接是否有效
    if (db.isValid())
    {
        qDebug() << "mysql connection is ok数据库连接成功!";

        if (sqlError.type() == QSqlError::NoError)
        {
           // qDebug() << "表创建成功!";
        }
        else
        {
          //  qDebug() << "表创建失败! 错误信息: " << sqlError.text();
        }
    }
    else
    {
        sqlError = db.lastError();  // 获取最后一次数据库错误信息
        qDebug() << "mysql connection is false,数据库连接失败!";
        qDebug() << "错误信息: " << sqlError.text();
    }

    QSqlError daoError;
    QList<book> list_of_book;

    // 尝试从数据库中获取所有的 book 记录
    daoError = qx::dao::fetch_all(list_of_book);
    if (daoError.type() == QSqlError::NoError)
    {
        qDebug() << "数据查询成功!";
        // 遍历 QList<book>
        for (const book& book2 : list_of_book)
        {
            qDebug() << "ID: " << book2.id << ", Name: " << book2.book_name << ", isbn: " << book2.book_ibsn<<",price:"<<book2.book_price;
            // 在这里可以执行其他操作
        }
    }
    else
    {
        qDebug() << "查询所有数据失败! 错误信息: " << daoError.text();
    }


/**********************************************
* @projectName   %{CurrentProject:Name}
* @brief         查询
* @param         void
* @return        void
* @author        cdtxw@foxmail.com/ by txwtech
* @date          2024-08-27
**********************************************/

    //第一种方法-执行原生的sql语句
    List_book list_book;
   // qx_query querySql("select * from user");

   // daoError = qx::dao::execute_query(querySql, list_user);

   // List_user::iterator it = list_user.begin();
  //  while(it != list_user.end()){

       // qDebug() << "id:" << it.i->t().second->id;
       // qDebug() << "name:" << it.i->t().second->name;
       // qDebug() << "age:" << it.i->t().second->age;
       // qDebug() << "capacity:" << it.i->t().second->capacity;
       // it++;
   // }
    //第二种方法-fetch_xxx
    //qx::dao::fetch_all(list_book);
    // 当然还有其他很多函数:fetch_by_id(),fetch_by_query()....
    //占位符形式
    //QList<book> list_of_book;
    qx::QxSqlQuery query("WHERE book_name = :book_name");   //默认前面是 select * from user
    query.bind(":book_name","语文");

    daoError = qx::dao::fetch_by_query(query,list_of_book);
    for (long l = 0; l < list_of_book.count(); l++)
    {
        /* here we can work with the collection provided by database */
        qDebug()<<"yuwen query:"<<list_of_book[l].book_name<<",price:"+list_of_book[l].book_price;
    }

    //占位符的变体
    qx_query query2;
    query2.where("book_ibsn").startsWith("isbn")
        .and_("book_price").isGreaterThan(10)
        .and_("book_price").isLessThan(30);

    daoError = qx::dao::fetch_by_query(query2,list_of_book);
    qDebug()<<"书本序号开始查找:";
    for (long l = 0; l < list_of_book.count(); l++)
    {
        /* here we can work with the collection provided by database */
        qDebug()<<list_of_book[l].book_name<<"isbn:"<<list_of_book[l].book_ibsn<<",price:"+list_of_book[l].book_price;
    }

    //查询自己关心的字段,默认是查询指定表的所有列,指定关系可以查询自己指定的列
    //定义一个关系
    QStringList relations = QStringList() << "-{book_ibsn,book_price}" << "{book_name}";//获取感兴趣的属性(name,capacity),如果没有关系默认是查询一个表的所有列数据,如果在{}前面加-,表示不要此属性
    qx::dao::fetch_by_query_with_relation(relations,query2,list_of_book);

    qDebug()<<"仅仅显示书名:";
    for (long l = 0; l < list_of_book.count(); l++)
    {
        /* here we can work with the collection provided by database */
        qDebug()<<list_of_book[l].book_name<<"isbn:"<<list_of_book[l].book_ibsn<<",price:"+list_of_book[l].book_price;
    }

/**********************************************
* @projectName   %{CurrentProject:Name}
* @brief         添加数据
* @param         void
* @return        void
* @author        cdtxw@foxmail.com/ by txwtech
* @date          2024-08-27
**********************************************/
    typedef QSharedPointer<book> bk_ptr;
    bk_ptr bk1;
    bk1.reset(new book());
    bk1->book_name="yuwen11";
    bk1->book_ibsn ="yusn001";
    bk1->book_price ="32.1";

    bk_ptr bk2;
    bk2.reset(new book());
    bk2->book_name="yuwen22";
    bk2->book_ibsn ="yusn002";
    bk2->book_price ="33.1";

    //qvector存放book的智能指针
    typedef QVector<bk_ptr> book_vec;
    book_vec bk_vec;
    bk_vec.push_back(bk1);
    bk_vec.push_back(bk2);

    daoError = qx::dao::insert(bk_vec);
    if(daoError.type()==QSqlError::NoError)
    {
        qDebug()<<"数据添加成功";
    }
    else
    {
        qDebug()<<"数据添加失败"<<daoError.text();
    }

/**********************************************
* @projectName   %{CurrentProject:Name}
* @brief         删除数据
* @param         void
* @return        void
* @author        cdtxw@foxmail.com/ by txwtech
* @date          2024-08-27
**********************************************/
    book del_bookInfo;
    del_bookInfo.id=12;
    daoError = qx::dao::delete_by_id(del_bookInfo);
    if(daoError.type()==QSqlError::NoError)
    {
        qDebug()<<"数据删除成功";
    }
    else
    {
        qDebug()<<"数据删除失败"<<daoError.text();
        return;
    }

   //条件删除:
    qx::QxSqlQuery condition_query("WHERE book_name = 'yuwen1'");
    daoError = qx::dao::delete_by_query<book>(condition_query);
/**********************************************
* @projectName   %{CurrentProject:Name}
* @brief         修改数据 by id
* @param         void
* @return        void
* @author        cdtxw@foxmail.com/ by txwtech
* @date          2024-08-27
**********************************************/

    book bookInfo;
    bookInfo.id=10;

    daoError = qx::dao::fetch_by_id(bookInfo);
    if(daoError.type()==QSqlError::NoError)
    {
        qDebug()<<"数据查询成功";
    }
    else
    {
        qDebug()<<"数据查询失败"<<daoError.text();
        return;
    }
    bookInfo.book_name="语文3";
    bookInfo.book_price="99.99999";
    daoError = qx::dao::update(bookInfo);
    if(daoError.type()==QSqlError::NoError)
    {
        qDebug()<<"数据更新成功";
    }
    else
    {
        qDebug()<<"数据更新失败"<<daoError.text();
        return;
    }

    /**********************************************
* @projectName   %{CurrentProject:Name}
* @brief         修改数据 by bookname
* @param         void
* @return        void
* @author        cdtxw@foxmail.com/ by txwtech
* @date          2024-08-27
**********************************************/

    book bookInfo2;
   // qx::QxSqlQuery query_mo("WHERE book_name = :book_name");   //默认前面是 select * from user
    qx::QxSqlQuery query_mo("WHERE book_name = 'yuwen2'");
    //query_mo.bind(":book_name","yuwen2");
    qx_query qx2;
    qx2.where("book_name").isEqualTo("yuwen2");
     daoError = qx::dao::fetch_by_query(query_mo,list_of_book);
    //bookInfo2.id =18;
    //bookInfo2.book_name = "yuwen2b";

    bookInfo2.book_price="6.661";
     QStringList aa={"book_price"};


     daoError = qx::dao::update_by_query(query_mo,bookInfo2,NULL,aa,true);//测试未修改成功,待分析

     //QStringList relations3 = QStringList() << "-{id,book_ibsn,name}" << "{book_price}";//获取感兴趣的属性(name,capacity),如果没有关系默认是查询一个表的所有列数据,如果在{}前面加-,表示不要此属性

    // daoError = qx::dao::update_by_query_with_relation(relations3,query_mo,bookInfo2);




     //qx::dao::save 和 qx::dao::insert都可以进行插入,区别在于如果save的数据的id是存在的则修改数据
    // bookInfo2.id =2;
    // bookInfo2.book_name = "art2";
    // qx::dao::save(bookInfo2);

//普通查询语句
     QString price_value ="7.78";
     QString com_sql =QString("UPDATE book_info SET book_ibsn='ibsn1',book_price='%1' WHERE book_name='yuwen2'").arg(price_value);
     qx_query querySql_normal(com_sql);


      daoError = qx::dao::execute_query(querySql_normal,bookInfo2);
    if(daoError.type()==QSqlError::NoError)
    {
        qDebug()<<"数据更新成功by bookname";
    }
    else
    {
        qDebug()<<"数据更新失败by book name"<<daoError.text();
        return;
    }



}


void MainWindow::connect_mysql()
{
    db = QSqlDatabase::addDatabase("QMYSQL");

    db.setHostName("localhost");

    db.setPort(3306);

    db.setDatabaseName("book_store_db");

    db.setUserName("root");

    db.setPassword("87958868");

    if (!db.open()) {

        qDebug("Sql connect failed.");

        qDebug() << db.lastError().text();

    } else {

        qDebug("Sql connected.");

    }

    query=QSqlQuery(db);

    QString sq="INSERT INTO db_mysql VALUES(0,'ttxsss', 123, '很好', 60, 0);";

    bool res=query.exec(sq);
    if(!res){
        qDebug()<<"添加失败";
    }else
    {
        qDebug()<<"添加成功";
    }
}

\
MainWindow::~MainWindow()
{
    delete ui;
}

 建立数据库映射

book.h

// book.h
#ifndef BOOK_H
#define BOOK_H
//#include "precompiled.h"    //带有 '#include <QxOrm.h>' 和 '#include "export.h"' 的预编译头文件
//#include <QxOrm_Impl.h>

class QX_BOOK_DLL_EXPORT book
//class QX_DLL_EXPORT_HELPER book
{
    //在 QxOrm 上下文中注册的 4 个属性id,name,age,capacity
public:
    int id;
    QString book_name;
    //int age;
    //double capacity;
    QString book_ibsn;
    QString book_price;

    book(): id(1){;} //初始化id为1
    virtual ~book(){;}
};

QX_REGISTER_PRIMARY_KEY(book, int)  // 定义主键的类型

/**

 QX_REGISTER_HPP_QX_DEMO宏是在 QxOrm 上下文中注册 'BOOK' 类所必需的
 参数 1:要注册的当前类 => 'BOOK'
 参数 2 : 基类,如果没有基类,使用 qx trait => 'qx::trait::no_base_class_defined'
 参数 3 : 序列化引擎用来提供“上升兼容性”的类版本
*/
QX_REGISTER_HPP_QX_BOOK(book, qx::trait::no_base_class_defined, 0)

typedef std::shared_ptr<book> book_ptr;
typedef qx::QxCollection<int, book_ptr> List_book;

#endif // BOOK_H

cpp

#include "precompiled.h"    //带有 '#include <QxOrm.h>' 和 '#include "export.h"' 的预编译头文件
#include "book.h"
#include <QxOrm_Impl.h>     // 自动内存泄漏检测和提升序列化导出宏

QX_REGISTER_CPP_QX_BOOK(book)    // 这个宏是在 QxOrm 上下文中注册 'User' 类所必需的

namespace qx
{

  template <> void register_class(QxClass<book> &t)
  {

    t.setName("book_info");  // 'User' C++ 类映射到 'user' 数据库表
    t.id(&book::id, "id");  // Register 'User::id' <=> primary key in your database
    t.data(&book::book_name, "book_name");  // Register 'User::age' property mapped to 'age' database column name
    t.data(&book::book_ibsn, "book_ibsn"); // Register 'User::name' property mapped to 'name' database column name
    t.data(&book::book_price, "book_price");    // Register 'User::capacity' property mapped to 'capacity' database column name
  }

}

export.h

#ifndef EXPORT_H
#define EXPORT_H

#ifdef _BUILDING_QX_BOOK
#define QX_BOOK_DLL_EXPORT QX_DLL_EXPORT_HELPER
#else
#define QX_BOOK_DLL_EXPORT QX_DLL_IMPORT_HELPER
#endif

#ifdef _BUILDING_QX_BOOK
#define QX_REGISTER_HPP_QX_BOOK QX_REGISTER_HPP_EXPORT_DLL
#define QX_REGISTER_CPP_QX_BOOK QX_REGISTER_CPP_EXPORT_DLL
#else
#define QX_REGISTER_HPP_QX_BOOK QX_REGISTER_HPP_IMPORT_DLL
#define QX_REGISTER_CPP_QX_BOOK QX_REGISTER_CPP_IMPORT_DLL
#endif

#endif // EXPORT_H

PRECOMPILED.h预编译文件

#ifndef PRECOMPILED_H
#define PRECOMPILED_H

#include <QxOrm.h>
#include "export.h"

#endif // PRECOMPILED_H

 数据库

测试结果:

打印输出

QT5.15.2加载mysql驱动-QMYSQL driver not loaded解决方法_qt加载mysql-CSDN博客

工程代码:

https://download.csdn.net/download/txwtech/89720062

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

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

相关文章

安宝特案例 | AR如何大幅提升IC封装厂检测效率?

前言&#xff1a;如何提升IC封装厂检测效率&#xff1f; 在现代电子产品的制造过程中&#xff0c;IC封装作为核心环节&#xff0c;涉及到复杂处理流程和严格质量检测。这是一家专注于IC封装的厂商&#xff0c;负责将来自IC制造商的晶圆进行保护、散热和导通处理。整个制程繁琐…

C语言俄罗斯方块(VS2022版)

C语言俄罗斯方块 演示视频一、前置知识1.Win32 API 的使用2.宽字符的使用 二、封装核心数据与框架介绍三、核心操作介绍旋转操作检测操作水平检测竖直检测代码化简 四、源码展示在 tetris.h 中&#xff1a;在 tetris.c 中&#xff1a;在 test.c 中&#xff1a; 以下代码环境为 …

小阿轩yx-Zabbix企业级分布式监控环境部署

小阿轩yx-Zabbix企业级分布式监控环境部署 前言 “运筹帷幄之中&#xff0c;决胜千里之外”监控在 IT 运维中占据着重要地位&#xff0c;按比例说占 30% 也不为过在监控系统开源软件中有很多可选择的工具&#xff0c;但是真正符合要求的、能够真正解决业务问题的监控系统软件…

W外链微信推广短连接怎么做?

制作微信推广链接的难点分析 一、内容创作难度 制作微信推广链接时&#xff0c;首先需要创作有吸引力的内容。这不仅要求内容本身有趣、有价值&#xff0c;还要能够激起人们的分享欲望。对于许多企业和个人来说&#xff0c;尤其是那些缺乏创意和写作能力的人来说&#xff0c;…

OpenHarmony鸿蒙开发( Beta5.0)智能甲醛检测系统实践

样例简介 本项目是基于BearPi套件开发的智能甲醛检测系统Demo&#xff0c;该设备硬件部分主要由小熊派单板套件和和甲醛检测传感器组成。智能甲醛检测系统可以通过云和手机建立连接&#xff0c;可以在手机上设置甲醛浓度阈值&#xff0c;传感器感知到的甲醛浓度超过阈值之后&a…

QQ邮箱“已发送”邮件竟然无法一键清空?看我操作,怎么删除12万+已发送邮件

最近遇到了一个问题&#xff0c;QQ邮箱提示我空间已满&#xff0c;所以我就专门去看看有哪些邮件可以删除&#xff0c;释放点空间。 我直接暴力删除了很多文件夹的邮件&#xff0c;在文件夹管理界面 有“清空”按钮&#xff0c;点一个即可清空。 但是。。。不出意外的话要出意…

南卡、韶音、墨觉:精选三款旗舰骨传导耳机全面对比评测!

在科技日新月异的今天&#xff0c;耳机作为我们日常生活中不可或缺的音频伴侣&#xff0c;正经历着前所未有的变革。特别是骨传导耳机&#xff0c;凭借其独特的声音传导方式和出色的佩戴体验&#xff0c;逐渐成为了运动爱好者和户外探索者的首选。在众多品牌中&#xff0c;南卡…

Pycharm的安装与Conda环境的配置

目录 第一步&#xff1a;下载并安装 PyCharm 社区版 第二步&#xff1a;创建新项目并配置 Python 解释器 第三步&#xff1a;配置 Conda 环境 第四步&#xff1a;验证环境 第五步&#xff1a;测试 PyTorch 第六步&#xff1a;测试基本 PyTorch 代码 第一步&#xff1a;下…

替代区块链

随着比特币的成功&#xff0c;人们逐渐意识到区块链技术的潜力&#xff0c;并随之出现了迅速的发展&#xff0c;各种区块链协议、应用程序和平台相应产生。 需要指出的是&#xff0c;在这种多元的局面下&#xff0c;很多项目迅速失去了它们的吸引力。事实上&#xff0c;有不少项…

深圳MES系统在制造业的应用与发展

深圳MES在制造业的应用与发展呈现以下几个特点&#xff1a; 应用范围广泛&#xff1a;深圳制造业涵盖了电子、通信、汽车、机械等多个领域&#xff0c;MES系统在这些领域的应用非常广泛。不同行业的企业可以根据自身的需求和特点&#xff0c;定制化地应用MES系统来实现生产管理…

测试即服务(TaaS):概念、优势及应用场景!

引言 随着数字化转型的深入发展&#xff0c;软件质量和用户体验变得愈发重要。传统的软件测试方法已经难以满足现代企业对于快速迭代和高质量交付的需求。在此背景下&#xff0c;“测试即服务”(Testing as a Service, TaaS) 模式应运而生&#xff0c;为软件测试带来了新的解决…

基于SpringBoot+Vue+MySQL的足球俱乐部管理系统

系统展示 用户前台界面 管理员后台界面 系统背景 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统足球俱乐部管理…

Gtest(Google Test)使用

下面Gtest是在arm-linux下运行的 https://download.csdn.net/download/qq_31868891/89729426 一、下载编译 1.下载gtest代码 https://github.com/google/googletest 2.配置编译 vscode安装CMake Tools 将上面下载的gtest代码文件夹拖到vscode里&#xff0c;然后选择对应的…

SAP 凭证的替代传输GGB1

SAP 凭证的替代传输GGB1 之前没有留意过&#xff0c;前人一直是直接改的&#xff0c;搜索了一下是可以这样弄得 1.一般通过OBBH&#xff0c;配置的凭证替代&#xff0c;产生的请求号&#xff0c;从开发机传输不到生产机。只能通过GGB1来传输。在GGB1里面选择要传输的替代 选中…

BookStack在线文档管理系统本地Docker部署与远程访问详细教程

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

LEAN类型系统属性之规范性(Regularity)注解

在 《小结》 中&#xff0c;列出LEAN类型系统所定义的全部规律&#xff0c;下面 关于 LEAN 属性 的一些推论&#xff08;Lemma&#xff09;进行注解。主要是其规范性&#xff08;Regularity&#xff09;&#xff0c;以说明LEAN类型系统是完备构建的&#xff08;well founded&am…

Java+selenium+chrome+linux/windows实现数据获取

背景&#xff1a;在进行业务数据获取或者自动化测试时&#xff0c;通常会使用模拟chrome方式启动页面&#xff0c;然后获取页面的数据。在本地可以使用windows的chromedriver.exe进行打开chrome页面、点击等操作。在linux 下通常使用无界面无弹窗的方式进行操作。接下来是实现方…

【AI绘画】Midjourney之Lighting详解

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AI绘画 | Midjourney 文章目录 &#x1f4af;前言&#x1f4af;为什么要学习光影控制光影控制的作用 &#x1f4af;强化主题hard lighting&#xff08;硬光 &#xff09;soft lighting&#xff08;软光/柔光&#xff09;测试 &…

宠物浮毛怎么办,用专业工具——希喂、小米、美的宠物空气净化器

前段时间被医生科普&#xff0c;原来猫咪的毛发也分好几种的&#xff0c;我不是最后一个知道的吧...事情的起因是这样的&#xff0c;上次我去朋友家和她的猫咪玩&#xff0c;实在太可爱了所以自己也养了一只猫。一人一猫的幸福生活没过多久&#xff0c;我就发现自己的鼻炎好像复…

如何用AI先行者2.0轻松画出美图?我的亲身体验分享给你看!

越来越多的AI绘画工具开始出现在市场上。AI先行者2.0是一款备受关注的AI绘画软件。本文将为大家详细介绍这款软件的功能特点&#xff0c;并分享一些使用心得。 AI先行者2.0拥有强大的图像处理能力。 它支持多种AI模型&#xff0c;包括Midjourney、Niji、DallE3和Stable Diffu…