XUtils下载地址 http://www.oschina.net/p/xutils
以下是对demo的分析
进入DbFragment
首先看到的是
- DbManager.DaoConfig daoConfig = new DbManager.DaoConfig()
- .setDbName("test")
- .setDbDir(new File("/sdcard")) // "sdcard"的写法并非最佳实践, 这里为了简单, 先这样写了.
- .setDbVersion(2)
- .setDbUpgradeListener(new DbManager.DbUpgradeListener() {
- @Override
- public void onUpgrade(DbManager db, int oldVersion, int newVersion) {
- // TODO: ...
- // db.addColumn(...);
- // db.dropTable(...);
- // ...
- }
- });
此代码大致写了关于数据库名称、版本、路径以及更新操作
所以可以进入 new DbManager.DaoConfig() 中去查看具体信息
- <pre name="code" class="java">public interface DbManager extends Closeable
DbManager中的内部类定义了相关数据库配置、更新信息
- public static class DaoConfig {
- private File dbDir;
- private String dbName = "xUtils.db"; // default db name
- private int dbVersion = 1;
- private boolean allowTransaction = true;
- private DbUpgradeListener dbUpgradeListener;
- private TableCreateListener tableCreateListener;
此处注意对象的==与equals的不同
DaoConfig包含如下代码
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- DaoConfig daoConfig = (DaoConfig) o;
- if (!dbName.equals(daoConfig.dbName)) return false;
- return dbDir == null ? daoConfig.dbDir == null : dbDir.equals(daoConfig.dbDir);
- }
- @Override
- public int hashCode() {
- int result = dbName.hashCode();
- result = 31 * result + (dbDir != null ? dbDir.hashCode() : 0);
- return result;
- }
接口分析大致结束
然后回到DbFragment查看数据库具体操作
- private void onTestDbClick(View view) {
- // 一对多: (本示例的代码)
- // 自己在多的一方(child)保存另一方的(parentId), 查找的时候用parentId查parent或child.
- // 一对一:
- // 在任何一边保存另一边的Id并加上唯一属性: @Column(name = "parentId", property = "UNIQUE")
- // 多对多:
- // 再建一个关联表, 保存两边的id. 查询分两步: 先查关联表得到id, 再查对应表的属性.
- String temp = "";
- try {
- DbManager db = x.getDb(daoConfig);
此处真正的调用了数据库然后进入org.xutils.x;去查看具体实现
- /**
- * Created by wyouflf on 15/6/10.
- * 任务控制中心, http, image, db, view注入等接口的入口.
- * 需要在在application的onCreate中初始化: x.Ext.init(this);
- */
- public final class x {
- private x() {
- }
此处可以看出是所有模块的封装类
- public static DbManager getDb(DbManager.DaoConfig daoConfig) {
- return DbManagerImpl.getInstance(daoConfig);
- }
此处可以看到DbManagerImpl类
- public final class DbManagerImpl implements DbManager {
- //*************************************** create instance ****************************************************
- /**
- * key: dbName
- */
- private static HashMap<DaoConfig, DbManagerImpl> daoMap = new HashMap<DaoConfig, DbManagerImpl>();
- private SQLiteDatabase database;
- private DaoConfig daoConfig;
- private boolean allowTransaction;
- private DbManagerImpl(DaoConfig config) {
- if (config == null) {
- throw new IllegalArgumentException("daoConfig may not be null");
- }
- this.database = createDatabase(config);
- this.daoConfig = config;
- this.allowTransaction = config.isAllowTransaction();
- }
- public synchronized static DbManager getInstance(DaoConfig daoConfig) {
- if (daoConfig == null) {//使用默认配置
- daoConfig = new DaoConfig();
- }
- DbManagerImpl dao = daoMap.get(daoConfig);
- if (dao == null) {
- dao = new DbManagerImpl(daoConfig);
- daoMap.put(daoConfig, dao);
- } else {
- dao.daoConfig = daoConfig;
- }
- // update the database if needed
- SQLiteDatabase database = dao.database;
- int oldVersion = database.getVersion();
- int newVersion = daoConfig.getDbVersion();
- if (oldVersion != newVersion) {
- if (oldVersion != 0) {
- DbUpgradeListener upgradeListener = daoConfig.getDbUpgradeListener();
- if (upgradeListener != null) {
- upgradeListener.onUpgrade(dao, oldVersion, newVersion);
- } else {
- try {
- dao.dropDb();
- } catch (DbException e) {
- LogUtil.e(e.getMessage(), e);
- }
- }
- }
- database.setVersion(newVersion);
- }
- return dao;
- }
注意public final class DbManagerImpl 为final 并且private DbManagerImpl(DaoConfig config) 私有构造函数
上述代码创建了database 并保存到HashMap<DaoConfig, DbManagerImpl> daoMap = new HashMap<DaoConfig, DbManagerImpl>();
创建database代码
- private SQLiteDatabase createDatabase(DaoConfig config) {
- SQLiteDatabase result = null;
- File dbDir = config.getDbDir();
- if (dbDir != null && (dbDir.exists() || dbDir.mkdirs())) {
- File dbFile = new File(dbDir, config.getDbName());
- result = SQLiteDatabase.openOrCreateDatabase(dbFile, null);
- } else {
- result = x.app().openOrCreateDatabase(config.getDbName(), 0, null);
- }
- return result;
- }
如果数据库路径不存在那么使用默认路径并但会database
返回DbFragment继续往下走
看到关于数据库表的操作
- Parent test = db.selector(Parent.class).where("id", "in", new int[]{1, 3, 6}).findFirst();
关于
- public final class Selector<T> 与 public class WhereBuilder
- db.selector(Parent.class).where("id", "in", new int[]{1, 3, 6}) 产生sql语句
- </pre>此处代码是为了封装sql数据<p>一下是具体分析</p><p></p><pre name="code" class="java"> @Override
- public <T> Selector<T> selector(Class<T> entityType) throws DbException {
- return Selector.from(TableEntity.get(this, entityType));
- }
- public final class TableEntity<T> {
- private final DbManager db;
- private final String name;
- private final String onCreated;
- private ColumnEntity id;
- private Class<T> entityType;
- private Constructor<T> constructor;
- /**
- * key: columnName
- */
- private final LinkedHashMap<String, ColumnEntity> columnMap;
- /**
- * key: dbName#className
- */
- private static final HashMap<String, TableEntity<?>> tableMap = new HashMap<String, TableEntity<?>>();
- public class WhereBuilder
最后执行findFirst
- public T findFirst() throws DbException {
- if (!table.tableIsExist()) return null;
- this.limit(1);
- Cursor cursor = table.getDb().execQuery(this.toString());
- if (cursor != null) {
- try {
- if (cursor.moveToNext()) {
- return CursorUtils.getEntity(table, cursor);
- }
- } catch (Throwable e) {
- throw new DbException(e);
- } finally {
- IOUtil.closeQuietly(cursor);
- }
- }
- return null;
- }
到此第一个操作语句结束
接着往下看进入第二个与数据库操作有关的方法
db.save(parent);
进入DbManagerImpl实现代码
- @Override
- public void save(Object entity) throws DbException {
- try {
- beginTransaction();
- if (entity instanceof List) {
- List<?> entities = (List<?>) entity;
- if (entities.isEmpty()) return;
- TableEntity<?> table = TableEntity.get(this, entities.get(0).getClass());
- createTableIfNotExist(table);
- for (Object item : entities) {
- execNonQuery(SqlInfoBuilder.buildInsertSqlInfo(table, item));
- }
- } else {
- TableEntity<?> table = TableEntity.get(this, entity.getClass());
- createTableIfNotExist(table);
- execNonQuery(SqlInfoBuilder.buildInsertSqlInfo(table, entity));
- }
- setTransactionSuccessful();
- } finally {
- endTransaction();
- }
- }
此方法首先开启了事务,然后判断传入的对象是否是集合再进行数据操作、此处运用了instanceof去判断是否是集合
此方法中调用了createTableIfNotExist(table)和execNonQuery(SqlInfoBuilder.buildInsertSqlInfo(table, entity))首先判断表是否存在然后进行数据库操作
关于异常的处理程序中直接向外层抛出未做处理