使用ormlite封装数据库

  很多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");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值