2-1.Jetpack 之 Room 简单编码模板(Entity、DAO、Database、Repository)

一、Room

1、Room 概述
  • Navigation 是 Jetpack 中的一个重要成员,它是一个持久化库,它为管理数据库提供了简单强大的方法
2、Room 引入
  • 在模块级 build.gradle 中引入相关依赖
implementation "androidx.room:room-runtime:2.2.5"
annotationProcessor "androidx.room:room-compiler:2.2.5"

二、Room 简单案例

1、Application
  • MyApplication.java
package com.my.room.application;import android.app.Application;
import android.content.Context;public class MyApplication extends Application {public static final String TAG = MyApplication.class.getSimpleName();private static Context context;@Overridepublic void onCreate() {super.onCreate();context = this;}public static Context getContext() {return context;}
}
2、Entity
  • User.java
package com.my.room.entity;import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;@Entity(tableName = "User")
public class User {@PrimaryKey(autoGenerate = true)public Long id;@ColumnInfo(name = "name")public String name;@ColumnInfo(name = "age")public Integer age;@Overridepublic String toString() {return "User{" +"id=" + id +", name='" + name + '\'' +", age=" + age +'}';}
}
3、DAO
  • UserDAO.java
package com.my.room.dao;import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;import com.my.room.entity.User;import java.util.List;@Dao
public interface UserDAO {@Insertvoid insert(User user);@Deletevoid delete(User user);@Updatevoid update(User user);@Query("SELECT * FROM User")List<User> queryAll();
}
4、Database
package com.my.room.database;import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;import com.my.room.application.MyApplication;
import com.my.room.dao.UserDAO;
import com.my.room.entity.User;@Database(entities = {User.class}, version = 1, exportSchema = false)
public abstract class MyDatabase extends RoomDatabase {public static final String TAG = MyDatabase.class.getSimpleName();public static final String DATABASE_NAME = "test.db";private static MyDatabase myDatabase;public static MyDatabase getInstance() {if (myDatabase == null) {myDatabase = Room.databaseBuilder(MyApplication.getContext(), MyDatabase.class, DATABASE_NAME).build();}return myDatabase;}public abstract UserDAO getUserDAO();
}
5、Repository Observer
  1. InsertObserver.java
package com.my.room.repository.observer;public interface InsertObserver {void onSuccess();void onError(String msg);
}
  1. DeleteObserver.java
package com.my.room.repository.observer;public interface DeleteObserver {void onSuccess();void onError(String msg);
}
  1. UpdateObserver.java
package com.my.room.repository.observer;public interface UpdateObserver {void onSuccess();void onError(String msg);
}
  1. QueryAllObserver.java
package com.my.room.repository.observer;import java.util.List;public interface QueryAllObserver<T> {void onResult(List<T> ts);
}
6、Repository
  • UserRepository.java
package com.my.room.repository;import android.os.AsyncTask;
import android.os.Handler;import com.my.room.dao.UserDAO;
import com.my.room.database.MyDatabase;
import com.my.room.entity.User;
import com.my.room.repository.observer.DeleteObserver;
import com.my.room.repository.observer.InsertObserver;
import com.my.room.repository.observer.QueryAllObserver;
import com.my.room.repository.observer.UpdateObserver;import java.util.List;public class UserRepository {private MyDatabase myDatabase;private UserDAO userDAO;private Handler handler;public UserRepository() {myDatabase = MyDatabase.getInstance();userDAO = myDatabase.getUserDAO();handler = new Handler();}// ====================================================================================================public void insert(User user, InsertObserver insertObserver) {new InsertAsyncTask(user, insertObserver).execute();}public void delete(User user, DeleteObserver deleteObserver) {new DeleteAsyncTask(user, deleteObserver).execute();}public void update(User user, UpdateObserver updateObserver) {new UpdateAsyncTask(user, updateObserver).execute();}public void queryAll(QueryAllObserver<User> queryAllObserver) {new QueryAllAsyncTask(queryAllObserver).execute();}// ====================================================================================================private class InsertAsyncTask extends AsyncTask<Void, Void, Void> {private User user;private InsertObserver insertObserver;public InsertAsyncTask(User user, InsertObserver insertObserver) {this.user = user;this.insertObserver = insertObserver;}@Overrideprotected Void doInBackground(Void... voids) {try {userDAO.insert(user);if (insertObserver != null) handler.post(() -> insertObserver.onSuccess());} catch (Exception e) {e.printStackTrace();if (insertObserver != null)handler.post(() -> insertObserver.onError(e.getMessage()));}return null;}}private class DeleteAsyncTask extends AsyncTask<Void, Void, Void> {private User user;private DeleteObserver deleteObserver;public DeleteAsyncTask(User user, DeleteObserver deleteObserver) {this.user = user;this.deleteObserver = deleteObserver;}@Overrideprotected Void doInBackground(Void... voids) {try {userDAO.delete(user);if (deleteObserver != null) handler.post(() -> deleteObserver.onSuccess());} catch (Exception e) {e.printStackTrace();if (deleteObserver != null)handler.post(() -> deleteObserver.onError(e.getMessage()));}return null;}}private class UpdateAsyncTask extends AsyncTask<Void, Void, Void> {private User user;private UpdateObserver updateObserver;public UpdateAsyncTask(User user, UpdateObserver updateObserver) {this.user = user;this.updateObserver = updateObserver;}@Overrideprotected Void doInBackground(Void... voids) {try {userDAO.update(user);if (updateObserver != null) handler.post(() -> updateObserver.onSuccess());} catch (Exception e) {e.printStackTrace();if (updateObserver != null)handler.post(() -> updateObserver.onError(e.getMessage()));}return null;}}private class QueryAllAsyncTask extends AsyncTask<Void, Void, Void> {private QueryAllObserver<User> queryAllObserver;public QueryAllAsyncTask(QueryAllObserver<User> queryAllObserver) {this.queryAllObserver = queryAllObserver;}@Overrideprotected Void doInBackground(Void... voids) {try {List<User> users = userDAO.queryAll();handler.post(() -> queryAllObserver.onResult(users));} catch (Exception e) {handler.post(() -> queryAllObserver.onResult(null));}return null;}}
}
7、Activity Layout
  • activity_user.java
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".UserActivity"tools:ignore="MissingConstraints"><Buttonandroid:id="@+id/btn_insert"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text=""app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><Buttonandroid:id="@+id/btn_delete"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text=""app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.498"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/btn_insert" /><Buttonandroid:id="@+id/btn_update"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text=""app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.498"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/btn_delete" /><Buttonandroid:id="@+id/btn_query_all"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text=""app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.498"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/btn_update" />
</androidx.constraintlayout.widget.ConstraintLayout>
8、Activity Code
  • UserActivity.java
package com.my.room;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.util.Log;
import android.widget.Button;import com.my.room.entity.User;
import com.my.room.repository.UserRepository;
import com.my.room.repository.observer.DeleteObserver;
import com.my.room.repository.observer.InsertObserver;
import com.my.room.repository.observer.UpdateObserver;public class UserActivity extends AppCompatActivity {public static final String TAG = UserActivity.class.getSimpleName();private UserRepository userRepository;private Button btnInsert;private Button btnDelete;private Button btnUpdate;private Button btnQueryAll;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_user);userRepository = new UserRepository();btnInsert = findViewById(R.id.btn_insert);btnDelete = findViewById(R.id.btn_delete);btnUpdate = findViewById(R.id.btn_update);btnQueryAll = findViewById(R.id.btn_query_all);btnInsert.setOnClickListener(v -> {User user = new User();user.name = "jack";user.age = 20;userRepository.insert(user, new InsertObserver() {@Overridepublic void onSuccess() {Log.i(TAG, "------------------------------ insert success");}@Overridepublic void onError(String msg) {Log.i(TAG, "------------------------------ insert error - " + msg);}});});btnDelete.setOnClickListener(v -> {User user = new User();user.id = 1L;userRepository.delete(user, new DeleteObserver() {@Overridepublic void onSuccess() {Log.i(TAG, "------------------------------ delete success");}@Overridepublic void onError(String msg) {Log.i(TAG, "------------------------------ delete error - " + msg);}});});btnUpdate.setOnClickListener(v -> {User user = new User();user.id = 1L;user.name = "jack";user.age = 30;userRepository.update(user, new UpdateObserver() {@Overridepublic void onSuccess() {Log.i(TAG, "------------------------------ update success");}@Overridepublic void onError(String msg) {Log.i(TAG, "------------------------------ update error - " + msg);}});});btnQueryAll.setOnClickListener(v -> {userRepository.queryAll(users -> {if (users == null) {Log.i(TAG, "------------------------------ queryAll - users is null");return;}if (users.size() == 0) {Log.i(TAG, "------------------------------ queryAll - users is empty");return;}for (User user : users)Log.i(TAG, "------------------------------ queryAll - " + user);});});}
}
Test
  • 增 -> 改 -> 查 -> 删 -> 查,输出结果
I/UserActivity: ------------------------------ insert success
I/UserActivity: ------------------------------ update success
I/UserActivity: ------------------------------ queryAll - User{id=1, name='jack', age=30}
I/UserActivity: ------------------------------ delete success
I/UserActivity: ------------------------------ queryAll - users is empty

三、Room 简单案例解析

1、Entity 解析
@Entity(tableName = "User")
public class User {@PrimaryKey(autoGenerate = true)public Long id;@ColumnInfo(name = "name")public String name;@ColumnInfo(name = "age")public Integer age;@Overridepublic String toString() {return "User{" +"id=" + id +", name='" + name + '\'' +", age=" + age +'}';}
}
  • @Entity(tableName = "User"):指定 User 类为 Room 数据库中 User 表对应的实体类
  1. @PrimaryKey(autoGenerate = true):指定 id 字段为主键,并且它的值是自动生成的

  2. @ColumnInfo(name = "name"):指定 name 字段映射到表中的 name 列,@ColumnInfo(name = "age") 同理

  • User 表会在 APP 首次安装时由 Room 根据 User 类创建,SQL 语句如下
CREATE TABLE IF NOT EXISTS User (id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT,age INTEGER
);
2、DAO 解析
@Dao
public interface UserDAO {@Insertvoid insert(User user);@Deletevoid delete(User user);@Updatevoid update(User user);@Query("SELECT * FROM User")List<User> queryAll();
}
  • @Dao:指定 UserDAO 接口与 Room 数据库进行交互,以操作 User 类,该接口使用 Room 相关注解来定义操作方法
  1. @Insert:插入数据,这里传递一个 User 对象作为参数,Room 将这个对象插入到数据库中

  2. @Delete:删除数据,这里传递一个 User 对象作为参数,Room 基于该对象的 id 字段来删除相应的行

  3. @Update:修改数据,这里传递一个 User 对象作为参数,Room 基于该对象的 id 字段来修改相应的行

  4. @Query("SELECT * FROM User"):查询数据,查询表中的所有行

3、Database 解析
@Database(entities = {User.class}, version = 1, exportSchema = false)
public abstract class MyDatabase extends RoomDatabase {public static final String TAG = MyDatabase.class.getSimpleName();public static final String DATABASE_NAME = "test.db";private static MyDatabase myDatabase;public static MyDatabase getInstance() {if (myDatabase == null) {myDatabase = Room.databaseBuilder(MyApplication.getContext(), MyDatabase.class, DATABASE_NAME).build();}return myDatabase;}public abstract UserDAO getUserDAO();
}
(1)注解解析
  • @Database:指定 MyDatabase 抽象类为 Room 数据库
  1. entities = {User.class}:指定这个数据库包含 User 类

  2. version = 1:指定数据库的版本号,当实体或数据库结构发生变化时,需要增加这个版本号

  3. exportSchema = false:指定不导出数据库的 schema

(2)思路解析
  1. 单例模式确保整个应用程序中只有一个 MyDatabase 实例对象

  2. 通过 Room.databaseBuilder 方法构建数据库,该方法需要三个参数,分别为上下文、数据库类、数据库名称

  3. 定义获取 UserDao 实例对象的抽象方法,Room 将自动生成这个方法的实现

4、Repository 解析
public class UserRepository {private MyDatabase myDatabase;private UserDAO userDAO;private Handler handler;public UserRepository() {myDatabase = MyDatabase.getInstance();userDAO = myDatabase.getUserDAO();handler = new Handler();}// ====================================================================================================public void insert(User user, InsertObserver insertObserver) {new InsertAsyncTask(user, insertObserver).execute();}public void delete(User user, DeleteObserver deleteObserver) {new DeleteAsyncTask(user, deleteObserver).execute();}public void update(User user, UpdateObserver updateObserver) {new UpdateAsyncTask(user, updateObserver).execute();}public void queryAll(QueryAllObserver<User> queryAllObserver) {new QueryAllAsyncTask(queryAllObserver).execute();}// ====================================================================================================private class InsertAsyncTask extends AsyncTask<Void, Void, Void> {private User user;private InsertObserver insertObserver;public InsertAsyncTask(User user, InsertObserver insertObserver) {this.user = user;this.insertObserver = insertObserver;}@Overrideprotected Void doInBackground(Void... voids) {try {userDAO.insert(user);if (insertObserver != null) handler.post(() -> insertObserver.onSuccess());} catch (Exception e) {e.printStackTrace();if (insertObserver != null)handler.post(() -> insertObserver.onError(e.getMessage()));}return null;}}private class DeleteAsyncTask extends AsyncTask<Void, Void, Void> {private User user;private DeleteObserver deleteObserver;public DeleteAsyncTask(User user, DeleteObserver deleteObserver) {this.user = user;this.deleteObserver = deleteObserver;}@Overrideprotected Void doInBackground(Void... voids) {try {userDAO.delete(user);if (deleteObserver != null) handler.post(() -> deleteObserver.onSuccess());} catch (Exception e) {e.printStackTrace();if (deleteObserver != null)handler.post(() -> deleteObserver.onError(e.getMessage()));}return null;}}private class UpdateAsyncTask extends AsyncTask<Void, Void, Void> {private User user;private UpdateObserver updateObserver;public UpdateAsyncTask(User user, UpdateObserver updateObserver) {this.user = user;this.updateObserver = updateObserver;}@Overrideprotected Void doInBackground(Void... voids) {try {userDAO.update(user);if (updateObserver != null) handler.post(() -> updateObserver.onSuccess());} catch (Exception e) {e.printStackTrace();if (updateObserver != null)handler.post(() -> updateObserver.onError(e.getMessage()));}return null;}}private class QueryAllAsyncTask extends AsyncTask<Void, Void, Void> {private QueryAllObserver<User> queryAllObserver;public QueryAllAsyncTask(QueryAllObserver<User> queryAllObserver) {this.queryAllObserver = queryAllObserver;}@Overrideprotected Void doInBackground(Void... voids) {try {List<User> users = userDAO.queryAll();handler.post(() -> queryAllObserver.onResult(users));} catch (Exception e) {handler.post(() -> queryAllObserver.onResult(null));}return null;}}
}
  • UserRepository 类是对 userDAO 的封装,封装的主要目的是异步任务处理
(1)异步任务处理
  • 对于每种 UserDAO 实例对象的操作都定义了一个继承 AsyncTask 的内部类,它用于安排操作在后台线程中执行,然后使用观察者模式来通知调用者
  1. InsertAsyncTask:负责在后台线程中执行插入操作,完成后(无论成功还是失败)通过 InsertObserver 通知调用者

  2. DeleteAsyncTask:负责在后台线程中执行删除操作,完成后(无论成功还是失败)通过 DeleteObserver 通知调用者

  3. UpdateAsyncTask:负责在后台线程中执行插入操作,完成后(无论成功还是失败)通过 UpdateObserver 通知调用者

  4. QueryAllAsyncTask:负责在后台线程中执行查询操作,完成后(无论成功还是失败)通过 QueryAllObserver 通知调用者

(2)补充
  1. 线程调度:数据库操作不能在 UI 线程执行,操作在后台线程中执行完成后,使用 Handler 来回到 UI 线程执行后续操作

  2. 异常处理:在异步任务种,捕获可能抛出的异常,例如,执行插入操作时主键冲突会抛出异常

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

The NCCoE’s Automation of the CMVP

Earlier today at the ICMC24, we heard from a panel about the US National Cybersecurity Center of Excellence’s (NCCoE) work on the Automated Cryptographic Module Validation Program (ACMVP), which intends to tackle the troublingly long queue times we’ve se…

Flink 与 Kubernetes (K8s)、YARN 和 Mesos集成对比

Flink 与 Kubernetes (K8s)、YARN 和 Mesos 的紧密集成&#xff0c;是 Flink 能够在不同分布式环境中高效运行的关键特性。 Flink 提供了与这些资源管理系统的深度集成&#xff0c;以便在多种集群管理环境下提交、运行和管理 Flink 作业。Flink 与 K8s、YARN 和 Mesos 集成的详…

百度Android IM SDK组件能力建设及应用

作者 | 星途 导读 移动互联网时代&#xff0c;随着社交媒体、移动支付、线上购物等行业的快速发展&#xff0c;对即时通讯功能的需求不断增加。对于各APP而言&#xff0c;接入IM SDK&#xff08;即时通讯软件开发工具包&#xff09;能够大大降低开发成本、提高开发效率&#…

数据结构:(OJ141)环形列表

给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置&#xff08;…

C++ | Leetcode C++题解之第420题强密码检验器

题目&#xff1a; 题解&#xff1a; class Solution { public:int strongPasswordChecker(string password) {int n password.size();bool has_lower false, has_upper false, has_digit false;for (char ch: password) {if (islower(ch)) {has_lower true;}else if (isu…

渗透测试综合靶场 DC-2 通关详解

一、准备阶段 准备工具如Kali Linux&#xff0c;下载并设置DC-2靶场机。确保攻击机和靶机在同一网络段&#xff0c;通常设置为桥接模式或NAT模式。 1.1 靶机描述 Much like DC-1, DC-2 is another purposely built vulnerable lab for the purpose of gaining experience in …

面试知识点总结篇二

一、makefile链接库参数 LIBS -L/path/to/lib -lmylib//&#xff0c;-lmylib会链接名为libmylib.so或libmylib.a的库。all: myprogrammyprogram: myprogram.ogcc -o myprogram myprogram.o $(LIBS)//此处使用myprogram.o: myprogram.cgcc -c myprogram.c二、shell指令 Shell…

高性能分布式搜索引擎Elasticsearch详解

♥️作者&#xff1a;小宋1021 &#x1f935;‍♂️个人主页&#xff1a;小宋1021主页 ♥️坚持分析平时学习到的项目以及学习到的软件开发知识&#xff0c;和大家一起努力呀&#xff01;&#xff01;&#xff01; &#x1f388;&#x1f388;加油&#xff01; 加油&#xff01…

在线相亲交友系统:寻找另一半的新方式

在这个快节奏的时代里&#xff0c;越来越多的单身男女发现&#xff0c;传统意义上的相亲方式已经难以满足他们的需求。与此同时&#xff0c;互联网技术的迅猛发展为人们提供了新的社交渠道——在线相亲交友系统作者h17711347205。本文将探讨在线相亲交友系统如何成为一种寻找另…

MYSQL基础语法

1-什么是数据库 数据库就是保留数据的仓库&#xff0c;体现在电脑当中&#xff0c;是一个软件或者是文件系统。然后把这些数据都保存在特殊的文件中&#xff0c;然后使用固定的语言&#xff08;SQL语句&#xff09;去操作文件中的数据。 2-数据库的优点 数据库是按照特定的格…

Spring MVC 基本配置步骤 总结

1.简介 本文记录Spring MVC基本项目拉起配置步骤。 2.步骤 在pom.xml中导入依赖&#xff1a; <dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>6.0.6</version><scope>…

Activiti7《第九式:破气式》——流畅驱动工作流进程。面试题大全

冲冲冲&#xff01;开干 这篇文章将分为九个篇章&#xff0c;带你逐步掌握工作流的核心知识。“破气式”&#xff0c;代表着工作流中的 无形之力&#xff0c;它是贯穿整个流程的 关键驱动 不知不觉已经到了独孤九剑最后一式了&#xff0c;我相信到这里之后各位都已经出神入化…

成功使用DDNS动态域名访问我的群晖NAS(TP-link路由器)

当NAS设备部署在动态IP环境中&#xff08;如家庭或小型办公室宽带&#xff09;&#xff0c;远程访问常常受到IP地址频繁变动的困扰。为了解决这一问题&#xff0c;结合神卓互联NAS公网助手提供的DDNS&#xff08;动态域名服务&#xff09;功能&#xff0c;我们可以轻松实现通过…

EasyGBD国标GB28181设备端,支持GB28181-2016、GB28181-2022

功能概要&#xff1a; 功能概述&#xff1a;EasyGBD是GB/T28181 Device的简称&#xff0c;指国标GB28181协议的设备端。EasyGBD功能组件支持Windows、Linux、Android、iOS、ARM等所有平台&#xff0c;可兼容国标GB28181-2011、GB28181-2016的全部功能。 操作系统&#xff1a;任…

医院监护病房智慧ICU远程探视双向对讲为医院带来什么?

随着信息技术的进步和社会对医疗服务要求的不断提高&#xff0c;医院在努力提升服务质量的同时&#xff0c;也在积极寻求更科学有效的管理手段。全视通智慧医院解决方案下有十几个业务系统&#xff0c;主要专注于医院信息化系统&#xff0c;针对于智慧门诊、智慧病房、智慧手术…

玩转腾讯混元大模型——带您解读各个功能

自从2022年的OpenAI公司推出chatGPT人工智能聊天机器人&#xff0c;从此人工智能大模型便在各国可所谓风靡一时&#xff0c;不断涌现出各种各样的大模型&#xff0c;深得用户喜爱。然而在此领域中&#xff0c;腾讯也研发出了自己的大语言模型&#xff0c;下面我们一起来了解一下…

C#基础(11)函数重载

前言 前面我们已经完成了ref和out补充知识点的学习&#xff0c;以及函数参数相关的学习&#xff0c;今天便再次为函数补充一个知识点&#xff1a;函数重载。 函数重载是指在同一个作用域中&#xff0c;可以有多个同名函数&#xff0c;但参数列表不同。它的发展可以追溯到早期…

一.python入门

gyp的读研日记&#xff0c;哈哈哈哈&#xff0c;&#x1f642;&#xff0c;从复习python开始&#xff0c; 目录 1.python入门 1.1 Python说明书 1.2 Python具备的功能 1.3 学习前提 1.4 何为Python 1.5 编程语言 2.Python环境搭建 2.1 开发环境概述 2.2 Python的安装与…

【开发心得】筑梦上海:项目风云录(5)

写这个长篇的目的&#xff0c;前文已经说过。就这个目的而言&#xff0c;这里会更多的讲项目中存在的风险和应对&#xff0c;假如你正在做项目或者打算从事软件项目管理&#xff0c;可以一起交流讨论一下。 目录 小娇的离去 管人的大忌 理解甲方的立场 时刻表的诞生 未完…

dotnet4.0编译问题

因为最近在写cobaltstrike的execute-assembly内存加载的c#项目 用visual studio2022编译&#xff0c;最低net只能用6.0版本的&#xff0c;并且execute-assembly不支持 我想使用4.x版本进行编译&#xff0c;因为visual studio不支持&#xff0c;那么使用命令行进行编译 因为要用…