浅析郭婶儿子--LitePal框架(三)

毕业半年了,Android也学习了半年了,零零散散的学了一些,漫无目的,于是看了看郭哥的<<第一行代码>>,真心觉得不错,对于没有系统培训过Android的来说,是一本很好的书籍,忘了谁问过我怎么学Android,说实在的我也不知道,我也是个小菜,但是看过这本书之后,推荐去看一看,对于新手来说是本很好地资料,对于接触过的人来说可以好好玩完善你的知识体系,当然没人都有自己的认识,以上只是代表我的个人观点.

今天我们继续接上回讲说LitePal框架源码浅析,本博客只是浅析,更详细的移步到源码那去看.

1.使用LitePal修改数据

修改单条数据:

DataSupport.update(modelClass, values, id);根据id修改数据库内容,那我们来研究一下他的代码

public static synchronized int update(Class<?> modelClass, ContentValues values, long id) {
		UpdateHandler updateHandler = new UpdateHandler(Connector.getDatabase());
		return updateHandler.onUpdate(modelClass, id, values);
	}

首先获得SQLiteDatabase,然后调用UpdateHandle中的onUpdate方法,那我们就继续看onUpdate方法吧!

int onUpdate(Class<?> modelClass, long id, ContentValues values) {
		if (values.size() > 0) {
			return mDatabase.update(getTableName(modelClass), values, "id = " + id, null);
		}
		return 0;
	}

看到熟悉的代码了,这里就是你理解的那样了,使用传统数据库的更新功能

还有另一种方法也是根据id更新数据库的单条数据:

news.update(2);实体对象调用update方法,废话少说直接看update源码,估计应该和上面的onUpdate方法的代码差不多,猜测完毕,上源码

public synchronized int update(long id) {
		try {
			UpdateHandler updateHandler = new UpdateHandler(Connector.getDatabase());
			int rowsAffected = updateHandler.onUpdate(this, id);
			getFieldsToSetToDefault().clear();
			return rowsAffected;
		} catch (Exception e) {
			throw new DataSupportException(e.getMessage());
		}
	}

果然不出所料,还是调用了UpdateHandle方法里面的onUpdate方法,只是参数不相同

int onUpdate(DataSupport baseObj, long id) throws SecurityException, IllegalArgumentException,
			NoSuchMethodException, IllegalAccessException, InvocationTargetException {
		List<Field> supportedFields = getSupportedFields(baseObj.getClassName());
		ContentValues values = new ContentValues();
		putFieldsValue(baseObj, supportedFields, values);
		putFieldsToDefaultValue(baseObj, values);
		if (values.size() > 0) {
			return mDatabase.update(baseObj.getTableName(), values, "id = " + id, null);
		}
		return 0;
	}

这里只看update,上面两个方法主要是给value赋值,下面的部分就是传统的操作数据库更新的内容了.

上面主要介绍的通过id更新数据库的单条信息,下面介绍一下,多条信息的更新,当然也可以使用下面方法更新单条信息.

public static synchronized int updateAll(Class<?> modelClass, ContentValues values,
			String... conditions) {
		return updateAll(BaseUtility.changeCase(modelClass.getSimpleName()), values, conditions);
	}

这里通过changeCase方法把实体名转换成String类型的表名,具体如何实现自行去看代码吧,这里略过,我们继续看调用的updateAll方法

ublic static synchronized int updateAll(String tableName, ContentValues values,
			String... conditions) {
		UpdateHandler updateHandler = new UpdateHandler(Connector.getDatabase());
		return updateHandler.onUpdateAll(tableName, values, conditions);
	}

又到这里了,调用UpdateHandle方法中的onUpdateAll方法,应该跟上面的onUpdate差不多

int onUpdateAll(String tableName, ContentValues values, String... conditions) {
		return doUpdateAllAction(tableName, values, conditions);
	}

嗯?怎么不太一样,不要着急,我们继续看

private int doUpdateAllAction(String tableName, ContentValues values, String... conditions) {
		BaseUtility.checkConditionsCorrect(conditions);
		if (values.size() > 0) {
			return mDatabase.update(tableName, values, getWhereClause(conditions),
					getWhereArgs(conditions));
		}
		return 0;
	}

又看到你熟悉的代码了,没错,就是传统的操作数据库的方法,这里只是把方法继续做了封装

当然update不止这一个方法,它还有好几种方法,我们继续看

public synchronized int updateAll(String... conditions) {
		try {
			UpdateHandler updateHandler = new UpdateHandler(Connector.getDatabase());
			int rowsAffected = updateHandler.onUpdateAll(this, conditions);
			getFieldsToSetToDefault().clear();
			return rowsAffected;
		} catch (Exception e) {
			throw new DataSupportException(e.getMessage());
		}
	}

还是那个配方,还是那个味道,这里就不叙述了,使用实体对象直接调用updateAll方法也同样使用了上面这段代码

2.使用LitePal删除数据

删除也有很多方法,当然郭哥也提供了通过id直接删除,下面我们就先从通过id删除数据开始看源码

public static synchronized int delete(Class<?> modelClass, long id) {
		int rowsAffected = 0;
		SQLiteDatabase db = Connector.getDatabase();
		db.beginTransaction();
		try {
			DeleteHandler deleteHandler = new DeleteHandler(db);
			rowsAffected = deleteHandler.onDelete(modelClass, id);
			db.setTransactionSuccessful();
			return rowsAffected;
		} finally {
			db.endTransaction();
		}
	}

如果你看懂了更新是如何实现,看上面的这段代码应该很简单,获得SQLiteDatabase,然后开启事务,调用DeleteHandle函数里的onDelete方法实现删除,如果你对上面的更新数据有印象的话,你应该猜到在onDelete方法里面使用传统操作数据库的方法将数据删除,下面贴一下代码:

int onDelete(Class<?> modelClass, long id) {
		analyzeAssociations(modelClass);
		int rowsAffected = deleteCascade(modelClass, id);
		rowsAffected += mDatabase.delete(getTableName(modelClass), "id = " + id, null);
		getForeignKeyTableToDelete().clear();
		return rowsAffected;
	}

这里注意一下,上面忘了说,这里id为主键,增删改查时都要操作外键,保证数据统一,上面这段代码使用传统的操作数据库的方法删除数据,原理和上面的差不多

当然LitePal也支持根据条件删除数据DataSupport.deleteAll(modelClass, conditions);下面看一下源码:

public static synchronized int deleteAll(Class<?> modelClass, String... conditions) {
		return deleteAll(BaseUtility.changeCase(modelClass.getSimpleName()), conditions);
	}

跟更新一样先将实体转化为string类型的表名,然后调用deleteAll方法实现根据条件删除

private int doDeleteAllAction(String tableName, String... conditions) {
		BaseUtility.checkConditionsCorrect(conditions);
		return mDatabase.delete(tableName, getWhereClause(conditions), getWhereArgs(conditions));
	}

同样的实体对象调用delete方法也跟更新类似

public static synchronized int delete(Class<?> modelClass, long id) {
		int rowsAffected = 0;
		SQLiteDatabase db = Connector.getDatabase();
		db.beginTransaction();
		try {
			DeleteHandler deleteHandler = new DeleteHandler(db);
			rowsAffected = deleteHandler.onDelete(modelClass, id);
			db.setTransactionSuccessful();
			return rowsAffected;
		} finally {
			db.endTransaction();
		}
	}

如果上面你都看懂了的话,看到这段代码你应该很高兴,好了,今天就先扯这么多,现在你应该对LitePal框架比较了解了,后续还会更新,有疑问的留言撒~~~

时间: 2024-12-21 08:08:51

浅析郭婶儿子--LitePal框架(三)的相关文章

浅析郭婶儿子--LitePal框架(一)

最近看了郭神的LitePal框架感觉愣牛逼,牛逼之余,也很好奇他是如何实现的,好奇心害死猫啊!跟随大神脚步,看源码. 1.在使用LitePal框架的时候,在项目的assets目录下面新建一个litepal.xml文件,其中的内容包括数据库的名称,版本,以及映射,那它如何去把这些内容映射进去的? 先贴一下litepal.xml代码: <?xml version="1.0" encoding="utf-8"?> <litepal> <!--

关于郭婶Litepal框架,保存和修改返回值提示成功,但是数据库的值没改变的问题

如题,一直在使用郭婶的litepal,真的很方便的一个框架,郭婶的博客中也讲的很详细,上手很快,不过,今天在我的项目中发现了这么一个问题,就是我update后,返回了1,说明我更新成功了一条数据,但是,我再次打开的时候,发现那条数据没有变,我又试了试保存,也有同样的问题,但是有时候又是正常的,通过查看源码发现,郭婶的数据库里面是有做过优化的,直接删了两个条件,也就是去掉优化,结果就立刻解决了,不过应该还有更好的办法,我时间来不及就直接删掉了优化的部分. DataHandler中有个判断在917-

企业级应用框架(三)三层架构之数据访问层的改进以及测试DOM的发布

在上一篇我们在宏观概要上对DAL层进行了封装与抽象.我们的目的主要有两个:第一,解除BLL层对DAL层的依赖,这一点我们通过定义接口做到了:第二,使我们的DAL层能够支持一切数据访问技术,如Ado.net,EF,linq To Sql,这一点我们实现的不是很完美,仍有很大的改进空间,本文将加以改进. 在此之前我们来看一下我们最新的dom(PS:经过两天的赶工,我们的dom已经相对成熟,其中BLL层已经被我高度抽象化了,并且引进了业务上文文的概念:DAL层除了具体的技术实现尚为完成,其他方面已经相

类集框架(三)

1. Map和HashMap的使用方法 2. JDK帮助文档的使用方法 1. Map和HashMap的使用方法 2. JDK帮助文档的使用方法 帮助文档下载chm格式的英文版, 在索引里面搜索Map 1 import java.util.Map; 2 import java.util.HashMap; 3 4 public class Test{ 5 public static void main(String args []){ 6 HashMap<String,String> hashMa

子查询的三种使用方式

子查询的三种使用方式: 1,子查询作为条件 1>如果是跟在> < >= <= = != <>后面就必须保证子查询             只返回单个值,如果是返回多行一列,那么就需要使用in来指定范围,如果是返回一行多列,那么就报错 Eg:(多行一列) Select * from Student where ClassId in (select ClassId from grade) 2,子查询作为结果集(可以将from后面的表用虚拟结果集进行替换) //根据主键

写自己的Socket框架(三)

在通信写完了以后,应用层接收到Socket抛上来的byte[],这个时候对于实际的写逻辑的开发者来说,这样的数据并不友好,我们就需要在应用层统一一个包的规则(应用层协议),处理完以后,然后再传给实际的逻辑层去处理. 以下是一个常用的Command模式.既接收到传递过来的包以后,根据Command(命令)来执行对应的Command(逻辑). 我们假定我们的包(以下所有的包都指的是应用层的包,而非Socket层的包)分为 命令头/数据 两块. public class InterUnit { pub

多线程 创建子父线程 保证一件事 子线程执行三次后 父线程执行5次 循环10次

package Thread; /** * 创建子父线程 保证一件事 子线程执行三次后 父线程执行5次 循环10次 * 父线程main线程则为Console台项目的主线程 * 在main线程中调用了start线程则为子线程 * */ public class FatherAndSonTest { public static void main(String[] args) { final FatherAndSon fs = new FatherAndSon(); new Thread(new R

从零开始实现一个简易的Java MVC框架(三)--实现IOC

Spring中的IOC IoC全称是Inversion of Control,就是控制反转,他其实不是spring独有的特性或者说也不是java的特性,他是一种设计思想.而DI(Dependency Injection),即依赖注入就是Ioc的一种实现方式.关于Ioc和DI的具体定义和优缺点等大家可以自行查找资料了解一下,这里就不详细赘述,总之spring的IoC功能很大程度上便捷了我们的开发工作. 在实现我们的Ioc之前,我们先了解一下spring的依赖注入,在spring中依赖注入有三种方式

scrapy框架(三)

scrapy框架(三) CrawlSpider类 创建CrawlSpider  # 创建项目后 $ scrapy genspider -t crawl spider_name website_domain ? url 就是你想要爬取的网址 注意:分析本地文件是一定要带上路径,scrapy shell默认当作url ? 介绍: CrawlSpider类继承自spider类 CrawlSpiders url规则 自动生成Request请求 Rule  Rule用来定义CrawlSpider的爬取规则