欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Jetpack Room 使用示例詳解

 更新時(shí)間:2025年04月29日 10:33:54   作者:百錦再@新空間  
Room 是 Android 開(kāi)發(fā)中強(qiáng)大的持久化解決方案,它簡(jiǎn)化了 SQLite 的使用,提供了類(lèi)型安全的數(shù)據(jù)庫(kù)訪(fǎng)問(wèn),并與 Android 架構(gòu)組件深度集成,本文給大家介紹Jetpack Room 使用詳解,感興趣的朋友一起看看吧

1. Room 概述

1.1 Room 簡(jiǎn)介

Room 是 Android Jetpack 組件中的一部分,它是一個(gè) SQLite 對(duì)象映射庫(kù),提供了在 SQLite 上更抽象的層,使開(kāi)發(fā)者能夠更流暢地訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)。Room 在編譯時(shí)驗(yàn)證 SQL 查詢(xún),避免了運(yùn)行時(shí)錯(cuò)誤,并且減少了大量樣板代碼。

1.2 Room 的優(yōu)勢(shì)

  • 編譯時(shí) SQL 驗(yàn)證:Room 會(huì)在編譯時(shí)檢查 SQL 查詢(xún)的正確性,避免運(yùn)行時(shí)錯(cuò)誤。
  • 減少樣板代碼:自動(dòng)生成大量重復(fù)的數(shù)據(jù)庫(kù)操作代碼。
  • 與 LiveData 和 RxJava 集成:可以輕松地將數(shù)據(jù)庫(kù)操作與 UI 更新結(jié)合。
  • 類(lèi)型安全:使用注解處理器生成代碼,確保類(lèi)型安全。
  • 遷移支持:提供簡(jiǎn)單的數(shù)據(jù)庫(kù)遷移方案。

1.3 Room 組件架構(gòu)

Room 主要由三個(gè)組件組成:

  • Database:包含數(shù)據(jù)庫(kù)持有者,并作為與應(yīng)用持久關(guān)聯(lián)數(shù)據(jù)的底層連接的主要訪(fǎng)問(wèn)點(diǎn)。
  • Entity:表示數(shù)據(jù)庫(kù)中的表。
  • DAO:包含用于訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)的方法。

2. Room 基本使用

2.1 添加依賴(lài)

首先需要在項(xiàng)目的 build.gradle 文件中添加 Room 的依賴(lài):

dependencies {
    def room_version = "2.4.0"
    implementation "androidx.room:room-runtime:$room_version"
    annotationProcessor "androidx.room:room-compiler:$room_version"
    // 可選 - Kotlin 擴(kuò)展和協(xié)程支持
    implementation "androidx.room:room-ktx:$room_version"
    // 可選 - RxJava 支持
    implementation "androidx.room:room-rxjava2:$room_version"
    implementation "androidx.room:room-rxjava3:$room_version"
    // 可選 - 測(cè)試助手
    testImplementation "androidx.room:room-testing:$room_version"
}

2.2 創(chuàng)建 Entity

Entity 是數(shù)據(jù)表的 Java/Kotlin 表示。每個(gè) Entity 類(lèi)對(duì)應(yīng)數(shù)據(jù)庫(kù)中的一個(gè)表,類(lèi)的字段對(duì)應(yīng)表中的列。

@Entity(tableName = "users")
public class User {
    @PrimaryKey(autoGenerate = true)
    private int id;
    @ColumnInfo(name = "user_name")
    private String name;
    private int age;
    // 構(gòu)造方法、getter 和 setter
}

常用注解:

  • @Entity:標(biāo)記類(lèi)為數(shù)據(jù)實(shí)體
  • @PrimaryKey:標(biāo)記主鍵
  • @ColumnInfo:自定義列名
  • @Ignore:忽略字段,不存入數(shù)據(jù)庫(kù)

2.3 創(chuàng)建 DAO

DAO (Data Access Object) 是訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)的主要組件,定義了訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)的方法。

@Dao
public interface UserDao {
    @Insert
    void insert(User user);
    @Update
    void update(User user);
    @Delete
    void delete(User user);
    @Query("SELECT * FROM users")
    List<User> getAllUsers();
    @Query("SELECT * FROM users WHERE id = :userId")
    User getUserById(int userId);
}

常用注解:

  • @Insert:插入數(shù)據(jù)
  • @Update:更新數(shù)據(jù)
  • @Delete:刪除數(shù)據(jù)
  • @Query:自定義 SQL 查詢(xún)

2.4 創(chuàng)建 Database

Database 類(lèi)是 Room 的主要訪(fǎng)問(wèn)點(diǎn),它持有數(shù)據(jù)庫(kù)并作為持久化數(shù)據(jù)的底層連接的主要訪(fǎng)問(wèn)點(diǎn)。

@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
    public abstract UserDao userDao();
    private static volatile AppDatabase INSTANCE;
    public static AppDatabase getInstance(Context context) {
        if (INSTANCE == null) {
            synchronized (AppDatabase.class) {
                if (INSTANCE == null) {
                    INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                            AppDatabase.class, "app_database")
                            .build();
                }
            }
        }
        return INSTANCE;
    }
}

2.5 使用 Room 數(shù)據(jù)庫(kù)

// 獲取數(shù)據(jù)庫(kù)實(shí)例
AppDatabase db = AppDatabase.getInstance(context);
// 獲取 DAO
UserDao userDao = db.userDao();
// 插入用戶(hù)
User user = new User();
user.setName("John");
user.setAge(30);
userDao.insert(user);
// 查詢(xún)所有用戶(hù)
List<User> users = userDao.getAllUsers();

3. Room 高級(jí)特性

3.1 數(shù)據(jù)庫(kù)關(guān)系

Room 支持三種類(lèi)型的關(guān)系:

  • 一對(duì)一關(guān)系:一個(gè)實(shí)體只與另一個(gè)實(shí)體關(guān)聯(lián)
  • 一對(duì)多關(guān)系:一個(gè)實(shí)體可以與多個(gè)實(shí)體關(guān)聯(lián)
  • 多對(duì)多關(guān)系:多個(gè)實(shí)體可以相互關(guān)聯(lián)

3.1.1 一對(duì)一關(guān)系

@Entity
public class User {
    @PrimaryKey public long userId;
    public String name;
}
@Entity
public class Library {
    @PrimaryKey public long libraryId;
    public long userOwnerId;
}
public class UserAndLibrary {
    @Embedded public User user;
    @Relation(
         parentColumn = "userId",
         entityColumn = "userOwnerId"
    )
    public Library library;
}
@Dao
public interface UserDao {
    @Transaction
    @Query("SELECT * FROM User")
    public List<UserAndLibrary> getUsersAndLibraries();
}

3.1.2 一對(duì)多關(guān)系

@Entity
public class User {
    @PrimaryKey public long userId;
    public String name;
}
@Entity
public class Playlist {
    @PrimaryKey public long playlistId;
    public long userCreatorId;
    public String playlistName;
}
public class UserWithPlaylists {
    @Embedded public User user;
    @Relation(
         parentColumn = "userId",
         entityColumn = "userCreatorId"
    )
    public List<Playlist> playlists;
}
@Dao
public interface UserDao {
    @Transaction
    @Query("SELECT * FROM User")
    public List<UserWithPlaylists> getUsersWithPlaylists();
}

3.1.3 多對(duì)多關(guān)系

@Entity
public class Playlist {
    @PrimaryKey public long playlistId;
    public String playlistName;
}
@Entity
public class Song {
    @PrimaryKey public long songId;
    public String songName;
    public String artist;
}
@Entity(primaryKeys = {"playlistId", "songId"})
public class PlaylistSongCrossRef {
    public long playlistId;
    public long songId;
}
public class PlaylistWithSongs {
    @Embedded public Playlist playlist;
    @Relation(
         parentColumn = "playlistId",
         entityColumn = "songId",
         associateBy = @Junction(PlaylistSongCrossref.class)
    )
    public List<Song> songs;
}
public class SongWithPlaylists {
    @Embedded public Song song;
    @Relation(
         parentColumn = "songId",
         entityColumn = "playlistId",
         associateBy = @Junction(PlaylistSongCrossref.class)
    )
    public List<Playlist> playlists;
}

3.2 類(lèi)型轉(zhuǎn)換器

Room 默認(rèn)支持基本類(lèi)型和它們的包裝類(lèi),但如果想存儲(chǔ)自定義類(lèi)型,需要使用 @TypeConverter

public class Converters {
    @TypeConverter
    public static Date fromTimestamp(Long value) {
        return value == null ? null : new Date(value);
    }
    @TypeConverter
    public static Long dateToTimestamp(Date date) {
        return date == null ? null : date.getTime();
    }
}
@Database(entities = {User.class}, version = 1)
@TypeConverters({Converters.class})
public abstract class AppDatabase extends RoomDatabase {
    // ...
}
@Entity
public class User {
    @PrimaryKey public int id;
    public String name;
    public Date birthday;
}

3.3 數(shù)據(jù)庫(kù)遷移

當(dāng)數(shù)據(jù)庫(kù)結(jié)構(gòu)發(fā)生變化時(shí),需要升級(jí)數(shù)據(jù)庫(kù)版本并提供遷移策略。

// 版本1的數(shù)據(jù)庫(kù)
@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
    // ...
}
// 版本2的數(shù)據(jù)庫(kù) - 添加了新表
@Database(entities = {User.class, Book.class}, version = 2)
public abstract class AppDatabase extends RoomDatabase {
    // ...
    private static final Migration MIGRATION_1_2 = new Migration(1, 2) {
        @Override
        public void migrate(SupportSQLiteDatabase database) {
            database.execSQL("CREATE TABLE IF NOT EXISTS `Book` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT, `author` TEXT)");
        }
    };
    public static AppDatabase getInstance(Context context) {
        if (INSTANCE == null) {
            synchronized (AppDatabase.class) {
                if (INSTANCE == null) {
                    INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                            AppDatabase.class, "app_database")
                            .addMigrations(MIGRATION_1_2)
                            .build();
                }
            }
        }
        return INSTANCE;
    }
}

3.4 預(yù)填充數(shù)據(jù)庫(kù)

有時(shí)需要在應(yīng)用首次啟動(dòng)時(shí)預(yù)填充數(shù)據(jù)庫(kù):

Room.databaseBuilder(context.getApplicationContext(),
        AppDatabase.class, "app_database")
        .createFromAsset("database/myapp.db")
        .build();

3.5 數(shù)據(jù)庫(kù)測(cè)試

Room 提供了測(cè)試支持:

@RunWith(AndroidJUnit4.class)
public class UserDaoTest {
    private UserDao userDao;
    private AppDatabase db;
    @Before
    public void createDb() {
        Context context = ApplicationProvider.getApplicationContext();
        db = Room.inMemoryDatabaseBuilder(context, AppDatabase.class).build();
        userDao = db.userDao();
    }
    @After
    public void closeDb() throws IOException {
        db.close();
    }
    @Test
    public void insertAndGetUser() throws Exception {
        User user = new User();
        user.setName("John");
        userDao.insert(user);
        List<User> allUsers = userDao.getAllUsers();
        assertEquals(allUsers.get(0).getName(), "John");
    }
}

4. Room 與架構(gòu)組件集成

4.1 Room 與 LiveData

Room 可以返回 LiveData 對(duì)象,使數(shù)據(jù)庫(kù)變化自動(dòng)反映到 UI 上。

@Dao
public interface UserDao {
    @Query("SELECT * FROM users")
    LiveData<List<User>> getAllUsers();
}
// 在 Activity/Fragment 中觀察
userDao.getAllUsers().observe(this, users -> {
    // 更新 UI
});

4.2 Room 與 ViewModel

public class UserViewModel extends AndroidViewModel {
    private UserDao userDao;
    private LiveData<List<User>> allUsers;
    public UserViewModel(@NonNull Application application) {
        super(application);
        AppDatabase db = AppDatabase.getInstance(application);
        userDao = db.userDao();
        allUsers = userDao.getAllUsers();
    }
    public LiveData<List<User>> getAllUsers() {
        return allUsers;
    }
}
// 在 Activity/Fragment 中
UserViewModel viewModel = new ViewModelProvider(this).get(UserViewModel.class);
viewModel.getAllUsers().observe(this, users -> {
    // 更新 UI
});

4.3 Room 與 Paging Library

Room 支持 Paging Library,可以輕松實(shí)現(xiàn)分頁(yè)加載:

@Dao
public interface UserDao {
    @Query("SELECT * FROM users")
    PagingSource<Integer, User> usersByName();
}
// 在 ViewModel 中
public class UserViewModel extends ViewModel {
    public LiveData<PagingData<User>> users;
    public UserViewModel(UserDao userDao) {
        users = Pager(
            new PagingConfig(pageSize = 20)
        ) {
            userDao.usersByName()
        }.liveData
            .cachedIn(viewModelScope);
    }
}

5. Room 性能優(yōu)化

5.1 索引優(yōu)化

@Entity(indices = {@Index("name"), @Index(value = {"last_name", "address"}, unique = true)})
public class User {
    @PrimaryKey public int id;
    public String name;
    @ColumnInfo(name = "last_name") public String lastName;
    public String address;
}

5.2 事務(wù)處理

@Dao
public interface UserDao {
    @Transaction
    default void insertUsers(User user1, User user2) {
        insert(user1);
        insert(user2);
    }
}

5.3 批量操作

@Dao
public interface UserDao {
    @Insert
    void insertAll(User... users);
    @Update
    void updateAll(User... users);
    @Delete
    void deleteAll(User... users);
}

5.4 異步查詢(xún)

使用 RxJava 或 Kotlin 協(xié)程進(jìn)行異步操作:

@Dao
public interface UserDao {
    @Query("SELECT * FROM users")
    Flowable<List<User>> getAllUsers();
    @Query("SELECT * FROM users")
    Single<List<User>> getAllUsersSingle();
    @Query("SELECT * FROM users")
    Maybe<List<User>> getAllUsersMaybe();
}
// 或使用 Kotlin 協(xié)程
@Dao
interface UserDao {
    @Query("SELECT * FROM users")
    suspend fun getAllUsers(): List<User>
}

6. Room 常見(jiàn)問(wèn)題與解決方案

6.1 主線(xiàn)程訪(fǎng)問(wèn)問(wèn)題

默認(rèn)情況下,Room 不允許在主線(xiàn)程執(zhí)行數(shù)據(jù)庫(kù)操作。解決方法:

  • 使用異步操作(LiveData, RxJava, 協(xié)程等)
  • 允許主線(xiàn)程訪(fǎng)問(wèn)(不推薦):
Room.databaseBuilder(context.getApplicationContext(),
        AppDatabase.class, "app_database")
        .allowMainThreadQueries()
        .build();

6.2 數(shù)據(jù)庫(kù)升級(jí)失敗

解決方案:

  • 確保提供了所有必要的遷移
  • 使用 fallbackToDestructiveMigration 作為最后手段:
Room.databaseBuilder(context.getApplicationContext(),
        AppDatabase.class, "app_database")
        .fallbackToDestructiveMigration()
        .build();

6.3 類(lèi)型轉(zhuǎn)換錯(cuò)誤

確保所有 TypeConverter 都正確實(shí)現(xiàn),并在數(shù)據(jù)庫(kù)類(lèi)上添加了 @TypeConverters 注解。

6.4 數(shù)據(jù)庫(kù)文件過(guò)大

解決方案:

  • 定期清理不必要的數(shù)據(jù)
  • 使用數(shù)據(jù)庫(kù)壓縮工具
  • 考慮分庫(kù)分表策略

7. Room 最佳實(shí)踐

7.1 設(shè)計(jì)原則

  • 單一職責(zé):每個(gè) DAO 只處理一個(gè)實(shí)體的操作
  • 最小化查詢(xún):只查詢(xún)需要的字段
  • 合理使用索引:為常用查詢(xún)字段添加索引
  • 批量操作:使用事務(wù)進(jìn)行批量操作

7.2 代碼組織

推薦的項(xiàng)目結(jié)構(gòu):

- data/
  - model/       # 實(shí)體類(lèi)
  - dao/         # DAO 接口
  - database/    # 數(shù)據(jù)庫(kù)類(lèi)和相關(guān)工具
  - repository/  # 倉(cāng)庫(kù)層(可選)

7.3 測(cè)試策略

  • 使用內(nèi)存數(shù)據(jù)庫(kù)進(jìn)行單元測(cè)試
  • 測(cè)試所有自定義查詢(xún)
  • 測(cè)試數(shù)據(jù)庫(kù)遷移
  • 測(cè)試異常情況

8. Room 與其他存儲(chǔ)方案比較

8.1 Room vs SQLiteOpenHelper

優(yōu)勢(shì):

  • 編譯時(shí) SQL 驗(yàn)證
  • 減少樣板代碼
  • 更好的類(lèi)型安全
  • 與架構(gòu)組件集成

劣勢(shì):

  • 學(xué)習(xí)曲線(xiàn)
  • 靈活性稍低

8.2 Room vs Realm

優(yōu)勢(shì):

  • 基于 SQLite,兼容性好
  • 不需要額外運(yùn)行時(shí)
  • 更小的 APK 體積

劣勢(shì):

  • 性能在某些場(chǎng)景下不如 Realm
  • 不支持跨進(jìn)程

8.3 Room vs ObjectBox

優(yōu)勢(shì):

  • Google 官方支持
  • 基于 SQLite,兼容現(xiàn)有工具
  • 更成熟穩(wěn)定

劣勢(shì):

  • 性能不如 ObjectBox
  • 不支持 NoSQL 特性

9. Room 實(shí)際應(yīng)用案例

9.1 筆記應(yīng)用

@Entity
public class Note {
    @PrimaryKey(autoGenerate = true)
    private int id;
    private String title;
    private String content;
    private Date createdAt;
    private Date updatedAt;
}
@Dao
public interface NoteDao {
    @Insert
    void insert(Note note);
    @Update
    void update(Note note);
    @Delete
    void delete(Note note);
    @Query("SELECT * FROM notes ORDER BY updatedAt DESC")
    LiveData<List<Note>> getAllNotes();
    @Query("SELECT * FROM notes WHERE id = :noteId")
    LiveData<Note> getNoteById(int noteId);
    @Query("SELECT * FROM notes WHERE title LIKE :query OR content LIKE :query")
    LiveData<List<Note>> searchNotes(String query);
}

9.2 電商應(yīng)用

@Entity
public class Product {
    @PrimaryKey
    private String id;
    private String name;
    private String description;
    private double price;
    private int stock;
    private String imageUrl;
}
@Entity
public class CartItem {
    @PrimaryKey
    private String productId;
    private int quantity;
}
public class ProductWithCartStatus {
    @Embedded
    public Product product;
    @Relation(parentColumn = "id", entityColumn = "productId")
    public CartItem cartItem;
}
@Dao
public interface ProductDao {
    @Query("SELECT * FROM product")
    LiveData<List<Product>> getAllProducts();
    @Transaction
    @Query("SELECT * FROM product")
    LiveData<List<ProductWithCartStatus>> getAllProductsWithCartStatus();
}

10. Room 的未來(lái)發(fā)展

10.1 多平臺(tái)支持

Room 正在增加對(duì) Kotlin Multiplatform 的支持,未來(lái)可以在 iOS 等平臺(tái)使用。

10.2 增強(qiáng)的查詢(xún)功能

未來(lái)版本可能會(huì)增加更復(fù)雜的查詢(xún)支持,如全文搜索、更強(qiáng)大的關(guān)聯(lián)查詢(xún)等。

10.3 性能優(yōu)化

持續(xù)的底層性能優(yōu)化,特別是在大數(shù)據(jù)量情況下的查詢(xún)效率。

11. 總結(jié)

Room 是 Android 開(kāi)發(fā)中強(qiáng)大的持久化解決方案,它簡(jiǎn)化了 SQLite 的使用,提供了類(lèi)型安全的數(shù)據(jù)庫(kù)訪(fǎng)問(wèn),并與 Android 架構(gòu)組件深度集成。通過(guò)合理使用 Room 的各種特性,開(kāi)發(fā)者可以構(gòu)建高效、可維護(hù)的數(shù)據(jù)層,為應(yīng)用提供可靠的數(shù)據(jù)存儲(chǔ)和訪(fǎng)問(wèn)能力。

到此這篇關(guān)于Jetpack Room 使用示例詳解的文章就介紹到這了,更多相關(guān)Jetpack Room 使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解JAVA使用Comparator接口實(shí)現(xiàn)自定義排序

    詳解JAVA使用Comparator接口實(shí)現(xiàn)自定義排序

    這篇文章主要介紹了JAVA使用Comparator接口實(shí)現(xiàn)自定義排序,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Java中的String、StringBuilder、StringBuffer三者的區(qū)別詳解

    Java中的String、StringBuilder、StringBuffer三者的區(qū)別詳解

    這篇文章主要介紹了Java中的String、StringBuilder、StringBuffer三者的區(qū)別詳解,就是String,StringBuilder以及StringBuffer這三個(gè)類(lèi)之間有什么區(qū)別呢,自己從網(wǎng)上搜索了一些資料,有所了解了之后在這里整理一下,便于大家觀看,需要的朋友可以參考下
    2023-12-12
  • 解決Test類(lèi)中不能使用Autowired注入bean的問(wèn)題

    解決Test類(lèi)中不能使用Autowired注入bean的問(wèn)題

    這篇文章主要介紹了解決Test類(lèi)中不能使用Autowired注入bean的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java中Word與PDF轉(zhuǎn)換為圖片的方法詳解

    Java中Word與PDF轉(zhuǎn)換為圖片的方法詳解

    這篇文章主要為大家詳細(xì)介紹了如何使用Java實(shí)現(xiàn)將Word與PDF轉(zhuǎn)換為圖片,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-10-10
  • 利用Java異常機(jī)制實(shí)現(xiàn)模擬借書(shū)系統(tǒng)

    利用Java異常機(jī)制實(shí)現(xiàn)模擬借書(shū)系統(tǒng)

    這篇文章主要給大家介紹了利用Java異常機(jī)制實(shí)現(xiàn)模擬借書(shū)系統(tǒng)的相關(guān)資料,文中先對(duì)java異常機(jī)制進(jìn)行了簡(jiǎn)單介紹,而后通過(guò)示例代碼介紹了java語(yǔ)言是如何實(shí)現(xiàn)一個(gè)控制臺(tái)版的模擬借書(shū)系統(tǒng),需要的朋友可以參考學(xué)習(xí),一起來(lái)看看吧。
    2017-04-04
  • Spring框架中@AliasFor注解詳細(xì)說(shuō)明

    Spring框架中@AliasFor注解詳細(xì)說(shuō)明

    這篇文章主要給大家介紹了關(guān)于Spring框架中@AliasFor注解詳細(xì)說(shuō)明的相關(guān)資料,@AliasFor是Spring Framework中的一個(gè)注解,它用于指定注解屬性之間的別名關(guān)系,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-02-02
  • MyBatisPlus的autoResultMap生成策略實(shí)現(xiàn)

    MyBatisPlus的autoResultMap生成策略實(shí)現(xiàn)

    本文主要介紹了MyBatisPlus的autoResultMap生成策略實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-02-02
  • jdk21環(huán)境配置詳細(xì)步驟記錄

    jdk21環(huán)境配置詳細(xì)步驟記錄

    JDK是整個(gè)Java開(kāi)發(fā)的核心,它包含了Java的運(yùn)行環(huán)境和Java工具,這篇文章主要給大家介紹了關(guān)于jdk21環(huán)境配置的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-11-11
  • Mybatis-plus更新字段為null兩種常用方法及優(yōu)化

    Mybatis-plus更新字段為null兩種常用方法及優(yōu)化

    Mybatis Plus在進(jìn)行更新操作時(shí),默認(rèn)情況下是不能將字段更新為null的,如果要更新字段為null,需要進(jìn)行以下處理,這篇文章主要給大家介紹了關(guān)于Mybatis-plus更新字段為null的兩種常用方法及優(yōu)化,需要的朋友可以參考下
    2024-03-03
  • springcloud gateway自定義斷言規(guī)則詳解,以后綴結(jié)尾進(jìn)行路由

    springcloud gateway自定義斷言規(guī)則詳解,以后綴結(jié)尾進(jìn)行路由

    這篇文章主要介紹了springcloud gateway自定義斷言規(guī)則詳解,以后綴結(jié)尾進(jìn)行路由,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10

最新評(píng)論