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事务不用关闭数据库连接