使用ormlite封装数据库

来源:互联网 发布:网络语安利什么意思 编辑:程序博客网 时间:2024/04/29 15:55

  很多Android应用都需要用到本地SQLite数据库,然而Android对于数据库操作的原生API使用起来略显复杂。ormlite是应用于Android数据库的一个很牛的开源项目,它的亮点在于可以直接写入数据结构,进行对象的增删改查操作。更进一步,如果对ormlite略微进行封装,使用起来将更加方便。本文只介绍对于ormlite的封装,不介绍ormlite的基本用法,关于这个项目的用法,网上有很多介绍的帖子和博客,麻烦读者自行学习啦~
  整体结构设计思路如下:
  DatabaseHelper类管理数据包的创建和销毁,使用单例模式。在其内部维护一个HashMap,可以通过Bean类找到对应的DAO类。
  BaseBean类是所有Bean类的基类,它是抽象的空的类,只起标识的作用。其每一个子类对应一张数据表。
  接下来是DAO类。BaseDAO类主要完成两个工作:1、建立DAO子类与对应的Bean类的联系;2、提供基本的增删改查的方法,这些方法与数据表无关。
  闲话不多扯,下面上代码,首先是DatabaseHelper类,这个与网上很多栗子的设计思路相似。只不过增加了一个对于用户的判断,有很多用到数据库的App都是区分登录用户的,并且在用户登录之后将userId,用户名一类的信息存入到SharedPreference中,这里通过userId拿到数据库的db文件。

public class DatabaseHelper extends OrmLiteSqliteOpenHelper{    private static DatabaseHelper instance;    private static String mCurUserId = "";    private Map<String, Dao> daos = new HashMap<String, Dao>();    private DatabaseHelper(Context context, String databaseName, int databaseVersion)    {        super(context, databaseName, null, databaseVersion);    }    public static synchronized DatabaseHelper getHelper(Context context)    {        String userid = /*从SharedPreference中读到的userId*/;        if (instance == null || !userid.equals(mCurUserId) )        {            synchronized (DatabaseHelper.class)            {                if (instance == null || !userid.equals(mCurUserId) )                {                    instance = new DatabaseHelper(context,"YOUR_APP_NAME"+userid+".db", AppConstants.DATABASE_VERSION);                    mCurUserId = userid;                }            }        }        return instance;    }    public synchronized Dao getDao(Class cls) throws SQLException    {        Dao dao = null;        String className = cls.getSimpleName();        if (daos.containsKey(className))        {            dao = daos.get(className);        }        if (dao == null)        {            dao = super.getDao(cls);            daos.put(className, dao);        }        return dao;    }    /**     * 释放资源     */    @Override    public void close()    {        super.close();        for (String key : daos.keySet())        {            Dao dao = daos.get(key);            dao = null;        }    }    @Override    public void onCreate(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource)    {        try        {            TableUtils.createTableIfNotExists(connectionSource, xxxxBean.class);            TableUtils.createTableIfNotExists(connectionSource, xxxxxxxxBean.class);        }        catch (SQLException e)        {            e.printStackTrace();        }    }    @Override    public void onUpgrade(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource,                          int oldVersion, int newVersion)    {        try        {            TableUtils.dropTable(connectionSource, xxxxBean.class, true);            TableUtils.dropTable(connectionSource, xxxxxxxxBean.class, true);            onCreate(sqLiteDatabase,connectionSource);        }        catch (SQLException e)        {            e.printStackTrace();        }    }}

  这个类里的onCreate()和onUpgrade()方法不解释了,getHelper()方法用于获取实例,这里会判断如果用户id发生了改变(比如换小号登录),会读取或者创建新的db文件(取决于之前这个db文件是否存在)。类中daos这个变量就是保存Bean类和对应DAO类之间关系的HashMap,getDao()是通过Key获取Value的方法,daos这个变量会在close()方法中清理掉。

  前面说过,BaseBean类除了标识作用之外,没什么实际价值。

public abstract class BaseBean{}

  接下来是BaseDAO类,绝大多数代码都是基本的增删改查方法,所以重点看一下构造函数。

public abstract class BaseDAO<T extends BaseBean>{    protected Context context;    protected Dao<T,Integer> daoOpe;    protected DatabaseHelper helper;    /**     * 注意啦,由于数据库是区分用户的,因此应当在登录之后再调用子类的构造方法     * @param context     */    public BaseDAO(Context context)    {        this.context = context;        helper = DatabaseHelper.getHelper(context);        ParameterizedType pt = (ParameterizedType)getClass().getGenericSuperclass();        Class<T> cls = (Class<T>) pt.getActualTypeArguments()[0];        try        {            daoOpe = helper.getDao(cls);        }        catch (SQLException e)        {            e.printStackTrace();        }    }    public void add(T bean)    {        try        {            daoOpe.create(bean);        }        catch (SQLException e)        {            e.printStackTrace();        }    }    public void addIfNotExists(T bean)    {        try        {            daoOpe.createIfNotExists(bean);        }        catch (SQLException e)        {            e.printStackTrace();        }    }    public void delete(T bean)    {        try        {            daoOpe.delete(bean);        }        catch (SQLException e)        {            e.printStackTrace();        }    }    public void delete(Collection<T> beans)    {        try        {            daoOpe.delete(beans);        }        catch (SQLException e)        {            e.printStackTrace();        }    }    public void clearTable()    {        ParameterizedType pt = (ParameterizedType)getClass().getGenericSuperclass();        Class<T> cls = (Class<T>) pt.getActualTypeArguments()[0];        try        {            TableUtils.clearTable(helper.getConnectionSource(), cls);        }        catch (SQLException e)        {            e.printStackTrace();        }    }    public List<T> queryAll()    {        try        {            return daoOpe.queryForAll();        }        catch (SQLException e)        {            e.printStackTrace();            return null;        }    }    public List<T> queryAllOrder(String orderby, boolean asec)    {        try        {            QueryBuilder<T,Integer> qb = daoOpe.queryBuilder();            qb.orderBy(orderby, asec);            return daoOpe.query(qb.prepare());        }        catch (SQLException e)        {            e.printStackTrace();            return null;        }    }    /**     * 通常用于查找特定的一条记录     * @param key     * @param value     * @return     */    public List<T> queryWithConditon(String key, Object value)    {        try        {            return daoOpe.queryForEq(key, value);        }        catch (SQLException e)        {            e.printStackTrace();            return null;        }    }    public List<T> queryWithConditionOrder(String key, Object value, String orderby, boolean asec)    {        try        {            QueryBuilder<T,Integer> qb = daoOpe.queryBuilder();            qb.where().eq(key,value);            qb.orderBy(orderby,asec);            return daoOpe.query(qb.prepare());        }        catch (SQLException e)        {            e.printStackTrace();            return null;        }    }    /**     * 常用复合条件查询 不能查询不等式     * @param keys     * @param values     * @param orderby     * @param limit     * @param offset     * @param asec     * @return     */    public List<T> queryWithConditions(String[] keys,Object[] values,                       String orderby ,Long limit,Long offset, boolean asec)    {        if(keys.length != values.length)        {            throw new IllegalArgumentException("number of keys MUST BE SAME with number of values");        }        try        {            QueryBuilder<T,Integer> qb = daoOpe.queryBuilder();            for(int i=0;i<keys.length;i++)            {                qb.where().eq(keys[i],values[i]);            }            if(limit != null && limit.longValue()!=0)            {                qb.limit(limit );            }            if(orderby!=null)            {                qb.orderBy(orderby,asec);            }            if(offset!=null && offset.longValue()!=0)            {                qb.offset( offset );            }            return daoOpe.query(qb.prepare());        }        catch (SQLException e)        {            e.printStackTrace();            return null;        }    }    public void update(T bean)    {        try        {            daoOpe.update(bean);        }        catch (SQLException e)        {            e.printStackTrace();        }    }}

  在构造函数中,首先获取泛型类T(即Bean类的子类)的class对象,然后调用DatabaseHelper类中的getDao()方法,获得对应的DAO类对象,赋给daoOpe变量。后面定义的增删改查操作都是利用daoOpe对泛型类T进行操作的。
  在使用时BaseBean的子类只负责定义数据表,BaseDAO类的子类只负责关联Bean类和添加专用于数据表的操作。

/** * Créé par liusiqian 15/12/4. */@DatabaseTable(tableName = "student_info")public class StudentBean extends BaseBean{    @DatabaseField(generatedId = true)    private int _id;    @DatabaseField(canBeNull = false, defaultValue = "小明")    private String name;        //姓名    @DatabaseField()    private int age;            //年龄    @DatabaseField()    private String stuID;       //ID    public StudentBean()    {    }    public StudentBean(String name, int age, String stuID)    {        this.name = name;        this.age = age;        this.stuID = stuID;    }    public String getName()    {        return name;    }    public void setName(String name)    {        this.name = name;    }    public int getAge()    {        return age;    }    public void setAge(int age)    {        this.age = age;    }    public String getStuID()    {        return stuID;    }    public void setStuID(String stuID)    {        this.stuID = stuID;    }}
/** * Créé par liusiqian 15/12/4. */public class StudentDAO extends BaseDAO<StudentBean>{    public StudentDAO(Context context)    {        super(context);    }    public boolean addSingleStudent(String stuId, String name, int age)    {        StudentBean bean = querySingleStudent(stuId);        if (null == bean)        {            add(new StudentBean(name, age, stuId));            return true;        }        else        {            bean.setName(name);            bean.setAge(age);            update(bean);            return false;        }    }    public boolean deleteSingleStudent(String stuId)    {        StudentBean bean = querySingleStudent(stuId);        if (null != bean)        {            delete(bean);            return true;        }        return false;    }    public StudentBean querySingleStudent(String stuId)    {        List<StudentBean> students = queryWithConditon("stuId", stuId);        if (students == null || students.size() == 0)        {            return null;        //not found        }        else if (students.size() == 1)        {            return students.get(0);        }        else        {            throw new IllegalStateException("存在相同stuId的记录");        }    }    public void updateStudentAge(String stuId, int age)    {        StudentBean bean = querySingleStudent(stuId);        if (null != bean)        {            bean.setAge(age);            update(bean);        }    }}

  在使用的时候,直接调用各个DAO类的方法即可,是不是灰常方便~~

    StudentDAO dao = new StudentDAO(this);    dao.addSingleStudent("144","张三",25);    dao.addSingleStudent("133","李四",23);    dao.deleteSingleStudent("133");
0 0