一、创建数据库
安卓中使用的数据库是:
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.db5)定义为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 personselect * from person order by id descselect 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)增、删、改使用的语句是: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、需要注意释放游标资源
方法二:用Google提供的api
1)增long result = db.insert(table, nullColumnHack, values);// 通过拼sql语句实现的// table 表名// nullColumnHack 设置没有传值的参数为空// values 列名和值的map集合// result 是插入信息的行号,如果没有成功,返回-1public 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();
}
以银行转账为例:/**
* 银行转账
*
* @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事务不用关闭数据库连接