SearchView+RecyclerView+GreenDao的搜索功能实现(1)

来源:互联网 发布:网络平台投稿 编辑:程序博客网 时间:2024/05/16 15:22

功能需求如下:

①后端商品搜索会有热搜和联想词库两种类型提供

②联想词库可以包含热搜和搜索历史

③根据词库版本号是否变更数据库更新数据库存储的词库,搜索记录不会删除

④热词和联想词库根据被搜索过的次数排序,搜索历史根据搜索的时间排序

⑤输入词联想匹配的时候,搜索历史按搜索时间优先排在前面,搜索词库匹配按被搜索次数排在后面

⑥打开搜索框未输入任何词,或者输入词后又清空,无搜索历史时,只显示搜索热词;有搜索历史,优先显示搜索历史,搜索历史有删除按钮

⑦会有标题标注搜索历史和热搜

表设计如下

字段 说明 keyword 单词名称,不可为空 count 搜索次数,用于热词和联想词排序 time 搜索时间,用于搜索历史排序 type 单词的类型(历史,热词,联想词库),不可为空

GreenDao的使用

使用参考的是greenDAO简单使用经验

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();    }
0 0
原创粉丝点击