Android Room数据库如何使用增删改查

news2025/1/15 6:21:52

先看运行效果图。
在这里插入图片描述
1.在app下的build.gradle。在dependencies{}闭包中添加如下依赖

//room
    def room_version = "2.3.0"
    implementation "androidx.room:room-runtime:$room_version"
    annotationProcessor "androidx.room:room-compiler:$room_version"

完整的内容如下

plugins {
    id 'com.android.application'
}

android {
    namespace 'com.example.myapplication001'
    compileSdk 32

    defaultConfig {
        applicationId "com.xfjlfile.app"
        minSdk 21
        targetSdk 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

        ndk {
            // 设置支持的SO库架构
            abiFilters 'armeabi' //, 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a'
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

}

dependencies {

    implementation 'androidx.appcompat:appcompat:1.4.1'
    implementation 'com.google.android.material:material:1.5.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    
    //room。在这里写上你的依赖
    def room_version = "2.3.0"
    implementation "androidx.room:room-runtime:$room_version"
    annotationProcessor "androidx.room:room-compiler:$room_version"

}

点击Sync进行同步一下。
2.注解使用

注解使用,Room使用很简单的,这里有三个基本的使用注解,
@Database@Entity@Dao。分别对于数据库、表、表的具体操作(增删改查)。

例如创建一个数据表User。创建User类。代码内容如下

import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;

//这是一个实体类对象。
//@Entity就是表示数据库中的表。用这个来注解,一定要写的
@Entity
public class User {

    //主键id,自增长
    @PrimaryKey(autoGenerate = true)
    @NonNull
    public int id;

    //用户名
    @ColumnInfo(name = "user_name", defaultValue = "")
    public String userName;

    //用户年龄
    @ColumnInfo(name = "user_age")
    public int userAge;

    //用户别称
    @ColumnInfo(name = "nick_name")
    public String nickName;

    //用户地址
    @ColumnInfo(name = "address")
    public String address;

    public User(String userName, int userAge, String nickName, String address) {
        this.id = id;
        this.userName = userName;
        this.userAge = userAge;
        this.nickName = nickName;
        this.address = address;
    }

    public int getId() {
        return this.id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUserName() {
        return this.userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public int getUserAge() {
        return this.userAge;
    }

    public void setUserAge(int userAge) {
        this.userAge = userAge;
    }

    public String getNickName() {
        return this.nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }

    public String getAddress() {
        return this.address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

}
这个类很平常,主要是注解的说明,这个@Entity就是表示数据库中的表,
User类对应就是User表,@PrimaryKey表示主键,这里是id,
autoGenerate = true 是自增,@NonNull表示不为空。 
@ColumnInfo表示表中的列名,name = "user_name"表示列名的值。

Room是对象关系映射型数据库,所以你可以不用写这个@ColumnInfo注解,
写它主要是为了设置列名,不写则使用变量名做为列名。

假设我一个表中有30个字段,实际上用到的只有5个,
那么另外25个就不需要进行创建了,则使用@Ignore注解进行忽略。
例如这样。看如下内容

    @Ignore
    @ColumnInfo(name = "address")
    public String address;

创建UserDao类,代码如下

import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import androidx.room.Update;

import java.util.List;

//@Dao就是表的具体操作(增删改查)。用这个来注解,一定要写的
@Dao
public interface UserDao {

    /**
     * 增加
     *
     * @param users 用户
     */
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insertUser(User... users);


    /**
     * 查询所有用户
     * @return 用户列表
     */
    @Query("SELECT * FROM user")
    List<User> queryAll();

    /**
     * 按用户名查询
     * @param userName 用户名
     * @return 用户
     */
   // @Query("SELECT * FROM user WHERE user_name LIKE :userName LIMIT 1")//这里有两种写法。都可以
    @Query("SELECT * FROM user WHERE user_name= :userName")
    User findByName(String userName);

    /**
     * 按用户年龄查询
     * @param user_Age 用户年龄
     * @return 用户
     */
    // @Query("SELECT * FROM user WHERE user_name LIKE :userName LIMIT 1")//这里有两种写法。都可以
    @Query("SELECT * FROM user WHERE user_age= :user_Age")
    User findByAge(String user_Age);

    /**
     * 按条件查询
     * @param userName 用户名称
     * @param user_Age 用户年龄
     * @param address  用户地址
     * @return 用户
     */
    // @Query("SELECT * FROM user WHERE user_name LIKE :userName LIMIT 1")//这里有两种写法。都可以
    @Query("SELECT * FROM user WHERE user_name= :userName and user_age= :user_Age and address= :address")
    User findByAll(String userName,int user_Age,String address);

    /**
     * 修改
     * @param user 根据用户进行修改
     */
    @Update
    void update(User user);

    /**
     * 删除
     * @param user 根据用户进行删除
     */
    @Delete
    void delete(User user);

    //删除整张表的数据
    @Query("DELETE FROM user")
    void deleteAll();

}

UserDao是一个接口,主要是定义了一些方法,通过注解在编译的时候会生成实现类。
下面是数据库的创建,新建一个MyDatabase类,继承RoomDatabase,代码如下

import androidx.room.Database;
import androidx.room.RoomDatabase;

//@Database对应数据库。用这个来注解,一定要写的
@Database(entities = {User.class}, version = 1, exportSchema = false)
public abstract class MyDatabase extends RoomDatabase {
    public abstract UserDao userDao();
}

这里的@Database注解表示这个类是用来操作数据库的,entities = {User.class}表示当前数据库中的表,只有一个User表,多的表用英文逗号隔开。version = 1表示数据库的版本,可以做数据库的升级操作。

注意这是一个抽象类,在编译时Room会帮助构建实现类。

现在运行一下,手机或者模拟器都可以。然后什么都不用去做。会出现如下图内容
在这里插入图片描述
可以查看到,MyDatabase和UserDao的实现类都自动生成了。
3.主活动MainActivity2类。代码内容如下

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.sqlite.db.SupportSQLiteDatabase;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.example.myapplication001.R;

import java.util.ArrayList;
import java.util.List;


public class MainActivity2 extends AppCompatActivity {

    private MyDatabase db;
    private List<User> mList = new ArrayList<>();
    HomeAdapter homeAdapter;

    @SuppressLint({"MissingInflatedId", "WrongViewCast"})
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        initView();

    }

    /**
     * 初始化
     */
    private void initView() {
        //列表
        RecyclerView rv = findViewById(R.id.rv);
        homeAdapter = new HomeAdapter(getApplicationContext(),mList);
        rv.setLayoutManager(new LinearLayoutManager(this));
        rv.setAdapter(homeAdapter);
        //初始化数据库
        initDB();
        
        findViewById(R.id.btn_add).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity2.this, "用户点击了新增所有", Toast.LENGTH_SHORT).show();
                addUser();
            }
        });
        
        findViewById(R.id.btn_add_yg).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity2.this, "用户点击了新增一个用户", Toast.LENGTH_SHORT).show();
                addUser_yg();
            }
        });

        findViewById(R.id.btn_delete).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity2.this, "用户点击了删除所有", Toast.LENGTH_SHORT).show();
                deleteAll();
            }
        });
        
        findViewById(R.id.btn_sc_mc).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity2.this, "用户点击了删除用户名", Toast.LENGTH_SHORT).show();
                deleteUser();
            }
        });
        
        findViewById(R.id.btn_update).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity2.this, "用户点击了修改", Toast.LENGTH_SHORT).show();
                updateUser();
            }
        });
        
        findViewById(R.id.btn_query).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity2.this, "用户点击了查询所有", Toast.LENGTH_SHORT).show();
                queryAll();
            }
        });
        
        findViewById(R.id.btn_cx).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity2.this, "用户点击了查询名称", Toast.LENGTH_SHORT).show();
                query_dg();
            }
        });
        
        findViewById(R.id.btn_nl).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity2.this, "用户点击了查询年龄", Toast.LENGTH_SHORT).show();
                query_nl();
            }
        });
        
        findViewById(R.id.btn_tj).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity2.this, "用户点击了按条件查询", Toast.LENGTH_SHORT).show();
                query_tj();
            }
        });
    }
    
    /**
     * 初始化数据库
     */
    private void initDB() {
        //本地持久化数据库
        db = Room.databaseBuilder(getApplicationContext(), MyDatabase.class, "DemoDB")
                //是否允许在主线程上操作数据库,默认false。
                .allowMainThreadQueries()
                //数据库创建和打开的事件会回调到这里,可以再次操作数据库
                .addCallback(new CallBack())
                .build();
    }


    static class CallBack extends RoomDatabase.Callback {
        @Override
        public void onCreate(@NonNull SupportSQLiteDatabase db) {
            super.onCreate(db);
            Log.d("111333", "db create");
        }

        @Override
        public void onOpen(@NonNull SupportSQLiteDatabase db) {
            super.onOpen(db);
            Log.d("111333", "db open");
        }
    }

    /**
     * 增加所有用户
     */
    private void addUser() {
        runOnUiThread(() -> {
            db.userDao().insertUser(
                    new User("张三", 20, "张大炮", "北京八宝山4号墓地"),
                    new User("李四", 60, "尼古拉斯.凯奇", "美国佛罗里达州"),
                    new User("王五", 70, "爱新觉罗.爱国", "北京故宫乾清宫西北方向角落"),
                    new User("赵六", 30, "叶赫那拉.啦啦啦", "北京前门外前门大街皮条胡同")
            );
            Toast.makeText(MainActivity2.this,"增加所有用户成功",Toast.LENGTH_SHORT).show();

        });
    }

    /**
     * 增加用户
     */
    private void addUser_yg() {
        runOnUiThread(() -> {
            db.userDao().insertUser(
                   new User("北京", 25, "顽固派", "广东广州天河区旺角")
            );
            Toast.makeText(MainActivity2.this,"增加用户成功",Toast.LENGTH_SHORT).show();
        });
    }

    /**
     * 删除所有
     */
    private void deleteAll() {
        runOnUiThread(() -> {
            db.userDao().deleteAll();
            Toast.makeText(MainActivity2.this, "删除所有成功", Toast.LENGTH_SHORT).show();
        });
    }

    /**
     * 删除用户
     */
    private void deleteUser() {
        runOnUiThread(() -> {
            User user = db.userDao().findByName("张三");
            if (user == null) return;
            //这个是按用户名删除
            db.userDao().delete(user);
            Toast.makeText(MainActivity2.this, "删除用户成功", Toast.LENGTH_SHORT).show();
        });
    }

    /**
     * 修改用户
     */
    private void updateUser() {
        runOnUiThread(() -> {
            User user = db.userDao().findByName("李四");
            if (user == null) return;
            user.setUserName("赵四");
            user.setUserAge(10);
            user.setNickName("尼古拉斯.赵四");
            user.setAddress("中国东北");
            db.userDao().update(user);
            Toast.makeText(MainActivity2.this, "修改成功", Toast.LENGTH_SHORT).show();
        });
    }

    /**
     * 查询所有用户
     */
    private void queryAll() {
        runOnUiThread(() -> {
            mList.clear();
            mList.addAll(db.userDao().queryAll());
            homeAdapter.notifyDataSetChanged();
            Toast.makeText(MainActivity2.this, "查询所有用户成功", Toast.LENGTH_SHORT).show();
        });
    }

    /**
     * 查询名称
     */
    private void query_dg() {
        runOnUiThread(() -> {
            mList.clear();
            User user = db.userDao().findByName("王五");

            if (user == null) {
                Log.d("111333","数据为空");
                return;
            }else {
                Log.d("111333","有数据");

            }
            mList.add(user);
            homeAdapter.notifyDataSetChanged();
            Toast.makeText(MainActivity2.this, "查询用户名称成功", Toast.LENGTH_SHORT).show();
        });
    }

    /**
     * 查询年龄
     */
    private void query_nl() {
        runOnUiThread(() -> {
            mList.clear();
            User user = db.userDao().findByAge("20");

            if (user == null) {
                Log.d("111333","数据为空");
                return;
            }else {
                Log.d("111333","有数据");
            }
            mList.add(user);
            homeAdapter.notifyDataSetChanged();
            Toast.makeText(MainActivity2.this, "查询年龄成功", Toast.LENGTH_SHORT).show();
        });
    }


    /**
     * 按条件查询
     */
    private void query_tj() {
        runOnUiThread(() -> {
            mList.clear();
            User user = db.userDao().findByAll("赵六",30,"北京前门外前门大街皮条胡同");

            if (user == null) {
                Log.d("111333","数据为空");
                return;
            }else {
                Log.d("111333","有数据");

            }
            mList.add(user);
            homeAdapter.notifyDataSetChanged();
            Toast.makeText(MainActivity2.this, "按条件查询成功", Toast.LENGTH_SHORT).show();
        });
    }

}

4.主活动MainActivity2的activity_main2布局文件内容如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:id="@+id/refreshLa"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="horizontal">

            <Button
                android:id="@+id/btn_add"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="新增所有" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="horizontal">

            <Button
                android:id="@+id/btn_add_yg"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="新增一个用户" />
        </LinearLayout>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btn_delete"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="删除所有" />

        <Button
            android:id="@+id/btn_sc_mc"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="删除用户名" />
    </LinearLayout>

    <Button
        android:id="@+id/btn_update"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="修改" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btn_query"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="查询所有" />

        <Button
            android:id="@+id/btn_cx"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="查询王五" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btn_nl"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="查询年龄20" />

        <Button
            android:id="@+id/btn_tj"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="按条件查询" />
    </LinearLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

5.主活动的适配器HomeAdapter类,代码内容如下

import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.recyclerview.widget.RecyclerView;

import com.example.myapplication001.R;

import java.util.List;

public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder>{

    private Context mContext;
    List<User> list;

    public HomeAdapter(Context mContext, List<User> list) {
        this.mContext = mContext;
        this.list=list;
    }

    /**
     * 设置布局
     * @param viewGroup
     * @param i
     * @return
     */
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        MyViewHolder holder = new MyViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_recycler,viewGroup,false));
        return holder;
    }

    /**
     * 为控件绑定数据
     * @param myViewHolder
     * @param position
     */
    @Override
    public void onBindViewHolder(MyViewHolder myViewHolder, @SuppressLint("RecyclerView") int position) {
        myViewHolder.tv_id.setText(list.get(position).getId()+"");
        myViewHolder.tv_name.setText(list.get(position).getUserName());
        myViewHolder.tv_age.setText(list.get(position).getUserAge()+"");
        myViewHolder.tv_nickname.setText(list.get(position).getNickName());
        myViewHolder.tv_address.setText(list.get(position).getAddress());
    }

    /**
     * 返回项个数
     * @return
     */
    @Override
    public int getItemCount() {
        return list.size();
    }

    /**
     * 定义控件并初始化
     */
    class MyViewHolder extends RecyclerView.ViewHolder{

        TextView tv_id,tv_name,tv_age,tv_nickname,tv_address;

        public MyViewHolder(View itemView) {
            super(itemView);
            tv_id = itemView.findViewById(R.id.tv_id);
            tv_name = itemView.findViewById(R.id.tv_name);
            tv_age = itemView.findViewById(R.id.tv_age);
            tv_nickname = itemView.findViewById(R.id.tv_nickname);
            tv_address = itemView.findViewById(R.id.tv_address);
        }
    }
}

6.主活动的适配器HomeAdapter的item_recycler布局如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="wrap_content"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/tv_id"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:padding="10dp"
            android:text="Id"
            android:textColor="@color/black" />

        <TextView
            android:id="@+id/tv_name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:padding="10dp"
            android:text="name"
            android:textColor="@color/black" />

        <TextView
            android:id="@+id/tv_age"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:padding="10dp"
            android:text="age"
            android:textColor="@color/black" />

        <TextView
            android:id="@+id/tv_nickname"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:padding="10dp"
            android:text="nickname"
            android:textColor="@color/black" />

        <TextView
            android:id="@+id/tv_address"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:ellipsize="end"
            android:padding="10dp"
            android:text="address"
            android:textColor="@color/black" />
    </LinearLayout>

    <View
        android:id="@+id/view"
        android:layout_width="wrap_content"
        android:layout_height="1dp"
        android:background="#E1DFDF" />
</LinearLayout>

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

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

相关文章

爱奇艺DRM修炼之路

01 DRM的定义和作用 DRM&#xff0c;即数字版权管理&#xff08;digital rights management&#xff09;&#xff0c;是在数字内容交易过程中&#xff0c;对知识产权进行保护的技术、工具和处理过程。它的目的是防止数字内容被未经授权的用户复制、修改和分发&#xff0c;以保护…

解读TaskMatrix.AI

ChatGPT在广泛的开放域任务上展现出令人瞩目的强大对话、上下文学习和代码生成能力&#xff0c;而且它所获得的常识知识还可以为特定领域的任务生成高级解决方案概要。不过&#xff0c;除了更强大的学习、理解和生成能力&#xff0c;ChatGPT还有哪些问题需要解决呢&#xff1f;…

《利用光体积描记图信号的模糊递推特性估计无袖带血压的级联卷积神经网络模型》阅读笔记

目录 一、论文摘要 二、论文十问 Q1&#xff1a;论文试图解决什么问题&#xff1f; Q2&#xff1a;这是否是一个新的问题&#xff1f; Q3&#xff1a;这篇文章要验证一个什么科学假设&#xff1f; Q4&#xff1a;有哪些相关研究&#xff1f;如何归类&#xff1f;谁是这一…

城市的智能进化,汇成数字中国的璀璨银河

著名城市规划理论家刘易斯芒福德在《城市发展史——起源、演变和前景》中提出&#xff0c;“城市从其起源时代开始便是一种特殊的构造&#xff0c;它专门用来储存并流传人类文明的成果。这种构造致密而紧凑&#xff0c;足以用最小的空间容纳更多的设施。” 他认为&#xff0c;城…

我们如何将 Amazon Snowcone 送入轨道

我从 4 或 5 岁起就一直是太空旅行和美国太空计划的粉丝。我记得读过关于水星和双子星座计划的文章&#xff0c;兴奋地看着鹰号登月舱降落在月球上。 如今&#xff0c;随着每次发射到达近地轨道 (LEO) 的成本似乎都在不断下降&#xff0c;因此有比以往任何时候都要更多的机会&…

建设元宇宙基础设施——PPIO边缘云在云渲染/云游戏的思考和实践

关于“元宇宙”的讨论越发火热&#xff0c;而建设元宇宙不可避免需要布设基础设施&#xff0c;LiveVideoStackCon 2022 北京站邀请到PPIO边缘云联合创始人——王闻宇&#xff0c;同大家探讨元宇宙网络时延的最优解–边缘云基础设施的架构与建设&#xff0c;并介绍PPIO边缘云在泛…

Kafka Broker是如何基于Reactor模式来处理海量用户请求的?

介绍 https://kafka.apache.org/0110/documentation.html 参数名描述默认值queued.max.requestsbroker全局唯一的请求队列&#xff0c;用来保存请求500num.io.threads用来处理请求的线程数8 参考博客 [1]

Python环境设置

在了解Python语言的历史和介绍之后&#xff0c;要想开始学习Python语言&#xff0c;还需要在计算机中安装Python编译环境&#xff0c;本期就来聊聊怎么在计算机中安装Python环境。 在计算机中添加Python环境的几种选择&#xff1a; 直接安装Python程序&#xff0c;即Python官…

Spring Boot配置文件

日升时奋斗&#xff0c;日落时自省 目录 1、配置文件作用 2、配置文件格式 2.1、使用注意 3、properties配置文件 3.1、注释中文问题 3.2、properties语法格式 3.3、读取配置文件 3.3.1、Value读取 3.3.2、PropertySource读取 3.3.3、原生方式读取配置文件 3.4、pr…

C++-FFmpeg-1-VS2019-x264-fdk_aac-x265-pdb-QT5.14-makefile

1.环境搭建&#xff1a; 1.1VS2019 用的是控制台编译。 1.2.msys2 模拟linux的命令和指令。 2.源码编译与安装&#xff1a; 2.1.x264: ffmpeg :编码用X264 2.2x265: ffmpeg :编码用X265 c写的。msys2编译。 2.3.fdk-aac 音频编码。 2.4 ffmpeg源码4.3: 2.5.SDL2.0 视频渲…

ESP8266_RTOS_SDK之SPIFFS

需要在ESP8266的FLASH中存储一些可变参数&#xff0c;有两种方式&#xff0c;一种是调用SPI Flash API直接指定地址读写FLASH&#xff1b;二是在SPI FLASH上创建一块SPIFFS 分区&#xff0c;以读写文件的形式存取数据。 下面记录第二种方式&#xff0c;使用SPIFFS文件系统存取…

干货 | Elasticsearch 8.X 性能优化实战

Elasticsearch 是实现用户无缝搜索体验的关键工具。它通过提供快速、准确和相关的搜索结果&#xff0c;彻底改变了用户与应用程序的互动方式。然而&#xff0c;要确保 Elasticsearch 部署达到最佳性能&#xff0c;就必须关注关键指标&#xff0c;并对诸如索引、缓存、查询、搜索…

【计算机图形学】课堂习题汇总

在直线的光栅化算法中&#xff0c;如果不考虑最大位移方向则可能得到怎样的直线&#xff1f; A&#xff1a;斜率为1的线 B&#xff1a;总是垂直的 C&#xff1a;离散的点&#xff0c;无法构成直线 D&#xff1a;总是水平的 在直线的改进的Bresenham算法中&#xff0c;每当误…

Qt音视频开发42-网络推流(视频推流/本地摄像头推流/桌面推流/网络摄像头转发推流等)

一、前言 上次实现的文件推流&#xff0c;尽管优点很多&#xff0c;但是只能对现在存在的生成好的音视频文件推流&#xff0c;而现在更多的场景是需要将实时的视频流重新推流分发&#xff0c;用户在很多设备比如手机/平板/网页/电脑/服务器上观看&#xff0c;这样就可以很方便…

IP-GUARD如何通过流量控制策略限制客户端下载文件?

如何通过流量控制策略限制客户端下载文件? 可通过流量控制策略限制接收流量上限速度,实现控制客户端下载文件效果。流量控制支持网络地址和端口范围限制。 网络流量统计能否基于用户进行统计? 目前最新的客户端版本已经支持控制应用程序的网络流量,在应用层实现了控制…

专利进阶(二):专利撰写常用技术及算法汇总(持续更新中)

文章目录 一、前言二、常用技术及算法2.1 区跨链技术2.2 聚类算法2.3 边缘算法2.4 蚁群算法2.4.1 路径构建2.4.2 信息素更新 2.5 哈希算法2.5.1 常见算法 2.6 数字摘要2.72.82.92.10 三、拓展阅读 一、前言 专利撰写过程中使用已有技术或算法解决新问题非常常见&#xff0c;本…

基于SpringBoot的冬奥会科普平台

摘 要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理平台应运而生&#xff0c;各行各业相继进入信息管理时代&…

【五一创作】Scratch资料

Scratch软件是免费的、免费的、免费的。任何需要花钱才能下载Scratch软件的全是骗子。 1、什么是Scratch Scratch是麻省理工学院的“终身幼儿园团队”开发的一种图形化编程工具。是面向青少年的一款模块化&#xff0c;积木化、可视化的编程语言。 什么是模块化、积木化&…

leetcode每日一题【7】

第一题&#xff1a;67. 二进制求和 给你两个二进制字符串 a 和 b &#xff0c;以二进制字符串的形式返回它们的和。示例 1&#xff1a;输入:a "11", b "1" 输出&#xff1a;"100" 示例 2&#xff1a;输入&#xff1a;a "1010", b …

MyBatis:生命周期、作用域、结果集映射 ResultMap、日志、分页、使用注解开发、Lombok

文章目录 MyBatis&#xff1a;Day 02一、生命周期和作用域二、结果集映射&#xff1a;ResultMap三、日志工厂1. 标准日志&#xff1a;STDOUT_LOGGING2. LOG4J 四、分页五、使用注解开发六、Lombok注意&#xff1a; MyBatis&#xff1a;Day 02 一、生命周期和作用域 理解不同作…