Android系统内部集成了SQLite数据库,可是杯具的却没有Android系统可用的Hibernate。
想当初做JavaEE时有Hibernate在手的那个飘逸,我尝试用JavaEE的思路封装了一个类似的工具包。(感谢“编程浪子”在JavaEE上给我的帮助)
?
首先,晒晒我的包结构:
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
大家可以看到,我在项目中创建了两个SourceFolder。其中core文件夹下存放的都是通用代码,可以在其他项目中重复使用(当然最好是导出jar包了)。org.dw.core.utils包下是一些工具类,所提供的都是静态方法(可以开源的)。org.dw.core.db包下就是数据库的操作工具了。EntityDao是一个泛型接口,定义了CRUD的方法,其他实体DAO都要实现她。目前只做到这一步,下一步将利用反射实现更高级的封装。
?
上代码:
/** * 基本DAO接口 * @author EwinLive * * @param <T> * @param <PK> */ public interface EntityDao<T, PK extends Serializable> { /** * 添加 * @param entity */ void save(final T entity); /** * 移除记录(指定ID集) * @param ids 可以有多个 */ void remove(final PK... ids); /** * 更新 * @param entity */ void upDate(final T entity); /** * 按ID查询对象 * @param id * @return */ T find(final PK id); /** * 分页查询 * @param startResult 开始位置 * @param maxResult 记录容量 * @return */ List<T> getScroolData(Integer startResult, Integer maxResult); /** * 返回记录总数 * @return */ public Long getCount(); }
?
我的项目中要对消息实体"SimpleMessage"实现数据库的CRUD操作,只需要创建一个实现了"EntityDao"接口的"SimpleMessageDao"(可以观察一下包的位置)。这样做不仅可以简化代码结构,而且可以大大减少SQL语句的编写。
上代码:
/** * 简单消息DAO * SQLite * dbHelper * @author EwinLive * *事务处理示例: SQLiteDatabase sdb = dbHelper.getReadableDatabase(); sdb.beginTransaction();//开启事务 try { sdb.execSQL("XXXXX"); sdb.execSQL("YYYYY"); sdb.setTransactionSuccessful();//设置事务成功标志 } catch (SQLException e) { e.printStackTrace(); } sdb.endTransaction();//提交事务 */ public class SimpleMessageDao implements EntityDao<SimpleMessage, Integer> { /** * 表名 */ public static final String TABLE = "simple_message"; /** * 数据库管理器 * 注意:dbHelper.getReadableDatabase(),会先以可读写方式访问数据库,当磁盘空间已满时会切换到只读方式。 */ DataBaseHelper dbHelper; public SimpleMessageDao(Context context) { super(); dbHelper = new DataBaseHelper(context); } @Override public void save(SimpleMessage entity) { dbHelper.getReadableDatabase().execSQL( "insert into "+ TABLE +"(title, content, time, accountId, consumerId) values(?,?,?,?,?)", new Object[]{entity.getTitle(),entity.getContent(),entity.getTime(),entity.getAccountId(),entity.getConsumerId()}); } @SuppressWarnings("unused") @Override public void remove(Integer... ids) { if(ids.length > 0){ StringBuffer sb = new StringBuffer(); for(Integer id : ids){ sb.append('?').append(','); } sb.deleteCharAt(sb.length() - 1); dbHelper.getReadableDatabase().execSQL( "delete from "+ TABLE +" where id in(" + sb + ")", (Object[]) ids); } } @Override public void upDate(SimpleMessage entity) { dbHelper.getReadableDatabase().execSQL( "update "+ TABLE +" set title=?, content=?, time=?, accountId=?, consumerId=? where id =?", new Object[]{entity.getTitle(),entity.getContent(),entity.getTime(),entity.getAccountId(),entity.getConsumerId(),entity.getId()}); } @Override public SimpleMessage find(Integer id) { Cursor cursor = dbHelper.getReadableDatabase().rawQuery("select * from " + TABLE + " where id=?", new String[]{String.valueOf(id)}); if(cursor.moveToNext()) return new SimpleMessage(cursor.getInt(0),cursor.getString(1),cursor.getString(2),cursor.getString(3),cursor.getInt(4),cursor.getInt(5)); return null; } @Override public List<SimpleMessage> getScroolData(Integer startResult, Integer maxResult) { List<SimpleMessage> messages = new ArrayList<SimpleMessage>(0); Cursor cursor = dbHelper.getReadableDatabase().rawQuery("select * from " + TABLE + " limit ?, ?", new String[]{String.valueOf(startResult), String.valueOf(maxResult)}); while(cursor.moveToNext()){ messages.add(new SimpleMessage(cursor.getInt(0),cursor.getString(1),cursor.getString(2),cursor.getString(3),cursor.getInt(4),cursor.getInt(5))); } return messages; } @Override public Long getCount() { Cursor cursor = dbHelper.getReadableDatabase().rawQuery("select count(*) from " + TABLE, null); if(cursor.moveToNext()) return cursor.getLong(0); return 0l; } }?
这样就可以在你需要查寻数据的地方创建一个"SimpleMessageDao"对象来实现数据库的操作了。
比如要查询所有消息,并以ListView显示出来就很简单了(呵呵,再也不用被那个变态的"SimpleCursorAdapter"搞崩溃了吧!):
?
/** * 初始化消息列表 */ public void initMessageListView(){ ListView list = (ListView) Main.this.findViewById(R.id.message_list); //列表数据 List<HashMap<String, String>> messageListData = new ArrayList<HashMap<String, String>>(); //查询数据 SimpleMessageDao smDao = new SimpleMessageDao(Main.this); List<SimpleMessage> messages = smDao.getScroolData(1, 20); //添加数据 HashMap<String, String> message; for(SimpleMessage sm : messages){ message = new HashMap<String, String>(); message.put("id", String.valueOf(sm.getId())); message.put("content", sm.getContent()); message.put("time", sm.getTime()); messageListData.add(message); } //组装适配器 SimpleAdapter adapter = new SimpleAdapter( Main.this, messageListData, R.layout.message_list_item,//列表条目的布局样式 new String[]{"id", "content", "time"},//对应HashMap的Key new int[]{R.id.message_id, R.id.message_content, R.id.message_time});//对应TextView的id list.setAdapter(adapter); //设置条目监听器 list.setOnItemClickListener(new OnItemClickListener(){ @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { ListView listView = (ListView) parent; @SuppressWarnings("unchecked") HashMap<String, String> data = (HashMap<String, String>) listView.getItemAtPosition(position); Toast.makeText(Main.this, "ID: " + data.get("id") + " \nContent: " + data.get("content") + "\nTime: " + data.get("time"), Toast.LENGTH_SHORT).show(); } }); }?
到目前为止,这个工具类还很简单。如果加上BeanUtils实现方向解析实体,整个代码会更加简洁。