[C++][第三方库][ODB]详细讲解

news2024/11/24 19:12:02

目录

  • 1.介绍
  • 2.安装
    • 1.安装 build2
    • 2.安装 odb-compiler
    • 3.安装 ODB 运行时库
    • 4.安装MySQL和客户端开发包
    • 5.安装 boost profile 库
    • 6.总体操作
    • 7.测试样例
  • 3.ODB 常见操作
    • 1.ODB 类型映射
    • 2.ODB 编程
      • 1.指令
      • 2.示例
  • 4.类与接口
  • 5.使用


1.介绍

  • ODB框架:数据库ORM框架 --> 对象关系映射框架
  • 形象理解将数据结构与数据库表进行关系映射,通过数据结构的操作实现数据库中数据操作
    • 通过ODB框架实现MySQL数据库的关系映射操作

2.安装

1.安装 build2

  • 因为build2安装时,可能会版本更新,因此注意, 先从build2官网查看安装步骤
  • 如果安装过程中,因为网络问题超时失败,可以尝试:将超时时间设置的更长一些
    sh build2-install-0.17.0.sh --timeout 1800
    

2.安装 odb-compiler

#注意这里的gcc-13需要根据自己现有版本而定
~/workspace$ sudo apt-get install gcc-13-plugin-dev
~/workspace$ mkdir odb-build && cd odb-build

~/workspace/odb-build$ bpkg create -d odb-gcc-N cc \
  config.cxx=g++ \
  config.cc.coptions=-O3 \
  config.bin.rpath=/usr/lib \
  config.install.root=/usr/ \
  config.install.sudo=sudo

~/workspace/odb-build$ cd odb-gcc-N
~/workspace/odb-build/odb-gcc-N$ bpkg build odb@https://pkg.cppget.org/1/beta
~/workspace/odb-build/odb-gcc-N$ bpkg test odb
~/workspace/odb-build/odb-gcc-N$ bpkg install odb
~/workspace/odb-build/odb-gcc-N$ odb --version

# 如果上述命令报错找不到odb,则执行下面的命令
$ sudo echo 'export PATH=${PATH}:/usr/local/bin' >> ~/.bashrc
$ export PATH=${PATH}:/usr/local/bin
$ odb --version

3.安装 ODB 运行时库

~/workspace/odb-build/odb-gcc-N$ cd ..

~/workspace/odb-build$ bpkg create -d libodb-gcc-N cc \
    config.cxx=g++ \
    config.cc.coptions=-O3 \
    config.install.root=/usr/ \
    config.install.sudo=sudo

~/workspace/odb-build$ cd libodb-gcc-N
~/workspace/odb-build/libodb-gcc-N$ bpkg add https://pkg.cppget.org/1/beta
~/workspace/odb-build/libodb-gcc-N$ bpkg fetch
~/workspace/odb-build/libodb-gcc-N$ bpkg build libodb
~/workspace/odb-build/libodb-gcc-N$ bpkg build libodb-mysql

4.安装MySQL和客户端开发包

  • 安装
    sudo apt install mysql-server
    sudo apt install -y libmysqlclient-dev
    
  • 配置MySQLsudo vim /etc/my.cnf或者/etc/mysql/my.cnf,有哪个修改哪个
    # 添加以下内容 
    [client] 
    default-character-set=utf8 
    [mysql] 
    default-character-set=utf8 
    [mysqld] 
    character-set-server=utf8 
    bind-address = 0.0.0.0 
    
  • 修改root用户密码
    sudo cat /etc/mysql/debian.cnf
    sudo mysql -u debian-sys-maint -p
    Enter password: # 这里输入上边看到的密码
    
    mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'PASSWORD';
    		
    mysql> FLUSH PRIVILEGES;
    
    mysql> quit
    
  • 重启MySQL,并设置开机启动
    sudo systemctl restart mysql 
    sudo systemctl enable mysql
    

5.安装 boost profile 库

bpkg build libodb-boost

6.总体操作

  • 总体打包安装
    bpkg install --all --recursive
    
  • 总体卸载
    bpkg uninstall - all --recursive
    
  • 总体升级
    bpkg fetch
    bpkg status
    bpkg uninstall - all --recursive
    bpkg build --upgrade --recursive
    bpkg install --all --recursive
    

7.测试样例

  • 编写数据结构文件person.hpp
    #pragma once
    #include <string>
    #include <cstddef>
    #include <boost/date_time/posix_time/posix_time.hpp>
    
    // 在C++中,要使用ODB将类声明为持久化类,需要包含ODB的核心头文件,并使用#pragma db object指令
    // #pragma db object 指示 ODB 编译器将 person 类视为一个持久化类
    #include <odb/core.hxx>
    
    typedef boost::posix_time::ptime ptime;
    
    #pragma db object
    class Person
    {
    public:
        Person(const std::string &name, int age, const ptime &update)
            : _name(name), _age(age), _update(update)
        {}
    
        void age(int val) { _age = val; }
        int age() { return _age; }
    
        void name(const std::string &val) { _name = val; }
        std::string name() { return _name; }
    
        void update(const ptime &update) { _update = update; }
        std::string update() 
        {
    	    return boost::posix_time::to_simple_string(_update);
    	}
        	
    private:
        // 将odb::access类作为Person类的友元
        // 这是使数据库支持代码可访问默认构造函数和数据成员所必需的
        // 如果类具有公共默认构造函数和公共数据成员或数据成员的公共访问器和修饰符,则不需要友元声明
        friend class odb::access;
        Person() {}
    
    // _id 成员前面的 pragma 告诉 ODB 编译器,以下成员是对象的标识符
    // auto说明符指示它是数据库分配的 ID
    #pragma db id auto      // 表示 ID 字段将自动生成(通常是数据库中的主键)。 
        unsigned long _id;
        unsigned short _age;
        std::string _name;
    #pragma db type("TIMESTAMP") not_null
        boost::posix_time::ptime _update;
    };
    // 将 ODB 编译指示组合在一起,并放在类定义之后。它们也可以移动到一个单独的标头中,使原始类完全保持不变
    // #pragma db object(person)
    // #pragma db member(person::_name) id
    // 完成后,需要使用 odb 编译器将当前所写的代码生成数据库支持代码
    // odb -d mysql --generate-query --generate-schema person.hxx
    // 如果用到了 boost 库中的接口,则需要使用选项 : --profile boost/datetime
    // odb -d mysql --generate-query --generate-schema --profile boost/date-time person.hxx
    
  • 生成数据库支持的代码文件
    $ odb -d mysql --generate-query --generate-schema --profile boost/date-time person.hpp
    
    $ ls
    person.hpp  person-odb.cxx  person-odb.hxx  person-odb.ixx  person.sql
    
  • 编写主函数代码main.cc
    #include <string>
    #include <memory>
    #include <cstdlib>
    #include <iostream>
    #include <odb/database.hxx>
    #include <odb/mysql/database.hxx>
    #include "person.hpp"
    #include "person-odb.hxx"
    
    int main()
    {
        std::shared_ptr<odb::core::database> db(new odb::mysql::database
                ("root", "SnowK8989", "TestDB", "127.0.0.1", 0, 0, "utf8"));
        if (!db)
        {
            return -1;
        }
    
        ptime p = boost::posix_time::second_clock::local_time();
        Person Die("Die", 18, p);
        Person SnowK("SnowK", 19, p);
    
        typedef odb::query<Person> query;
        typedef odb::result<Person> result;
    
        // 新增数据
        {
            odb::core::transaction t(db->begin());
            size_t zid = db->persist(Die);
            size_t wid = db->persist(SnowK);
            t.commit();
        }
    
        // 查询数据
        {
            odb::core::transaction t (db->begin()); 
            result r (db->query<Person>()); 
            for (result::iterator i(r.begin()); i != r.end(); ++i) 
            {
                std::cout << "Hello, " << i->name() << " ";
                std::cout << i->age() << " " << i->update() << std::endl; 
            } 
            t.commit();
        }
    
        return 0;
    }
    
    // 如果用到了boost库中的接口,需要链接库: -lodb-boost
    // c++ -o mysql_test mysql_test.cpp person-odb.cxx -lodb-mysqllodb - lodb - boost
    
  • 代码编译
    c++ -o test test.cpp person odb.cxx -lodb-mysql -lodb -lodb-boost
    

3.ODB 常见操作

1.ODB 类型映射

请添加图片描述


2.ODB 编程

1.指令

  • ODB(Open Database)在数据元结构定义时,使用预处理器指令(#pragma)来提供元数据
    • 这些元数据指示如何将C++类型映射到数据库模式
    • 这些#pragma指令是在C++代码中使用的,它们不是C++语言的一部分,而是特定于ODB 编译器的扩展
  • 常用#pragma指令
    • 表的映射

      • #pragma db object:用于声明一个类是数据库对象
        • 这个类将映射到数据库中的一个表
      • #pragma db table("table_name"):指定类映射到数据库中的表名
        • 如果不指定,则默认使用类名
    • 字段的映射

      • #pragma db id:标记类中的一个成员变量作为数据库表的主键
      • #pragma db column("column_name"):指定类成员映射到数据库表中的列名
        • 如果不指定,则默认使用成员变量的名字
      • #pragma db auto:指定成员变量的值在插入时自动生成
        • 例如:自动递增的主键
      • #pragma db type("type_name"):指定成员变量不应该被持久化到数据库中
      • #pragma db unique:指定成员变量或一组变量应该具有唯一性约束
      • #pragma db index("index_name"):指定成员变量应该被索引
      • #pragma db null:指定成员变量允许为空
        • odb::nullable<>也可以实现
      • #pragma db not_null:指定成员变量不允许为空
      • #pragma db default("default_value"):指定成员变量的默认值
    • 查询相关

      • #pragma db view:用于声明一个类是一个数据库视图,而不是一个表
      • #pragma db query("query"):用于定义自定义的查询函数
    • 其它

      • #pragma db session:用于声明一个全局或成员变量是数据库会话
      • #pragma db transient:指定成员变量不应该被持久化到数据库中
      • #pragma db convert("converter"):指定用于成员变量的自定义类型转换器
      • #pragma db pool("pool_name"):指定用于数据库连接的连接池
      • #pragma db trigger("trigger_name"):指定在插入、更新或删除操作时触发的触发器

2.示例

#pragma once
#include <string>
#include <cstddef>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <odb/nullable.hxx>
#include <odb/core.hxx>

#pragma db object // 声明一个类是数据库对象
class Student
{
public:
    Student() {}
    Student(unsigned long sn, const std::string &name, unsigned short age, unsigned long cid) 
        : _sn(sn)
        , _name(name)
        , _age(age)
        , _classes_id(cid) 
    {}

    void sn(unsigned long num) { _sn = num; }
    unsigned long sn() { return _sn; }

    void name(const std::string &name) { _name = name; }
    std::string name() { return _name; }

    void age(unsigned short num) { _age = num; }
    odb::nullable<unsigned short> age() { return _age; }

    void classes_id(unsigned long cid) { _classes_id = cid; }
    unsigned long classes_id() { return _classes_id; }

private:
    // 将odb::access类作为Person类的友元
    // 这是使数据库支持代码可访问默认构造函数和数据成员所必需的
    friend class odb::access;

    // id: 标记成员变量为主键, auto: 值在插入时自动生成
    #pragma db id auto
    unsigned long _id;

    // unique: 指定变量或一组变量具有唯一键约束
    #pragma db unique
    unsigned long _sn;
    std::string _name;
    odb::nullable<unsigned short> _age;

    // 指定成员变量应该被索引
    #pragma db index
    unsigned long _classes_id;
};

#pragma db object
class Classes
{
public:
    Classes() {}
    Classes(const std::string &name) 
        : _name(name) 
    {}

    void name(const std::string &name) { _name = name; }
    std::string name() { return _name; }

private:
    friend class odb::access;

    #pragma db id auto
    unsigned long _id;
    std::string _name;
};

// 查询所有的学生信息, 并显示班级名称
#pragma db view object(Student)\
                object(Classes = classes : Student::_classes_id == classes::_id)\
                query((?)) // 用于自定义查询函数
struct Classes_Student
{
    // 指定类成员映射到数据库表中的列名
    #pragma db column(Student::_id)
    unsigned long id;
    #pragma db column(Student::_sn)
    unsigned long sn;
    #pragma db column(Student::_name)
    std::string name;
    #pragma db column(Student::_age)
    odb::nullable<unsigned short> age;
    #pragma db column(classes::_name)
    std::string classes_name;
};

// 只查询学生姓名, (?): 外部调用时传入的过滤条件
#pragma db view query("select name from Student + (?)")
struct All_Name
{
    std::string name;
};

// odb -d mysql --std c++11 --generate-query --generate-schema --profile boost/date-time student.hpp

4.类与接口

namespace odb
{ 
    namespace mysql 
    { 
        // mysql连接池对象类
        class LIBODB_MYSQL_EXPORT new_connection_factory:  
        public connection_pool_factory
        { 
            connection_pool_factory (std::size_t max_connections = 0, 
                                     std::size_t min_connections = 0, 
                                     bool ping = true);
        }; 
    }
    
    // 操作句柄类, 实现数据库的增删查改操作
    class LIBODB_EXPORT database 
    { 
        // 新增数据 
        persist (T& object); 
        
        // 更新数据 
        void update (T& object);

		// 删除数据
        void erase (T& object); 
        
        unsigned long long erase_query (const std::string&);
		// 过滤并删除
        unsigned long long erase_query (const odb::query<T>&);
        
        result<T> query (const std::string&); 
		// 查询
        result<T> query (const odb::query<T>&, bool cache = true);
        
        typename result<T>::pointer_type query_one(const odb::query<T>&); 

		// 获取事务对象指针
        virtual transaction_impl* begin () = 0; 
    }; 
    
    // 事务操作类
    class LIBODB_EXPORT transaction 
    { 
        transaction (transaction_impl*, bool make_current = true); 
        void commit ();   // 事务提交操作
        void rollback (); // 事务回滚操作
    }// 针对可能为空的字段封装的类似于智能指针的类型
	template <typename T> 
	class nullable 
	{ 
		typedef T value_type; 
		T&       get (); 
		const T& get () const; 

		T*       operator-> (); 
		const T* operator-> () const; 

		T&       operator* (); 
		const T& operator* () const; 
	};
    
    // 针对查询结果所封装的容器类 
    template <typename T> 
    class result: result_base<T, class_traits<T>::kind> 
    { 
        result ();
        result (const result& r);
        iterator begin ();
        iterator end ();
        size_type size (); 
        bool empty ();
    };
    
	// 针对查询封装的条件类
	class LIBODB_EXPORT query_base 
	{ 
		explicit query_base (const std::string& native);
		const clause_type& clause ();
	};
	
	namespace mysql 
	{ 
		template <typename T> 
		class query: public query_base,
		public query_selector<T, id_mysql>::columns_type 
		{ 
			query (const std::string& q);
			query (const query_base& q); 
			query (bool v);
		};
	}     

	// 过滤条件类
    template <typename T> 
    class query<T, mysql::query_base>: public mysql::query<T>  
    { 
		query (bool v);
		query (const std::string& q);
		query (const mysql::query_base& q);
    } 
}

5.使用

  • Student.hpp
    #pragma once
    #include <string>
    #include <cstddef>
    #include <boost/date_time/posix_time/posix_time.hpp>
    #include <odb/nullable.hxx>
    #include <odb/core.hxx>
    
    #pragma db object // 声明一个类是数据库对象
    class Student
    {
    public:
        Student() {}
        Student(unsigned long sn, const std::string &name, 
    		    unsigned short age, unsigned long cid) 
            : _sn(sn)
            , _name(name)
            , _age(age)
            , _classes_id(cid) 
        {}
    
        void sn(unsigned long num) { _sn = num; }
        unsigned long sn() { return _sn; }
    
        void name(const std::string &name) { _name = name; }
        std::string name() { return _name; }
    
        void age(unsigned short num) { _age = num; }
        odb::nullable<unsigned short> age() { return _age; }
    
        void classes_id(unsigned long cid) { _classes_id = cid; }
        unsigned long classes_id() { return _classes_id; }
    
    private:
        // 将odb::access类作为Person类的友元
        // 这是使数据库支持代码可访问默认构造函数和数据成员所必需的
        friend class odb::access;
    
        // id: 标记成员变量为主键, auto: 值在插入时自动生成
        #pragma db id auto
        unsigned long _id;
    
        // unique: 指定变量或一组变量具有唯一键约束
        #pragma db unique
        unsigned long _sn;
        std::string _name;
        odb::nullable<unsigned short> _age;
    
        // 指定成员变量应该被索引
        #pragma db index
        unsigned long _classes_id;
    };
    
    #pragma db object
    class Classes
    {
    public:
        Classes() {}
        Classes(const std::string &name) 
            : _name(name) 
        {}
    
        void name(const std::string &name) { _name = name; }
        std::string name() { return _name; }
    
    private:
        friend class odb::access;
    
        #pragma db id auto
        unsigned long _id;
        std::string _name;
    };
    
    // 查询所有的学生信息, 并显示班级名称
    #pragma db view object(Student)\
                    object(Classes = classes : \
                    Student::_classes_id == classes::_id)\
                    query((?)) // 用于自定义查询函数
    struct Classes_Student
    {
        // 指定类成员映射到数据库表中的列名
        #pragma db column(Student::_id)
        unsigned long id;
        #pragma db column(Student::_sn)
        unsigned long sn;
        #pragma db column(Student::_name)
        std::string name;
        #pragma db column(Student::_age)
        odb::nullable<unsigned short> age;
        #pragma db column(classes::_name)
        std::string classes_name;
    };
    
    // 只查询学生姓名, (?): 外部调用时传入的过滤条件
    #pragma db view query("select name from Student" + (?))
    struct All_Name
    {
        std::string name;
    };
    
    // odb -d mysql --std c++11 --generate-query --generate-schema --profile boost/date-time student.hpp
    
  • main.cc
    #include <odb/database.hxx>
    #include <odb/mysql/database.hxx>
    #include <gflags/gflags.h>
    #include "student.hpp"
    #include "student-odb.hxx"
    
    DEFINE_string(host, "127.0.0.1", "Mysql服务器地址");
    DEFINE_int32(port, 0, "Mysql服务器端口");
    DEFINE_string(db, "TestDB", "数据库默认库名称");
    DEFINE_string(user, "root", "Mysql用户名");
    DEFINE_string(pwd, "SnowK8989", "Mysql密码");
    DEFINE_string(cset, "utf8", "Mysql客户端字符集");
    DEFINE_int32(max_pool, 3, "Mysql连接池最大连接数量");
    
    void Insert_Classes(odb::mysql::database& db)
    {
        try
        {
            // 3.获取事务对象, 开启事务
            odb::transaction trans(db.begin());
    
            Classes c1("Electronic 221");
            Classes c2("Electronic 222");
    
            db.persist(c1);
            db.persist(c2);
    
            // 5.提交事务
            trans.commit();
        }
        catch(const std::exception& e)
        {
            std::cout << "插入数据出错: " << e.what() << std::endl;
        }
    }
    
    void Insert_Student(odb::mysql::database &db)
    {
        try
        {
            // 3.获取事务对象, 开启事务
            odb::transaction trans(db.begin());
    
            Student s1(1, "张三", 18, 1);
            Student s2(2, "李四", 19, 1);
            Student s3(3, "王五", 18, 1);
            Student s4(4, "赵六", 15, 2);
            Student s5(5, "刘七", 18, 2);
            Student s6(6, "孙八", 23, 2);
            db.persist(s1);
            db.persist(s2);
            db.persist(s3);
            db.persist(s4);
            db.persist(s5);
            db.persist(s6);
    
            // 5. 提交事务
            trans.commit();
        }
        catch (const std::exception &e)
        {
            std::cout << "插入学生数据出错: " << e.what() << std::endl;
        }
    }
    
    // 先查询,再修改
    void Update_Student(odb::mysql::database &db, Student &stu)
    {
        try
        {
            // 3.获取事务对象, 开启事务
            odb::transaction trans(db.begin());
            db.update(stu);
    
            // 5. 提交事务
            trans.commit();
        }
        catch (const std::exception &e)
        {
            std::cout << "更新学生数据出错: " << e.what() << std::endl;
        }
    }
    
    // TODO
    Student Select_Student(odb::mysql::database &db)
    {
        Student ret;
        try
        {
            // 3.获取事务对象, 开启事务
            odb::transaction trans(db.begin());
    
            odb::result<Student> r(db.query<Student>(odb::query<Student>::name == "张三"));
            if (r.size() != 1)
            {
                std::cout << "数据量不对" << std::endl;
                return Student();
            }
    
            ret = *r.begin();
    
            // 5. 提交事务
            trans.commit();
        }
        catch (const std::exception &e)
        {
            std::cout << "更新学生数据出错: " << e.what() << std::endl;
        }
    
        return ret;
    }
    
    void Remove_Student(odb::mysql::database &db)
    {
        try
        {
            // 3.获取事务对象, 开启事务
            odb::transaction trans(db.begin());
    
            // 查询和删除操作合并
            db.erase_query<Student>(odb::query<Student>::name == "李四");
    
            // 5. 提交事务
            trans.commit();
        }
        catch (const std::exception &e)
        {
            std::cout << "更新学生数据出错: " << e.what() << std::endl;
        }
    }
    
    void Classes_Student(odb::mysql::database &db)
    {
        try
        {
            // 3.获取事务对象, 开启事务
            odb::transaction trans(db.begin());
    
            typedef odb::query<struct Classes_Student> query;
            typedef odb::result<struct Classes_Student> result;
            
            result r(db.query<struct Classes_Student>(query::classes::id == 1));
            for (auto it = r.begin(); it != r.end(); ++it)
            {
                std::cout << it->id << std::endl;
                std::cout << it->sn << std::endl;
                std::cout << it->name << std::endl;
                std::cout << *it->age << std::endl; // nullable类型类似智能指针, 需要解引用
                std::cout << it->classes_name << std::endl;
            }
    
            // 5. 提交事务
            trans.commit();
        }
        catch (const std::exception &e)
        {
            std::cout << "更新学生数据出错: " << e.what() << std::endl;
        }
    }
    
    void All_Student(odb::mysql::database &db)
    {
        try
        {
            // 3.获取事务对象, 开启事务
            odb::transaction trans(db.begin());
    
            typedef odb::query<Student> query;
            typedef odb::result<All_Name> result;
    
            result r(db.query<All_Name>(query::id == 1));
            for (auto it = r.begin(); it != r.end(); ++it)
            {
                std::cout << it->name << std::endl;
            }
    
            // 5. 提交事务
            trans.commit();
        }
        catch (const std::exception &e)
        {
            std::cout << "查询所有学生姓名数据出错: " << e.what() << std::endl;
        }
    }
    
    int main(int argc, char *argv[])
    {
        google::ParseCommandLineFlags(&argc, &argv, true);
    
        // 1.构造连接池工厂配置对象, 这里只能用unique_ptr
        auto cpf = std::make_unique<odb::mysql::connection_pool_factory>(FLAGS_max_pool, 0);
    
        // 2.构造数据库操作对象
        odb::mysql::database db(FLAGS_user, FLAGS_pwd, FLAGS_db, FLAGS_host, 
                                FLAGS_port, "", FLAGS_cset, 0, std::move(cpf));
    
        // 4.数据操作
        // Insert_Classes(db);
        // Insert_Student(db);
        // {
        //     Student stu = Select_Student(db);
        //     stu.age(22);
        //     Update_Student(db, stu);
        // }
        // Remove_Student(db);
        // Classes_Student(db);
        All_Student(db);
    
        return 0;
    }
    

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

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

相关文章

vulnhub-Web Developer 1靶机

vulnhub&#xff1a;Web Developer: 1 ~ VulnHub 导入靶机&#xff0c;放在kali同网段&#xff0c;扫描 靶机在192.168.114.129&#xff0c;扫描端口 有网站服务&#xff0c;访问 没什么东西&#xff0c;扫目录 真不少&#xff0c;访问一下&#xff0c;也只是一些普通的Wordpr…

【机器学习】智驭未来:探索机器学习在食品生产中的革新之路

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀目录 &#x1f50d;1. 引言&#xff1a;探索机器学习在食品生产中的革新之路&#x1f4d2;2. 机器学习在食品质量控制中的应用&#x1f31e;实…

Crypto虐狗记---”你“和小鱼(六)

前言&#xff1a;剧情六 提示&#xff1a; 下载 手动&#xff1a; 脚本&#xff1a;我不会 参考大佬&#xff1a; 转轮机加密详解两种解题方法 -攻防世界-CSDN博客 import re sss1: < ZWAXJGDLUBVIQHKYPNTCRMOSFE < 2: < KPBELNACZDTRXMJQOYHGVSFUWI < 3: < …

计算机的错误计算(一百一十五)

摘要 用错数定量解释计算机的错误计算&#xff08;一百一十四&#xff09;中的错误计算原因。 例1. 已知 计算 在 的错数&#xff0c;并与计算机的错误计算&#xff08;一百一十四&#xff09;中的相应错误数字个数做比较。 由 知&#xff0c; 再由 可得&#xff0c…

爬虫工程师必备工具——Postman和Fiddler的使用教程(11)

文章目录 1、工具获取2、基础使用教程2.1 Postman2.2 Fiddler2.2.1 简介2.2.2 工作原理2.2.3 功能设置2.2.4 使用方法1、工具获取 PostmanFiddler2、基础使用教程 2.1 Postman Postman是一款API调试工具,它简化了HTTP请求的构建、发送、响应查看以及测试流程,帮助开发人员高…

No.9 笔记 | PHP学习指南:从入门到精通的要点总结

一、PHP概述 1. Web技术基础 Web&#xff1a;由互相链接的超文本文件组成的系统URL&#xff1a;定位Web资源的地址HTTP&#xff1a;Web数据交换协议架构类型&#xff1a;B/S&#xff08;浏览器/服务器&#xff09;和C/S&#xff08;客户端/服务器&#xff09; 2. PHP简介 定…

无法加载响应数据: No data found for resourcewith given identifier

背景 学习黑马2022Redis教程&#xff0c;在开发P78达人探店功能&#xff0c;重新在前端登录的时候发现&#xff0c;所有的请求都需要发两遍才能成功。 失败的请求报错&#xff1a; 无法加载响应数据: No data found for resourcewith given identifier 排查 因为用到nginx,…

No.8 笔记 | SQL 查询语句:数据探索的钥匙

2024/10/7 心记 - 致在路上默默奋斗的你 在当今数字化的时代&#xff0c;网络安全已成为我们生活中不可或缺的一部分。它如同守护数字世界的隐形盾牌&#xff0c;保护着我们的隐私、数据和整个社会的稳定运行。 学习网络安全&#xff0c;是踏上一段充满挑战与机遇的征程。 每一…

Pytorch实现心跳信号分类识别(支持LSTM,GRU,TCN模型)

Pytorch实现心跳信号分类识别(支持LSTM,GRU,TCN模型&#xff09; 目录 Pytorch实现心跳信号分类识别(支持LSTM,GRU,TCN模型&#xff09; 1. 项目说明 2. 数据说明 &#xff08;1&#xff09;心跳信号分类预测数据集 3. 模型训练 &#xff08;1&#xff09;项目安装 &am…

查缺补漏----IP通信过程

1.DHCP协议 H3刚接入网络时&#xff0c;只知道自己的MAC地址&#xff0c;所以需要通过DHCP协议请求自己的IP地址。 通过DHCP协议&#xff0c;得到IP地址、子网掩码、网关与DNS服务器IP地址。 DHCP协议是应用层协议(传输层为UDP)&#xff0c;请求报文是广播&#xff08;H3不知…

深入了解Python:那些常被忽略的知识点

作为现代编程语言的典范&#xff0c;Python以其简洁、高效和广泛的应用领域赢得了无数开发者的青睐。然而&#xff0c;即使是经验丰富的Python程序员&#xff0c;也可能不了解Python的一些特性或最佳实践。这篇文章将介绍Python中常被忽略的一些知识点&#xff0c;通过全面的分…

图文深入理解Oracle DB Scheduler

值此国庆佳节&#xff0c;深宅家中&#xff0c;闲来无事&#xff0c;就多写几篇博文。今天继续宅继续写。本篇图文深入介绍Oracle DB Scheduler。 Oracle为什么要使Scheduler&#xff1f; 答案就是6个字&#xff1a;简化管理任务。 • Scheduler&#xff08;调度程序&#x…

代码随想录训练营Day26 | 669. 修剪二叉搜索树 | 108.将有序数组转换为二叉搜索树 | 538.把二叉搜索树转换为累加树

学习文档&#xff1a;代码随想录 (programmercarl.com) Leetcode 669. 修剪二叉搜索树 题目描述 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[low, high]中。修剪树 不应该 改变保留…

o1-preview 在 IMO 2024 第一题的实测表现

相关博客&#xff1a;Learning to Reason with LLMs 以及 Introducing OpenAI o1-preview 测试了 IMO 2024 的第一题&#xff0c;OpenAI-o1-preview 的解题过程包括两部分&#xff1a;思考和推理。 正确答案是全体偶数&#xff0c;o1-preview 的 **思考方向正确&#xff0c;推…

计算机网络——email

pop3拉出来 超出ASCII码范围就不让传了 这样就可以传更大的文件

Linux命令大全及小例子

撰写一份关于Linux命令大全的详尽报道和分析是一项重要的任务&#xff0c;旨在让读者全面了解Linux命令的用途和应用场景。Linux系统因其强大的命令行工具而闻名&#xff0c;无论是系统管理、文件操作还是网络配置&#xff0c;Linux命令行都提供了灵活且强大的解决方案。以下是…

【模板进阶】std::void_t

一、 s t d : : v o i d _ t std::void\_t std::void_t的源码分析和常规范例 1. s t d : : v o i d _ t 1.std::void\_t 1.std::void_t的源码分析 C 17 C17 C17引入了 s t d : : v o i d _ t std::void\_t std::void_t&#xff0c;它其实是一个别名模板&#xff0c;源码非常简…

如何为树莓派安装操作系统,以及远程操控树莓派的两种方法,无线操控和插网线操控

文章目录 一、下载树莓派的系统二、将文件下载到SD卡中1.使用官方软件2.其他选择 三、远程连接电脑安装vnc-viewer1.无线操作&#xff08;配置树莓派&#xff0c;开启VNC&#xff09;电脑远程配置2.有线连接&#xff08;需要一根网线&#xff09; 总结 一、下载树莓派的系统 下…

github学生认证(Github Copilot)

今天想配置一下Github Copilot&#xff0c;认证学生可以免费使用一年&#xff0c;认证过程中因为各种原因折腾了好久&#xff0c;记录一下解决方法供大家参考。 p.s.本文章只针对Github学生认证部分遇到的问题及解决方法&#xff0c;不包括配置copilot的全部流程~ 1、准备工作…

【python实操】python小程序之定义类

引言 python小程序之定义类 文章目录 引言一、定义类1.1 题目1.2 代码1.3 代码解释 二、思考2.1 面向对象编程&#xff08;OOP&#xff09;原则2.2 self 参数2.3 内存地址2.4 代码的可读性和可维护性 一、定义类 1.1 题目 小猫爱吃鱼&#xff0c;小猫要喝水&#xff0c;定义不…