赞
踩
问题一:使用GreenDao如何实现创建表、关联表(一对一,一对多,多对多)?
第一种: 使用SharedPreferences存储数据
1).跨进程调用
2).SharedPreferences 的commit和apply的区别
3).优缺点,使用场景
适用范围:保存少量的数据,且这些数据的格式非常简单:字符串型、基本类型的值。比如应用程序的各种配置信息(如是否打开音效、是否使用震动效果、小游戏的玩家积分等),解锁口 令密码等
核心原理:保存基于XML文件存储的key-value键值对数据,通常用来存储一些简单的配置信息。通过DDMS的File Explorer面板,展开文件浏览树,很明显SharedPreferences数据总是存储在/data/data/<package name>/shared_prefs目录下。
Context.MODE_PRIVATE: 指定该SharedPreferences数据只能被本应用程序读、写。
Context.MODE_WORLD_READABLE: 指定该SharedPreferences数据能被其他应用程序读,但不能写。
Context.MODE_WORLD_WRITEABLE: 指定该SharedPreferences数据能被其他应用程序读,写
SharedPreferences对象与SQLite数据库相比,免去了创建数据库,创建表,写SQL语句等诸多操作,相对而言更加方便,简洁。但是SharedPreferences也有其自身缺陷,比如其职能存储boolean,int,float,long和String五种简单的数据类型,比如其无法进行条件查询等。所以不论SharedPreferences的数据存储操作是如何简单,它也只能是存储方式的一种补充,而无法完全替代如SQLite数据库这样的其他数据存储方式。无法进行条件查询,只能在不复杂的存储需求下使用,比如保存配置信息等。
SharedPreferences 的commit和apply的区别
public void SaveData() {
//指定操作的文件名称
SharedPreferences share = context.getSharedPreferences(SILENAME, MODE_PRIVATE);
SharedPreferences.Editor edit = share.edit(); //编辑文件
edit.putInt("age", 22); //根据键值对添加数据
edit.putString("name", "LJie");
edit.commit(); //保存数据信息
}
public void LoadData() {
//指定操作的文件名称
SharedPreferences share = getSharedPreferences(SILENAME, MODE_PRIVATE);
tv1.setText("作者:"+share.getString("name", "信息为空..."));
tv2.setText("年龄:"+share.getInt("age", 0));
}
commit是原子提交到数据库,所以从提交数据到存在Disk中都是同步过程,中间不可打断。
apply方法的原子操作是原子提交的内存中,而非数据库,所以在提交到内存中时不可打断,之后再异步提交数据到数据库中,因此也不会有相应的返回值。
所有commit提交是同步过程,效率会比apply异步提交的速度慢,但是apply没有返回值,永远无法知道存储是否失败。
在不关心提交结果是否成功的情况下,优先考虑apply方法。
第二种: 文件存储数据
应用场景:
一。录音文件,图片
二。服务器的json和网络请求json数据
1)。权限问题
2)。存储的路径,内部和外部
核心原理: Context提供了两个方法来打开数据文件里的文件IO流 FileInputStream openFileInput(String name); FileOutputStream(String name , int mode),这两个方法第一个参数 用于指定文件名,第二个参数指定打开文件的模式。具体有以下值可选:
第三种:SQLite存储数据(重点)
1.基本的语句
2.数据库迁移和数据库升级
3.数据库优化
4.数据库的位置和查看工具
5.多张表,内联和外联,greedao的学习
6.数据库实务操作
7.数据不能乱,同步原理
8.数据库加密
9.android 数据库islock解决方案
10.数据库备份
11.应用场景
防止张数据,其实就是为了同步,多线程访问带来的问题
1:多线程 单例 SQLiteOpenHelper 可以同时读和写。
2.多线程访问单列是否是安全的
对象是安全的,和写法有关,可以保证只生产一个对象,
2.多线程 多个对象 SQLiteOpenHelper 不能同时读写(可以同时读)。
SQLite是轻量级嵌入式数据库引擎,它支持 SQL 语言,并且只利用很少的内存就有很好的性能。现在的主流移动设备像Android、iPhone等都使用SQLite作为复杂数据的存储引擎,在我们为移动设备开发应用程序时,也许就要使用到SQLite来存储我们大量的数据,所以我们就需要掌握移动设备上的SQLite开发技巧
应用场景:
1.天气预报
2.断点下载
3.手机资料备份
4.松鼠整理首页状态显示
Android sqlite3数据库管理工具
Android SDK的tools目录下提供了一个sqlite3.exe工具,这是一个简单的sqlite数据库管理工具。开发者可以方便的使用其对sqlite数据库进行命令行的操作。
程序运行生成的*.db文件一般位于"/data/data/项目名(包括所处包名)/databases/*.db",因此要对数据库文件进行操作需要先找到数据库文件:
1、进入shell 命令
<span style="color:gray"><span style="color:#000000">adb shell</span></span>
2、找到数据库文件
- <span style="color:gray"><span style="color:#000000">#cd data/data
- #ls --列出所有项目
- #cd project_name --进入所需项目名
- #cd databases
- #ls --列出现寸的数据库文件</span></span>
3、进入数据库
<span style="color:gray"><span style="color:#000000">#sqlite3 test_db --进入所需数据库</span></span>
会出现类似如下字样:
- <span style="color:gray"><span style="color:#000000">SQLite version 3.6.22
- Enter ".help" for instructions
- Enter SQL statements terminated with a ";"
- sqlite></span></span>
至此,可对数据库进行sql操作。
4、sqlite常用命令
- <span style="color:gray"><span style="color:#000000">>.databases --产看当前数据库
- >.tables --查看当前数据库中的表
- >.help --sqlite3帮助
- >.schema --各个表的生成语句
- </span></span>
来源: https://www.cnblogs.com/ITtangtang/p/3920916.html
三、解决方案
1.将数据加密后再写入数据库:
http://blog.csdn.net/guolin_blog/article/details/11952409
1)优点:
a. 实现数据加密快速,只需添加两个方法
一是:对明文数据进行加密返回密文数据
二是:对密文数据进行解密返回明文数据
b. 程序无需进行太大变动,仅在对数据进行添加,修改,删除,查询时。针对指定的表字段进行修改进行加密,解密的字段即可。
2)不足:
a. 由于对数据进行了加密。所以为了看到明文,必须密文进行解密。因此会增加处理器的消耗。因终端手机的处理能力有限,可能会出现处理数据缓慢的现象发生。
b. 仅仅对数据进行了加密,还是可以看到数据表的sql语句,可能猜测到表的作用。另外,如果没有对一个表中的所有字段加密,则可以看没有加密的明文数据。
这种方式使用简单,在入库/出库只需要将字段做对应的加解密操作即可,一定程度上解决了将数据赤裸裸暴露的问题,这种只是靠存取数据库时通过自己的一些算法加密解密,一定程度上会影响性能。
这种方式并不是彻底的加密,因为数据库的表结构等信息还是能被查看到。另外写入数据库的内容加密后,搜索也是个问题。
2. 对数据库文件加密
将整个数据库整个文件加密,这种方式基本上能解决数据库的信息安全问题。目前已有的SQLite加密基本都是通过这种方式实现的。
目前流行的是一款开源的SQLite加密工具 SQLCipher ,微信也在使用。 SQLCipher是完全开源的,其代码托管在github上。SQLCipher使用256-bit AES加密,由于其基于免费版的SQLite,主要的加密接口和SQLite是相同的,也增加了一些自己的接口。它有一个缺点就是使用该库之后会导致Apk会变大6M左右。下面就是具体介绍SQLCipher的使用方法。
GitHub
greenDAO与其他常见的ORM框架不同,其原理不是根据反射进行数据库的各项操作
,而是一开始就人工生成业务需要的Model和DAO文件
,业务中可以直接调用相应的DAO文件进行数据库操作,从而避免了因反射带来的性能损耗和效率低下。
以查询为例,其首先是创建数据库,然后在SQLiteOpenHelper.onCreate
方法中根据已生成的model创建所有的表,而db.query其实就是Android原生的查询操作
,只不过参数是经过DAO文件处理过的,无需手动匹配。
由于需要人工生成model和DAO文件,所以greenDAO的配置就略显复杂。
优点:效率高,速度快,文件较小,占用更少的内存,操作实体灵活
缺点:学习成本较高。
GitHub
基于注解和反射
的的方式,导致ormlite性能有着一定的损失(运行时注解其实也是利用了反射的原理)
OrmLite 不是 Android 平台专用的ORM框架,它是Java ORM
。支持JDBC连接,Spring以及Android平台。语法中广泛使用了运行时注解。
优点:文档较全面,社区活跃,有好的维护,使用简单,易上手。
缺点:基于反射,效率较低(GreenDAO比OrmLite要快几乎4.5倍)
GitHub
An Android library that makes developers use SQLite database extremely easy.
特点
来源: https://www.cnblogs.com/baiqiantao/p/9492180.html#ORMLite注解+反射1.5K通用
GitHub
官网
Insanely easy way to work with Android Database.
SugarORM 是 Android 平台专用ORM。提供简单易学的APIs,可以很容易的处理1对1和1对多的关系型数据,并通过3个函数save(), delete() 和 find() (或者 findById()) 来简化CRUD基本操作。
1.和fileProvider的区别
2.怎么创建和共享数据给别人
3.优点:跨进程
Android这个系统和其他的操作系统还不太一样,我们需要记住的是,数据在Android当中是私有的,当然这些数据包括文件数据和数据库数据 以及一些其他类型的数据。那这个时候有读者就会提出问题,难道两个程序之间就没有办法对于数据进行交换?Android这么优秀的系统不会让这种情况发生 的。解决这个问题主要靠ContentProvider。一个Content Provider类实现了一组标准的方法接口,从而能够让其他的应用保存或读取此Content Provider的各种数据类型。也就是说,一个程序可以通过实现一个Content Provider的抽象接口将自己的数据暴露出去。外界根本看不到,也不用看到这个应用暴露的数据在应用当中是如何存储的,或者是用数据库存储还是用文件 存储,还是通过网上获得,这些一切都不重要,重要的是外界可以通过这一套标准及统一的接口和程序里的数据打交道,可以读取程序的数据,也可以删除程序的数 据,当然,中间也会涉及一些权限的问题。
一个程序可以通过实现一个ContentProvider的抽象接口将自己的数据完全暴露出去,而且ContentProviders是以类似数据 库中表的方式将数据暴露,也就是说ContentProvider就像一个“数据库”。那么外界获取其提供的数据,也就应该与从数据库中获取数据的操作基 本一样,只不过是采用URI来表示外界需要访问的“数据库”。
Content Provider提供了一种多应用间数据共享的方式,比如:联系人信息可以被多个应用程序访问。
Content Provider是个实现了一组用于提供其他应用程序存取数据的标准方法的类。 应用程序可以在Content Provider中执行如下操作: 查询数据 修改数据 添加数据 删除数据
标准的Content Provider: Android提供了一些已经在系统中实现的标准Content Provider,比如联系人信息,图片库等等,你可以用这些Content Provider来访问设备上存储的联系人信息,图片等等。
来源: http://www.cnblogs.com/pxsbest/p/5068482.html
前面介绍的几种存储都是将数据存储在本地设备上,除此之外,还有一种存储(获取)数据的方式,通过网络来实现数据的存储和获取。
总结:
偏好设置简单
哪些跨进程:文件,网络,contentprovider
不错的网站
http://www.360doc.com/content/11/0930/19/6938655_152478139.shtml
问题:
如何将图片存入数据库中,并从数据库中取出图片
内连接:
指连接结果仅包含符合连接条件的行,参与连接的两个表都应该符合连接条件。
外连接:
连接结果不仅包含符合连接条件的行同时也包含自身不符合条件的行。包括左外连接、右外连接和全外连接。
左外连接:
左边表数据行全部保留,右边表保留符合连接条件的行
右外连接:
右边表数据行全部保留,左边表保留符合连接条件的行
全外连接:
左外连接 union 右外连接
- <span style="color:gray"><span style="color:#333333">
- </span></span>
- <span style="color:gray"><span style="color:#333333">
- </span></span>
<span style="color:gray"><span style="color:#000000"><span style="color:#333333">简单来讲,随便来个例子: A表 B表 id name id name 1 a 1 b 2 b 3 c 4 c </span><span style="color:#ff00ff"><strong>内连接就是左表和右表相同的数据:交集</strong></span> <span style="color:#333333">select * from A inner join B on A.id=B.id id name id name 1 a 1 b 外连接分为:左外连接、右外连接、全外连接 左外连接就是以左表为准,去匹配右表,左表有多少条数据,结果就是多少条数据 select * from A left join B on A.id=B.id id name id name 1 a 1 b 2 b null null 4 c null null 右外连接就是与左外连接反之,以右表为准,去匹配左表,右表有多少条数据,结果就是多少条数据 select * from A right join B on A.id=B.id id name id name 1 a 1 b null null 3 c 全外连接数据条数不一定,相当与是左外连接 和右外连接 的综合 select * from A full join B on A.id=B.id id name id name 1 a 1 b 2 b null null null null 3 c 4 c null null 希望你能明白!!!</span></span></span>
- <span style="color:gray"><span style="color:#000000">
- </span></span>
- <span style="color:gray"><span style="color:#000000"><span style="color:#333333"><img data-cke-saved-src="file:///C:/Users/asus/Documents/My Knowledge/temp/75b91be7-4917-4ce3-b34a-f1cc63940220/128/index_files/1aaebfd0-8ff3-4607-9731-e545e523d383.png" src="file:///C:/Users/asus/Documents/My Knowledge/temp/75b91be7-4917-4ce3-b34a-f1cc63940220/128/index_files/1aaebfd0-8ff3-4607-9731-e545e523d383.png" alt="" width="546" height="247" />
- </span></span></span>
好的网站:列子举例
http://blog.csdn.net/liuhe688/article/details/6715983
应用:
1.天气预报
2.车载记录仪
1.数据库基本法则:创建,打开和封装
在执行完上面的代码后,系统就会在/data/data/[PACKAGE_NAME]/databases目录下生成一个“test.db”的数据库文件,如图:
2.SQLiteOpenHelper也就是所谓的SQLiteDBhelper目的主要是更好的封装性(处理数据库)
上面就是SQLite的基本应用,但在实际开发中,为了能够更好的管理和维护数据库
我们会封装一个继承自SQLiteOpenHelper类的数据库操作类,然后以这个类为基础,再封装我们的业务逻辑方法。
Cursor结果集需要注意些什么:一个最需要注意的是,在我们的结果集中必须要包含一个“_id”的列,否则SimpleCursorAdapter就会翻脸不认人,为什么一定要这样呢?因为这源于SQLite的规范,主键以“_id”为标准。解决办法有三:第一,建表时根据规范去做;第二,查询时用别名,例如:SELECT id AS _id FROM person;第三,在CursorWrapper里做文章:
下面我们先来看一下DBHelper:用于;创建数据库和更新打开数据库
[java] view plaincopy
来源: <http://blog.csdn.net/liuhe688/article/details/6715983>
我们需要一个DBManager,来封装我们所有的业务方法(增删改查),代码如下:
数据的添加
2种方式:ContentValue和直接的sql语句!
1.使用insert方法
1 2 3 |
|
2.使用execSQL方式来实现
1 2 |
|
数据的删除
同样有2种方式可以实现
1 2 3 |
|
使用execSQL方式的实现
1 2 |
|
数据修改
同上,仍是2种方式
1 2 3 4 5 |
|
使用execSQL方式的实现
1 2 |
来源: <http://www.cnblogs.com/Excellent/archive/2011/11/19/2254888.html>
|
[java] view plaincopy实现代码用Cursor的moveToNext函数对查询到的结果集进行遍历。
查询的函数还有:
db.rawQuery(String sql, String[] selectionArgs);
db.query(String table, String[] columns, String selection,String[] selectionArgs, String groupBy, String having, String orderBy);
db.query(String table, String[] columns, String selection,String[] selectionArgs, String groupBy, String having, String orderBy, Stringlimit);
db.query(String distinct, String table, String[] columns, Stringselection, String[] selectionArgs, String groupBy, String having, StringorderBy, String
来源: <http://blog.csdn.net/nupt123456789/article/details/7891887>
1 2 3 4 5 6 7 8 |
|
通过rawQuery实现的带参数查询
1 2 3 4 |
|
bt中的查询
为了方便我们面向对象的使用数据,我们建一个Person类,对应person表中的字段,如下:
直接操作实体类
[java] view plaincopy
/
实验说明:
Android中使用SQLite数据库时,需要用adb来辅助调试,如果想在windows下的cmd命令行中使用adb,
必须先配置环境变量,我这里是配的用户环境变量path: C:\Program Files\android-sdk\platform-tools;
数据库sqilte调试工具
问题:
在cmd命令中查询数据库,给数据库建立表格,…………等等!
知识:
Cursor的方法
注意:Cursor中游标的下一个,当前个可能为空
为了达到录音的自动话
一录完就看是播放,录制显示时间10秒
不用每次都存放在SD卡中,可以存放临时的文件
每个程序存放位置都有,在和偏好设置一样的,在data分区里面
================================================
问题:
插入数据库和添加数据库有什么区别
音乐播发器中查询的方法!
好的网站:列子举例
http://blog.csdn.net/liuhe688/article/details/6715983
重复的数据:高级语句
http://www.dedecms.com/knowledge/data-base/sql-server/2012/0821/10732.html
http://www.360doc.com/content/12/0328/14/8354145_198587857.shtml
- <span style="color:gray"><span style="color:#333333">一:as可以作为别名的标志。
- sql:select name as username form tablename;
- 解释:上面语句的意思就是查询出tablename表中字段name的所有记录,并且给name别名为username。
- 二:as可以作为连接语句的操作符。
- sql:create table tablename as select * from tablename2;
- 解释:上面语句的意思就是先获取到tablename表中的所有记录,之后创建一张tablename表,结构和tablename2表相同,记录为后面语句的查询结果。</span></span>
来源: https://zhidao.baidu.com/question/243815061.html
IN 操作符允许我们在 WHERE 子句中规定多个值。
SELECT column_name(s)
FROM table_name
WHERE column_name IN (value1,value2,...)
Persons 表:
Id | LastName | FirstName | Address | City |
---|---|---|---|---|
1 | Adams | John | Oxford Street | London |
2 | Bush | George | Fifth Avenue | New York |
3 | Carter | Thomas | Changan Street | Beijing |
现在,我们希望从上表中选取姓氏为 Adams 和 Carter 的人:
我们可以使用下面的 SELECT 语句:
SELECT * FROM Persons
WHERE LastName IN ('Adams','Carter')
Id | LastName | FirstName | Address | City |
---|---|---|---|---|
1 | Adams | John | Oxford Street | London |
3 | Carter | Thomas | Changan Street | Beijing |
应用:
1.天气预报
2.车载记录仪
1.数据库基本法则:创建,打开和封装
在执行完上面的代码后,系统就会在/data/data/[PACKAGE_NAME]/databases目录下生成一个“test.db”的数据库文件,如图:
2.SQLiteOpenHelper也就是所谓的SQLiteDBhelper目的主要是更好的封装性(处理数据库)
上面就是SQLite的基本应用,但在实际开发中,为了能够更好的管理和维护数据库
我们会封装一个继承自SQLiteOpenHelper类的数据库操作类,然后以这个类为基础,再封装我们的业务逻辑方法。
Cursor结果集需要注意些什么:一个最需要注意的是,在我们的结果集中必须要包含一个“_id”的列,否则SimpleCursorAdapter就会翻脸不认人,为什么一定要这样呢?因为这源于SQLite的规范,主键以“_id”为标准。解决办法有三:第一,建表时根据规范去做;第二,查询时用别名,例如:SELECT id AS _id FROM person;第三,在CursorWrapper里做文章:
下面我们先来看一下DBHelper:用于;创建数据库和更新打开数据库
[java] view plaincopy
来源: <http://blog.csdn.net/liuhe688/article/details/6715983>
我们需要一个DBManager,来封装我们所有的业务方法(增删改查),代码如下:
数据的添加
2种方式:ContentValue和直接的sql语句!
1.使用insert方法
1 2 3 |
|
2.使用execSQL方式来实现
1 2 |
|
数据的删除
同样有2种方式可以实现
1 2 3 |
|
使用execSQL方式的实现
1 2 |
|
数据修改
同上,仍是2种方式
1 2 3 4 5 |
|
使用execSQL方式的实现
1 2 |
来源: <http://www.cnblogs.com/Excellent/archive/2011/11/19/2254888.html>
|
[java] view plaincopy实现代码用Cursor的moveToNext函数对查询到的结果集进行遍历。
查询的函数还有:
db.rawQuery(String sql, String[] selectionArgs);
db.query(String table, String[] columns, String selection,String[] selectionArgs, String groupBy, String having, String orderBy);
db.query(String table, String[] columns, String selection,String[] selectionArgs, String groupBy, String having, String orderBy, Stringlimit);
db.query(String distinct, String table, String[] columns, Stringselection, String[] selectionArgs, String groupBy, String having, StringorderBy, String
来源: <http://blog.csdn.net/nupt123456789/article/details/7891887>
1 2 3 4 5 6 7 8 |
|
通过rawQuery实现的带参数查询
1 2 3 4 |
|
bt中的查询
为了方便我们面向对象的使用数据,我们建一个Person类,对应person表中的字段,如下:
直接操作实体类
[java] view plaincopy
/
实验说明:
Android中使用SQLite数据库时,需要用adb来辅助调试,如果想在windows下的cmd命令行中使用adb,
必须先配置环境变量,我这里是配的用户环境变量path: C:\Program Files\android-sdk\platform-tools;
数据库sqilte调试工具
问题:
在cmd命令中查询数据库,给数据库建立表格,…………等等!
知识:
Cursor的方法
注意:Cursor中游标的下一个,当前个可能为空
为了达到录音的自动话
一录完就看是播放,录制显示时间10秒
不用每次都存放在SD卡中,可以存放临时的文件
每个程序存放位置都有,在和偏好设置一样的,在data分区里面
================================================
问题:
插入数据库和添加数据库有什么区别
音乐播发器中查询的方法!
1.在shell中找到路径
总的来说就是:
2.在run命令中用adb pull 表格,可以导出许多的表格
数据库就会导入在当前的路径中
============================================
sqlitespy==怎么用?
查询语句中记得:字符串
实际的表示:Tables
View是我们在操作中查询用到的表
右键,查看表的连接的状态!
作业:在工具中进程查询语句的练习
xml文件的备份和通话记录的备份
我们的数据库建了几张表
如果xml文件删除了的点,就会重写进行整理
一开始创建了3个目
在分析的时候先删除上一次清理的时候的,然后在生成contactinfo,保证是最新的
数据的备份:有sd卡是存放在SD卡里面 ,没有sd卡的话是存放在了data/data/目录下
一个是缓存,一个备份
从缓存目录拷贝一份到备份目录
缓存目录:huanji
获取备份数据目录 huanji/.backup/
缓存目录和一个备份目录
备份的流程
1.要删除的Id
2.通过id在系统数据库中出他们的所以状态和性质
3.通过ID删除系统数据库中的数据
4.把在2中查出的条目数据写到xml文件中
1).按时间查出文件,找出最新的一个
2).把内容写到xml中,其中创建了一个临时的目录
5.删除自己创建的临时数据
短信,联系人,通话记录在系统数据库中不同的地方
联系人(短信和通话记录是一样的,联系人不一样)
短信
通话记录
数据是怎么插入的
在分析的时候
自己建的表有4张,3张是电话本,还有一张是第三方电话的信息(表的建立也是有一个管理类)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。