①后端商品搜索会有热搜和联想词库两种类型提供
②联想词库可以包含热搜和搜索历史
③根据词库版本号是否变更数据库更新数据库存储的词库,搜索记录不会删除
④热词和联想词库根据被搜索过的次数排序,搜索历史根据搜索的时间排序
⑤输入词联想匹配的时候,搜索历史按搜索时间优先排在前面,搜索词库匹配按被搜索次数排在后面
⑥打开搜索框未输入任何词,或者输入词后又清空,无搜索历史时,只显示搜索热词;有搜索历史,优先显示搜索历史,搜索历史有删除按钮
⑦会有标题标注搜索历史和热搜
字段 | 说明 |
---|---|
keyword | 单词名称,不可为空 |
count | 搜索次数,用于热词和联想词排序 |
time | 搜索时间,用于搜索历史排序 |
type | 单词的类型(历史,热词,联想词库),不可为空 |
使用参考的是greenDAO简单使用经验
最大性能(最快的 Android ORM)
易于使用API
高度优化
最小内存消耗
api接口可以直接通过对象类进行建表、增删改查等
①在原项目中新建一Java的Module取名为daogenerator,用于生成数据库操作所需的Dao类
build.gradle加入如下依赖
创建一个GreenDaoGenerator类用于生成所需的表格和字段
public class GreenDaoGenerator {
public static void main(String[] args) throws Exception {
int version = 1;
String defaultJavaPackage = "com.sailvan.dealsale.greendao";
// 第一个参数用来更新数据库版本号,第二个参数为要生成的DAO类所在包路径
Schema schema = new Schema(version, defaultJavaPackage);
// 生成表
addTable(schema);
// 第一个参数是Schema对象,第二个参数是希望自动生成的代码对应的项目路径
new DaoGenerator().generateAll(schema, "./demo/src/main/java-gen");
}
private static void addTable(Schema schema) {
// Entity表示一个实体可以对应成数据库中的表,这里表名就是SearchKeywordsTable
Entity note = schema.addEntity("SearchKeywordsTable");
// 添加ID字段
note.addIdProperty();
// 添加keyword字段,不允许为空
note.addStringProperty("keyword").notNull();
// 添加搜索次数字段
note.addLongProperty("count");
// 添加搜索时间字段
note.addLongProperty("time");
// 添加类型字段不允许为空
note.addIntProperty("type").notNull();
}
}
DaoGenerator().generateAll(schema, “./demo/src/main/java-gen”);第二个参数是希望自动生成的代码对应的项目路径,demo项目和java项目daogenerator处于同一级目录,注意的是java-gen必须手动创建
运行GreenDaoGenerator 代码成功后生成DaoMaster、DaoSession、SearchkeywordTable、SearchkeywordTableDao四个文件
②demo项目使用GreenDao的api完成CRUD
build.gradle加入如下依赖
CRUD的实现方法如下:
Bean如下
public class SearchKeywords {
public String keyword;
public long value;
public long time;
public int type;
public SearchKeywords(String keyword, long value, long time, int type) {
this.keyword = keyword;
this.value = value;
this.time = time;
this.type = type;
}
}
方法如下
private SearchKeywordsTableDao mKeywordsTableDao;
private Activity mContext = this;
/** * 获取数据库操作对象 * ①先创建了一个SQLiteOpenHelper并创建连接到一个具体数据库 * ②再根据具体的datebase创建一个master对象用于session * ③最后通过master创建一个数据库的会话操作 * * @param tableDao 数据库dao * @return 数据库dao,通常对应具体的java类,其有更多的权限和方法来操作数据库元素。 */
private SearchKeywordsTableDao getSearchKeywordsTableDao(SearchKeywordsTableDao tableDao) {
if (tableDao != null) return tableDao;
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(mContext, Constant.DB_NAME, null);
SQLiteDatabase db = helper.getWritableDatabase();
// 保存了sqlitedatebase对象以及操作DAO classes(注意:不是对象)。其提供了一些创建和删除table的静态方法,其内部类OpenHelper和DevOpenHelper实现了SQLiteOpenHelper并创建数据库的框架。
DaoMaster daoMaster = new DaoMaster(db);
// 会话层。操作具体的DAO对象(注意:是对象),比如各种getter方法
DaoSession daoSession = daoMaster.newSession();
return daoSession.getSearchKeywordsTableDao();
}
/** * 数据库插入搜索数据 * * @param keywords 搜索词名称list */
private void insertSearchKeywordsToDb(List<SearchKeywords> keywords) {
for (SearchKeywords info : keywords) {
SearchKeywordsTable keywordsTable = new SearchKeywordsTable(null,
info.keyword, info.value, info.time, info.type);
mKeywordsTableDao.insertOrReplace(keywordsTable);
}
}
/** * 插入历史纪录到数据库 * * @param info 搜索的单词 */
private void insertHistorySearchKeywordsToDb(SearchKeywords info) {
// 数据库存在此历史时删除之
clearSearchKeyWords(info.keyword);
// 然后再插入
SearchKeywordsTable keywordsTable = new SearchKeywordsTable(null,
info.keyword, info.value, info.time, info.type);
mKeywordsTableDao.insertOrReplace(keywordsTable);
}
/** * 根据搜索类型查找数据,放到list,用于填充RecycleView * * @param searchList list * @param type 搜索类型(历史、热搜、联想词) * @return 搜索的结果集合 */
private List<SearchKeywordsTable> insertKeywordsToRecyclerView(ArrayList<String>
searchList, int type) {
QueryBuilder<SearchKeywordsTable> qb = mKeywordsTableDao.queryBuilder();
qb.where(SearchKeywordsTableDao.Properties.Type.eq(type));
// 热搜根据搜索数排序,历史根据搜索时间排
qb.orderDesc(type == Constant.SEARCH_KEYWORDS_HOT ?
SearchKeywordsTableDao.Properties.Count :
SearchKeywordsTableDao.Properties.Time);
List<SearchKeywordsTable> tables = qb.list();
for (SearchKeywordsTable table : tables) {
searchList.add(table.getKeyword());
}
return tables;
}
/** * 根据输入的词查找数据库匹配的数据,放到list中,用于填充RecycleView * 用于输入单词的时候联想匹配单词 * ①首先匹配历史,排序按搜索的时间 * ②然后匹配联想词库,排序按搜索的次数,如果词库包含搜索历史,则不匹配因为第一步已经匹配 * * @param hotSearchList list * @param word 输入单词 * @return 搜索的结果集合 */
private List<SearchKeywordsTable> insertMatchKeywordsToRecycleView(ArrayList<String> hotSearchList, String word) {
// 先查找历史,按时间排序
List<SearchKeywordsTable> tables = mKeywordsTableDao.queryBuilder()
.where(SearchKeywordsTableDao.Properties.Keyword.like("%" + word + "%"),
SearchKeywordsTableDao.Properties.Type.eq(Constant.SEARCH_KEYWORDS_HISTORY))
.orderDesc(SearchKeywordsTableDao.Properties.Time)
.list();
for (SearchKeywordsTable table : tables) {
hotSearchList.add(table.getKeyword());
DebugLog.e("查找历史有匹配");
}
// 然后查找词库,按次数排序
List<SearchKeywordsTable> tables1 = mKeywordsTableDao.queryBuilder()
.where(SearchKeywordsTableDao.Properties.Keyword.like("%" + word + "%"),
// 热词不包括在联想里面,因为联想里面会包含热词
SearchKeywordsTableDao.Properties.Type.eq(Constant.SEARCH_KEYWORDS_ALL))
.orderDesc(SearchKeywordsTableDao.Properties.Count)
.list();
for (SearchKeywordsTable table : tables1) {
// 没跟历史词重复才添加上去
if (!hotSearchList.contains(table.getKeyword())) {
DebugLog.e("查找词库有匹配,且不跟历史重复");
hotSearchList.add(table.getKeyword());
}
}
return tables;
}
/** * 数据库清除某个搜索历史 */
private void clearSearchKeyWords(String keyword) {
DeleteQuery<SearchKeywordsTable> dq = mKeywordsTableDao.queryBuilder()
.where(SearchKeywordsTableDao.Properties.Keyword.eq(keyword), SearchKeywordsTableDao.Properties.Type.eq(Constant.SEARCH_KEYWORDS_HISTORY))
.buildDelete();
dq.executeDeleteWithoutDetachingEntities();
}
/** * 数据库清空搜索历史以外的数据 */
private void clearTopAndAssociativeSearchKeyWords() {
// 将不是历史的清空掉
mKeywordsTableDao = getSearchKeywordsTableDao(mKeywordsTableDao);
DeleteQuery<SearchKeywordsTable> dq = mKeywordsTableDao.queryBuilder()
.where(SearchKeywordsTableDao.Properties.Type.notEq(Constant.SEARCH_KEYWORDS_HISTORY))
.buildDelete();
dq.executeDeleteWithoutDetachingEntities();
}
/** * 数据库清空搜索历史的数据,用于一键情况历史纪录 */
private void clearHisotySearchKeyWords() {
// 将不是历史的清空掉
mKeywordsTableDao = getSearchKeywordsTableDao(mKeywordsTableDao);
DeleteQuery<SearchKeywordsTable> dq = mKeywordsTableDao.queryBuilder()
.where(SearchKeywordsTableDao.Properties.Type.eq(Constant.SEARCH_KEYWORDS_HISTORY))
.buildDelete();
dq.executeDeleteWithoutDetachingEntities();
}