参考链接
http://blog.csdn.net/liuhe688/article/details/6715983
学习SQLite数据库之前,先去学习数据库中的增删改查语句,以前用工具创建表,表字段,那么请重新学习SQLite,它是和数据库操作差不多,不过它轻量级的,很多事情是做不了的。下面事几个简单的语句:
create table user(id INTEGER primary key autoincrement,username char(20),userpwd char(20));
select * from user where id = 2;
update user set username = 'ice' where id = 2;
insert into(username,userpwd) values('li','123456');
delete from user where id = 2;
上面事一些基本的语句,需要详细了解的,可以去网络上查找相关知识。
接下来介绍一些如何操作数据库呢?
第一点,SQLite嵌入式的,轻量级的数据库,它已经放在了android手机上,并不是像后台需要去链接数据库。SQLite将存储的信息放入到指定的路径下data/<项目文件夹>/databases/。
像要使用SQLite,那么就需要去继承SQLiteOpenHelper,它来执行创建,增删改查相关的操作。继承SQLiteOpenHelper后,必须要实现两个方法,和实现一个构造函数。两个方法分别事onCreate(SQLiteDatabase db) 和 onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 。一个事创建表,一个是用来升级数据库的。
构造函数中,需要去些指出数据库名和数据库版本。
public class DBOpenHelper extends SQLiteOpenHelper{
private static final String DATABASENAME = "test.db"; //数据库名称
private static final int DATABASEVERSION = 2;//数据库版本,大于0
//数据库的创建
public DBOpenHelper(Context context) {
super(context, DATABASENAME, null, DATABASEVERSION);
}
//创建表
@Override
public void onCreate(SQLiteDatabase db) {
String sql = "create table user(id INTEGER primary key autoincrement,username char(20),userpwd char(20))";
db.execSQL(sql);
}
//数据库的升级
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
String sql = "DROP TABLE IF EXISTS user";
db.execSQL(sql);
onCreate(db);
}
}
OnCreate()方法只调用一次,onUpgrade(),当数据库版本改变的时候,就会调用。我在代码中在调用时,重新去删除到表后重新执行onCreate(db)。可以像到,为了获取db(db是用来操作数据库的),需要去创建一次,这样就不用每次创建的时候都去调用构造函数。下面事会实现的。
接下来就是如何操作数据库,操作数据库有两种方式,一种是执行sql语句,还有一个事db来执行,只需要去调用对象的方法,并将参数传过去。
这里将一个类建立起来,并获取到DBOpenHelper。
public class DataHelper {
private DBOpenHelper mDBOpenHelper;
private DataHelper(Context context){
if (mDBOpenHelper == null){
mDBOpenHelper = new DBOpenHelper(context);
}
}
private static DataHelper mDataHelper;
public static DataHelper getDataHelper(Context context){
if (mDataHelper == null){
mDataHelper = new DataHelper(context);
}
return mDataHelper;
}
}
1.插入
首先事插入。表创建了,如何去创建数据。
execSQL(str);
insert(table,null,values);
第一个是执行sql语句,例如:insert into user(username,userpwd) values(' + "ice“+"','" + "123456"+"')";放入到execSQL参数中。可以执行在函数中些上要执行的语句,其中ice和12345用形参来代替,如insert into user(username,userpwd) values(' + username+"','" + password+"')"来代替。
insert()方法中第一个参数事表名,第二个参数一般设置为null,第三个参数事要插入的值,这个值事ContentValues。
下面来看代码,放入在DataHelper中的代码:
/**
* 执行sql语句
* @param sql
*/
public void insert(String sql){
bdOpenHelper.getWritableDatabase().execSQL(sql);
}
/**
* 插入数据
* @param username 插入的用户名
* @param password 插入的密码
*/
public void insert1(String username,String password){
String str = "insert into user(username,userpwd) values('" + username + "','" + password + "')";
bdOpenHelper.getWritableDatabase().execSQL(str);
}
/**
* 插入数据
* @param values
*/
public void insert2(ContentValues values){
bdOpenHelper.getWritableDatabase().insert("user",null,values);
}
接下来看它的实现
private DataHelper dataHelper;
dataHelper = DataHelper.getDataHelper(SQLTestActivity.this);
/**
* 保存数据
*/
public void save(){
String sql = "insert into user(username,userpwd) values('ice','123456')";
try {
dataHelper.insert(sql);
} catch (Exception e) {
e.printStackTrace();
}
}
public void save1(){
try {
dataHelper.insert1("ice","123456");
} catch (Exception e) {
e.printStackTrace();
}
}
public void save2(){
ContentValues values = new ContentValues();
values.put("username","ice"); //key值需要和创建表的字段名是一样的
values.put("userpwd","123456");
dataHelper.insert2(values);
}
2.查询
查询相对与其它会复杂一些,先来介绍有哪几种方法
1 db.rawQuery(Stringsql, String[] selectionArgs);
2 db.query(Stringtable, String[] columns, String selection, String[] selectionArgs, StringgroupBy, String having, String orderBy);
3 db.query(Stringtable, String[] columns, String selection, String[] selectionArgs, StringgroupBy, String having, String orderBy, String limit);
4 db.query(Stringdistinct, String table, String[] columns, String selection, String[] selectionArgs,String groupBy, String having, String orderBy, String limit);
还是有两种方式,一个rawQuery(),两个参数分别事sql语句,和查询的条件。
query()查询,传入的参数表明,获取的字段,查询的条件,查询条件的值。后面的参数用于分组,排序,分页(这里暂不考虑)。
/**
* 查询
* @param sql
*/
public Cursor query(String sql,String[] selectionArgs){
return bdOpenHelper.getWritableDatabase().rawQuery(sql, selectionArgs);
}
public Cursor query1(String table, String[] columns,String selection,String[] selectionArgs){
return bdOpenHelper.getWritableDatabase().query(table,columns,selection,selectionArgs,null,null,null);
}
实现:
public void query(){
String sql = "select * from user where id = ?"; //?是占位符
Cursor cursor = dataHelper.query(sql, new String[]{"1"});
if (cursor.moveToFirst()){ //判断是光标移动到第一个位置时是否有值
String username = cursor.getString(1);
String password = cursor.getString(2); //这里没有从0开始,因为0是id的值
}
cursor.close(); //使用完后需要关闭
}
public void query1(){
Cursor cursor = dataHelper.query1("user", new String[]{"username", "userpwd"}, "id = ?", new String[]{"1"});
while (cursor.moveToNext()){ //判断是光标移动到第一个位置时是否有值
String username = cursor.getString(cursor.getColumnIndex("username"));
String password = cursor.getString(cursor.getColumnIndex("userpwd")); //这里没有从0开始,因为0是id的值
}
cursor.close();
}
下面事Cursor的一些函数操作,有解释就不多说了。
1.c.move(int offset); //以当前位置为参考,移动到指定行
2 c.moveToFirst(); //移动到第一行
3 c.moveToLast(); //移动到最后一行
4 c.moveToPosition(int position); //移动到指定行
5 c.moveToPrevious(); //移动到前一行
6 c.moveToNext(); //移动到下一行
7 c.isFirst(); //是否指向第一条
8 c.isLast(); //是否指向最后一条
9 c.isBeforeFirst(); //是否指向第一条之前
10c.isAfterLast(); //是否指向最后一条之后
11 c.isNull(int columnIndex); //指定列是否为空(列基数为0)
12 c.isClosed(); //游标是否已关闭
13 c.getCount(); //总数据项数
14c.getPosition(); //返回当前游标所指向的行数
15c.getColumnIndex(String columnName);//返回某列名对应的列索引值
16 c.getString(int columnIndex); //返回当前行指定列的值
3.修改
/**
* 修改
* @param sql
*/
public void update(String sql){
try {
bdOpenHelper.getWritableDatabase().execSQL(sql);
} catch (SQLException e) {
e.printStackTrace();
}
}
public void update1(ContentValues values,String where,String[] whereArgs){
try {
bdOpenHelper.getWritableDatabase().update("user",values,where,whereArgs);
} catch (Exception e) {
e.printStackTrace();
}
}
实现:
public void update(){
String sql = "update user set username = '" + "li" + "' where id = '" + "1" + "'";
dataHelper.update(sql);
}
public void update1(){
ContentValues values = new ContentValues();
values.put("username","li");
String where = "id = ?";
String[] whereArgs = new String[]{"1"};
dataHelper.update1(values,where,whereArgs);
}
4.删除
因为和上面很相似,这里就直接给出代码/**
* 删除数据
* @param sql
*/
public void delete(String sql){
try {
bdOpenHelper.getWritableDatabase().execSQL(sql);
} catch (SQLException e) {
e.printStackTrace();
}
}
public void delete(String where,String[] whereArgs){
try {
bdOpenHelper.getWritableDatabase().delete("user",where,whereArgs);
} catch (Exception e) {
e.printStackTrace();
}
}
实现
/** * 删除数据 */ public void delete(){ String sql = "delete from user where id = '" + "1" + "'"; dataHelper.delete(sql); } public void delete1(){ dataHelper.delete1("id = ?",new String[]{"1"}); }
上面是介绍原生的SQLite数据查询,如果对数据操作不是很大的话,原生的语句就可以了,但有时候需要一些框架来辅助自己完成。下面介绍一个框架。要说一点的是,采用框架,就会增大apk的体积,如果对数据操作不多,建议不要使用。
框架名字GreenDAO
GreenDAO
参考链接:

sourceSets {
main {
java.srcDirs = ['src/main/java', 'src/main/java-gen']
}
}
compile 'org.greenrobot:greendao:2.2.1'
compile 'org.greenrobot:greendao-generator:2.2.0'
上面两个compile都放在dependecies中。
然后在java res同文件中中创建java-gen文件夹,用于放生成的文件。
public class Test {
private static Schema schema;
// public static void main(String args[]) throws Exception{
// schema = new Schema(1,"com.ice.bean");
// schema.setDefaultJavaPackageDao("com.ice.dao");
// addAircle();
// new DaoGenerator().generateAll(schema,"../ProjectDemo/app/src/main/java-gen");
// }
private static void addAircle(){
Entity aircle = schema.addEntity("Aircle");
aircle.addIdProperty(); //主键
aircle.addStringProperty("title").notNull();//其他属性,非空
}
}
注释掉的部分是用来生成一些文件,这些文件被放在java-gen中
new DaoGenerator().generateAll(schema,"../ProjectDemo/app/src/main/java-gen");这句代码就是告诉GreenDAO,我的java-gen的位置在哪里,ProjectDemo就是项目名。
运行起来就能够在java-gen看到com.ice.bean和com.ice.dao文件夹该文件夹下放了GreenDAO自动配置的文件。
具体操作
在继承了Application的类中的onCreate()方法中添上
<pre name="code" class="html">// 通过 DaoMaster 的内部类 DevOpenHelper,你可以得到一个便利的 SQLiteOpenHelper 对象。
// 可能你已经注意到了,你并不需要去编写「CREATE TABLE」这样的 SQL 语句,因为 greenDAO 已经帮你做了。
// 注意:默认的 DaoMaster.DevOpenHelper 会在数据库升级时,删除所有的表,意味着这将导致数据的丢失。
// 所以,在正式的项目中,你还应该做一层封装,来实现数据库的安全升级。
private void setupDatabase(){
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "notes-db", null);
db = helper.getWritableDatabase();
// 注意:该数据库连接属于 DaoMaster,所以多个 Session 指的是相同的数据库连接。
daoMaster = new DaoMaster(db);
daoSession = daoMaster.newSession();
}
private static DaoSession daoSession;
public static DaoSession getDaoSession() {
return daoSession;
}
public static void setDaoSession(DaoSession daoSession) {
App.daoSession = daoSession;
}
private void initData(){
Aircle aircle = new Aircle();
aircle.setTitle("ice");
getAircleDao().insert(aircle); //插入数据
List<Aircle> ice = getAircleDao().queryBuilder().where(AircleDao.Properties.Title.eq("ice"))
// .orderAsc(AircleDao.Properties.Id) //进行排序
.list();
for (int i = 0; i < ice.size();i++){
System.out.println(ice.get(i).getTitle());
}
}
private AircleDao getAircleDao(){
return App.getDaoSession().getAircleDao();
}
获取到到DAOsession,通过session,连接数据库,并对其操作。