当前位置: 首页 > wzjs >正文

深圳网站建设yuntianxia企业查询宝

深圳网站建设yuntianxia,企业查询宝,高端设计网站都有哪些,装饰公司网站记录数据使用ROOM,传递使用ViewModel LiveDataBus,这篇文章主要记录 搜索记录 本地 线上,上传失败,记录本地,网络回复统一上传等逻辑的操作。 目录 首先是设计数据表: 定义DAO操作接口 定义数据库类 Mvvm 模式中封…

记录数据使用ROOM,传递使用ViewModel LiveDataBus,这篇文章主要记录 搜索记录 本地 线上,上传失败,记录本地,网络回复统一上传等逻辑的操作。

目录

首先是设计数据表:

定义DAO操作接口

定义数据库类

Mvvm 模式中封装使用Room


首先阐述下搜索记录的要求,后面会逐一针对这些要求使用Room本身能力解决。

  1. 最多记录10条;
  2. 搜索分为点位搜索,和普通搜索。
  3. 列表展示输入搜索的文字,要求文字不可有重复。
  4. 记录分为本地记录和在线记录。

首先是设计数据表:

@Entity(indices = {@Index(value = {"searchKeyword", "searchType"}, unique = true)})
public class SearchHistoryEntity {@PrimaryKey(autoGenerate = true)public int id;public String userId; // 可以为null表示未登录用户public String searchKeyword;public long searchTime;@TypeConverters(Converters.class)public SearchType searchType; // 使用枚举类型public double latitude; // 纬度public double longitude; // 经度public boolean loginStatus; // false: 未登录, true: 已登录}
  • @Entity 表示这是一个 Room 数据库中的表。
  • indices 参数定义了一个组合索引 searchKeyword 和 searchType,并且设置为唯一索引。这意味着在表中,searchKeyword 和 searchType 的组合必须是唯一的。

serchType 是枚举类型,为了区分 普通搜索和点位搜索。

设置searchKeyword 和 searchType 组合必须是唯一的。

以上可以满足第二、三条要求。

定义DAO操作接口

@Dao
public interface SearchHistoryDao {// 插入新的搜索记录,如果发生冲突则替换@Insert(onConflict = OnConflictStrategy.REPLACE)long insertPerson(SearchHistoryEntity entity);@Query("DELETE FROM SearchHistoryEntity WHERE id = (SELECT id FROM SearchHistoryEntity ORDER BY searchTime ASC LIMIT 1)")void deleteOldestSearchHistory();// 删除所有的搜索历史记录@Query("DELETE FROM SearchHistoryEntity")void deleteAllSearchHistory();// 查询所有历史记录@Query("SELECT * FROM SearchHistoryEntity ORDER BY searchTime DESC")public List<SearchHistoryEntity> selectHis();// 查询所有已登录的数据@Query("SELECT * FROM SearchHistoryEntity WHERE userId = :userId")List<SearchHistoryEntity> getSearchHistoryByUserId(String userId);// 查询所有未登录的数据@Query("SELECT * FROM SearchHistoryEntity WHERE loginStatus = 0 ORDER BY searchTime DESC")List<SearchHistoryEntity> getAllLoggedOutData();// 删除所有已登录的数据@Query("DELETE FROM SearchHistoryEntity WHERE loginStatus = 1")void deleteAllLoggedInData();}

这个类其实就是操作数据的工具类,里面最主要需要解释的只有

  • @Insert(onConflict = OnConflictStrategy.REPLACE): 该注解表明该方法用于向数据库插入数据。onConflict 参数设置为 OnConflictStrategy.REPLACE,这意味着如果发生冲突(例如已经存在具有相同主键的行),则用新数据替换现有行。

这样是第二天 第三条的补充,在插入相同搜索的记录的时候覆盖原有记录。

定义数据库类

@Database(entities = {SearchHistoryEntity.class}, version = 1, exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {public abstract SearchHistoryDao searchHistoryDao();private static volatile AppDatabase INSTANCE;private static final int NUMBER_OF_THREADS = 4;static final ExecutorService databaseWriteExecutor = Executors.newFixedThreadPool(NUMBER_OF_THREADS);static AppDatabase getDatabase(final Context context) {if (INSTANCE == null) {synchronized (AppDatabase.class) {if (INSTANCE == null) {INSTANCE = Room.databaseBuilder(context.getApplicationContext(),AppDatabase.class, "app_database").addCallback(sRoomDatabaseCallback).build();}}}return INSTANCE;}private static RoomDatabase.Callback sRoomDatabaseCallback =new RoomDatabase.Callback() {@Overridepublic void onCreate(@NonNull SupportSQLiteDatabase db) {super.onCreate(db);// 创建触发器:确保最多保留10条记录db.execSQL("CREATE TRIGGER limit_search_history_count " +"AFTER INSERT ON SearchHistoryEntity " +"WHEN (SELECT COUNT(*) FROM SearchHistoryEntity) > 10 " +"BEGIN " +"DELETE FROM SearchHistoryEntity WHERE id = (SELECT id FROM SearchHistoryEntity ORDER BY searchTime ASC LIMIT 1); " +"END");}};
}

这里是一个模版代码,其中唯一注意的sRoomDatabaseCallback ,添加一个触发器,当数据超过10条后,按照添加顺序删除最早添加的数据。

其实和DAO接口中定义的 deleteOldestSearchHistory 方法功能是一样的,但是显然触发器的方式更省心。不需要我们每次添加都要去获取一次存储了多少条数据。再去删除。

满足第一条

以上就是Room完整的模版代码,下面才是最主要的第四个条件。

我项目框架是Mvvm,所以操作数据库的代码就放到了 Repository 中,其实没必要,但是咱们尊许模式搞一遍,不在意的话直接使用  db = AppDatabase.getDatabase(this); 即可

Mvvm 模式中封装使用Room

  1. 创建 AppDataBase 抽象类
@TypeConverters(value = {Converters.class})
@Database(entities = {SearchHistoryEntity.class}, version = 1)
public abstract class AppDataBase extends RoomDatabase {public abstract SearchHistoryDao searchHistoryDao();}

对了,差点忘记 Converters 了,在数据库中使用枚举  JSONObject 需要为其创建一个转换器

public class Converters {@TypeConverterpublic static SearchType toSearchType(String value) {return value == null ? null : SearchType.valueOf(value);}@TypeConverterpublic static String fromSearchType(SearchType searchType) {return searchType == null ? null : searchType.name();}
}
  1. 创建 单利 DbUtil 帮助类
public class DbUtil {private AppDataBase appDataBase;private static DbUtil instance;private Context context;private String dbName;public static DbUtil getInstance() {if (instance == null) {instance = new DbUtil();}return instance;}public void init(Context context,String dbName) {this.context =context.getApplicationContext();this.dbName = dbName;appDataBase = null;}public AppDataBase getAppDataBase() {if (appDataBase == null) {if (TextUtils.isEmpty(dbName)) {throw new NullPointerException("dbName is null");}appDataBase = Room.databaseBuilder(context, AppDataBase.class, dbName).allowMainThreadQueries().enableMultiInstanceInvalidation()
//                    .addMigrations(MIGRATION_1_2).addCallback(sRoomDatabaseCallback).build();}return appDataBase;}/*** 数据库版本 1->2 user表格新增了age列*/static final Migration MIGRATION_1_2 = new Migration(1, 2) {@Overridepublic void migrate(SupportSQLiteDatabase database) {}};/*** 数据库版本 2->3 新增book表格*/static final Migration MIGRATION_2_3 = new Migration(2, 3) {@Overridepublic void migrate(SupportSQLiteDatabase database) {}};private static RoomDatabase.Callback sRoomDatabaseCallback =new RoomDatabase.Callback() {@Overridepublic void onCreate(@NonNull SupportSQLiteDatabase db) {super.onCreate(db);db.execSQL("CREATE TRIGGER limit_search_history_count " +"AFTER INSERT ON SearchHistoryEntity " +"WHEN (SELECT COUNT(*) FROM SearchHistoryEntity) > 30 " +"BEGIN " +"DELETE FROM SearchHistoryEntity WHERE id = (SELECT id FROM SearchHistoryEntity ORDER BY searchTime ASC LIMIT 1); " +"END");}};}

MIGRATION_1_2 就是数据升级的操作,这里不做介绍。

  1. 创建 Repository
public class HomeSearchRepository extends BaseModel {private SearchHistoryDao searchHistoryDao;public HomeSearchRepository() {searchHistoryDao = DbUtil.getInstance().getAppDataBase().searchHistoryDao();}/*** Description:插入查询历史(name 相同,忽略策略)* author:clp* ModificationTime: 2024/12/26 13:06*/public long insertHis(SearchHistoryEntity entity) {return searchHistoryDao.insertPerson(entity);}
}
  1. 创建 ViewModel
ublic class HomeSearchViewModel extends BaseViewModel<HomeSearchRepository> {public MutableLiveData<List<SearchHistoryEntity>> searchHistories = new MutableLiveData<>();public HomeSearchViewModel(@NonNull Application application) {super(application);initAroundSearchDatas();gson = new Gson();}/*** 保存搜索历史** @param entity 搜索的内容*/public void insertHistory(SearchHistoryEntity entity) {if (isLogin) {uploadHistory(entity,true);} else {if (model.insertHis(entity) != -1) {searchHistories.postValue(model.getAllLoggedOutData());}}}
}

    isLogin 判断是否登录,

    登录状态 走接口上传,未登录状态 直接存入数据库,存入成功 postValue 到Activity 接收。

    Activity代码就不贴出来了。也就是

    ViewModel.observe(this, new Observer<List<SearchHistoryEntity>>() {@Overridepublic void onChanged(List<SearchHistoryEntity> searchHistoryEntities) {if (searchHistoryEntities != null) {mSearchHistoryAdapter.setNewData(searchHistoryEntities);}}
    });

    如果对Mvvm 框架使用感兴趣可以参考我上篇文章 Mvvm + viewModel

    http://www.dtcms.com/wzjs/400419.html

    相关文章:

  1. 鄱阳做网站朋友圈软文范例
  2. 做网站买什么书邵阳seo排名
  3. google网站登录入口鄂尔多斯seo
  4. 夏都通app下载最新版本太原网站建设优化
  5. 做网站网站加载内容慢怎么解决北京网站提升排名
  6. 网站后台管理系统多少钱百度关键词批量看排名工具
  7. 自己怎么做点击量好的网站googleseo推广
  8. 太和县建设银行网站百度关键词优化快速排名软件
  9. 网站服务器能更换吗爱站网长尾关键词挖掘查询工具
  10. 网站建设合同 英文公司网站开发费用
  11. wordpress多用户blog肇庆网站快速排名优化
  12. 网站为什么显示正在建设中怎么做网络营销推广
  13. 端子网站建设seo网站优化培训
  14. 鹤壁建设网站推广公司seo课程培训要多少钱
  15. 网站建设公司咋样百度手机助手下载安卓版
  16. 顶级设计网站推荐山西网络营销外包
  17. 怎样做淘宝联盟的网站产品软文是什么
  18. 城管网站内容建设方案谷歌seo视频教程
  19. 朋友做的网站图片不显示不出来上海谷歌seo推广公司
  20. intitle 郑州网站建设吉林黄页电话查询
  21. 网站备案密码格式潍坊网站开发公司
  22. 公司的网站建设费用怎么入账信息如何优化上百度首页
  23. wap网网站的优化
  24. 公司网站首页制作教程百度推广怎么收费标准案例
  25. 创办网站seo的流程是怎么样的
  26. 做推广送网站免费建站谷歌海外广告投放
  27. 做网站编辑有前途网页制作工具有哪些
  28. 做定制的B2b网站百度云网页版登录入口
  29. 临漳网站建站新东方英语培训机构官网
  30. 网站建设岗位的简介win10优化大师