目录

Android基础-数据库SQLite

Android基础-数据库SQLite

安卓中使用的数据库是:

SQLite(轻量级,嵌入式的数据库)

创建文件时:

	1.声明文件对象,文件是不会被创建出来的。
	File file = new File("文件名称");
	2.写文件(文件才会被创建出来)
	FileOutputStream fos = new FileOutputStream(file);
	fos.write("hdahfdsaklfh".getbytes());
数据库的创建流程:
    1.创建一个类,继承SQLiteOpenHelper,覆写父类的方法: 


public class MySQLLiteOpenHelper extends SQLiteOpenHelper {



public MySQLLiteOpenHelper(Context context ) {



//context 上下文



//name 数据库名字



//factory 游标工程



// version 数据库版本 (int 类型,从1开始)



super(context ,"person.db",null,1 );



}



//onCreate 方法在数据库第一次被创建时执行,当数据库创建完毕后,就不会再执行了



//该方法适合做数据库表结构的初始化操作



//db 代表当前数据库



public void onCreate(SQLiteDatabase db) {



System.out.println("--------数据库被创建了----------");



//执行sql语句



db.execSQL("creat table info (_id integer primary key autoincrement,name varchar(20),phone varchar(20) )");



}



//当数据库的版本号发生升级时调用



//数据库只能升级不能降级



//db 当前数据库,oldVersion 老版本号,newVersion 新版本号



public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {



System.out.println("-------数据库升级了--------");



db.execSQL("alter table info add money varchar(20)");



}



}
    2.创建MySQLLiteOpenHelper 对象,并执行getWritableDatabase/getReadableDatabase()方法,
只是创建对象,不会创建数据库,只有执行了getWritableDatabase/getReadableDatabase()方式时才会真正创建
可读、可写数据库返回的是同一个数据库的实例,区别就是:操作数据库的时候是否加锁。
注意细节:
1)sqlite数据库是一个嵌入式轻量级的数据库,内部不区分数据类型的,不对数据的长度校验。
2)onCreate 方法在数据库第一次被创建时执行,当数据库创建完毕后,就不会再执行了
3)数据库只能升级不能降级
4)数据库文件是在 /data/data/包名/databases/xxx.db
5)定义为INTEGER PRIMARY KEY的字段只能存储64位整数, 当向这种字段保存除整数以外的数据时,将会产生错误
利用sqlite3工具查看数据库的内容
> sqlite3 xxx.db

如果出现中文乱码 需要修改cmd的编码集:>chcp 6500165001 utf-8 ( 默认是gb2312 )



### 二、数据库的增删改查


#### 方法一:用Sql语句
复习sql语法:
查询语句:select * from 表名 where 条件子句 group by 分组字句 having ... order by 排序子句
如:select * from person
        select * from person order by id desc
        select name from person group by name having count(*)>1
分页SQL与mysql类似,下面SQL语句获取5条记录,跳过前面3条记录
select * from Account limit 5 offset 3 或者 select * from Account limit 3,5
插入语句:insert into 表名(字段列表) values(值列表)。如: insert into person(name, age) values(‘传智’,3)
更新语句:update 表名 set 字段名=值 where 条件子句。如:update person set name=‘传智‘ where id=10
删除语句:delete from 表名 where 条件子句。如:delete from person  where id=10
注意sql语句不能写错!
1)增、删、改使用的语句是:


```java


SQLiteDatabase db = hepler.getWritableDatabase();



db.execSQL("insert into info (name , phone) values (?,?)", new Object[]{ name,phone});



db.close();

其中:1、heler是自定义的

MySQLLiteOpenHelper 类的实例,用于获取数据库连接的。

2、

增、删、改使用的是:

execSQL ,其中:

new

 

Object

[]{

 name

,

phone

}是sql语句的参数

2)查询使用的是:



String phone = null;



SQLiteDatabase db = hepler.getWritableDatabase();



Cursor c= db.rawQuery("select phone from info where name =? ",new String[]{name});



if(c.moveToNext()){



phone = c.getString(0);



// phone = c.getString(c.getColumnIndex("phone"));



}



c.close();//注意释放游标资源



db.close();



return phone;

其中:1、使用的SQL语句是 rawQuery(和增删改不同),参数是new String[]{name} 注意这里是String类型的数组(和增删改不同)

2、查询有结果集,是cursor(游标),需要通过游标获取结果中的信息。

3、游标中是通过c.getString(列号)来获取每一行中具体信息的,如果不知道具体的列号,可以用c.getColumnIndex(“phone”)来获取

3、需要注意释放游标资源


```java


#### 方法二:用Google提供的api



1)增



long
    
     result = db.insert(table, nullColumnHack, values);

// 通过拼sql语句实现的



// table 表名



// nullColumnHack 设置没有传值的参数为空

// values 列名和值的map集合



// result 是插入信息的行号,如果没有成功,返回-1



```java


public
        
         
        
        boolean
        
         add
        
        (
        
        String
        
         name
        
        ,
        
         
        
        String
        
         phone
        
        )
        
         
        
        {



SQLiteDatabase db = helper.getWritableDatabase();



// ContentValues 是一个map,用来存放数据 其中:key 列名 values 值,相当于sql中的参数数组



ContentValues values = new ContentValues();



values.put("name", name);



values.put("phone", phone);



// 通过拼sql语句实现的



// table 表名



// nullColumnHack 设置没有传值的参数为空



// values 列名和值的map集合



long result = db.insert("info", null, values);



db.close();



// result 是插入信息的行号,如果没有成功,返回-1



if (result == -1) {



return false;



} else {



return true;



}

2)删

int result = db.delete(table, whereClause, whereArgs);

// table 表名

// whereClause 条件

// whereArgs 条件的值

// result 

成功删除的行数


public
        
         
        
        int
        
         deleteByName
        
        (
        
        String
        
         name
        
        )
        
         
        
        {



SQLiteDatabase db = helper.getWritableDatabase();



// table 表名



// whereClause 条件



// whereArgs 条件的值



int result = db.delete("info", "name = ?", new String[] { name });



db.close();



return result;



}

3)改

int result = db.update(table, values, whereClause, whereArgs);

// table 表名

// values 键值对

// whereClause 条件

// whereArgs 条件的值

//

result 更新了多少行


public
        
         
        
        int
        
         updata
        
        (
        
        String
        
         name
        
        ,
        
         
        
        String
        
         newphone
        
        )
        
         
        
        {



SQLiteDatabase db = helper.getWritableDatabase();



ContentValues values = new ContentValues();



values.put("phone", newphone);



// table 表名



// values 键值对



// whereClause 条件



// whereArgs 条件的值



int result = db.update("info", values, "name = ?",



new String[] { name });



db.close();



return result;



}

4)查

Cursor cursor = db.query(table, columns, selection, selectionArgs, groupBy, having, orderBy);

//table 表名

//columns 需要的查询结果

// selction 查询条件

// selectionArgs 查询条件参数

//groupBy 是否分组查询, having, orderBy 结果集排序方式//

查询有结果集,是cursor(游标),需要通过游标获取结果中的信息。


public String findPhone(String name) {



String phone = null;



SQLiteDatabase db = helper.getWritableDatabase();



//table 表名



//columns 需要的查询结果



// selction 查询条件



// selectionArgs 查询条件参数



//groupBy 是否分组查询, having, orderBy 结果集排序方式



Cursor cursor = db.query("info", new String[] { phone }, "name = ?",



new String[] { name }, null, null, null);



if (cursor.moveToNext()) {



phone = cursor.getString(0);



}



cursor.close();// 释放资源



db.close();



return name;



}


#### 两种数据库增删改查方式的优缺点
1. 直接利用sql语句增删改查
>优点:非常的灵活,多表查询,级联查询。
>缺点:代码容易出错,方法没有返回值。
2. 利用google包装的api 执行增删改查
>优点: 代码不容易出错,写起来简单,方法有返回值
>缺点: 不容易多表查询。复杂表的操作,视图都无法实现。



#### sqlite事务



sqlite 事务和jdbc中的事务是类似的几条操作语句的要么同时成功要么同时失败),在事务的写法上有些不同



SQLite事务的写法为:



db.beginTransaction();



try {



.....



// 事务的sql语句都执行成功了。 设置一个标记



db.setTransactionSuccessful();



} catch (Exception e) {



} finally {



db.endTransaction();



}



以银行转账为例



```java


/**



* 银行转账



*



* @param view



*/



public void click(View view) {



PersonDBOpenHelper helper = new PersonDBOpenHelper(this);



SQLiteDatabase db = helper.getWritableDatabase();



// 开启事务



db.beginTransaction();



try {



db.execSQL("update info set money= money -500 where name=?",



new String[] { "zhangsan" });



// s.equals("haha");



db.execSQL("update info set money= money +500 where name=?",



new String[] { "lisi" });



// 事务的sql语句都执行成功了。 设置一个标记



db.setTransactionSuccessful();



} catch (Exception e) {



Toast.makeText(this, "产生异常,事务回滚", 0).show();



} finally {



db.endTransaction();



}



}

注意:SQlite事务不用关闭数据库连接