1 package com.itheima.sqlite.dao; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import android.content.Context; 7 import android.database.Cursor; 8 import android.database.sqlite.SQLiteDatabase; 9 10 import com.itheima.sqlite.bean.Account; 11 12 public class AccountDao { 13 private MyHelper helper; 14 15 public AccountDao(Context context) { 16 helper = new MyHelper(context); 17 } 18 19 public void insert(Account a) { 20 SQLiteDatabase db = helper.getWritableDatabase(); // 获取SQLiteDatabase对象 21 db.execSQL("INSERT INTO account(name, balance) VALUES(?, ?)", new Object[] { a.getName(), a.getBalance() }); // 执行一条SQL语句 22 db.close(); // 关闭 23 } 24 25 public void delete(int id) { 26 SQLiteDatabase db = helper.getWritableDatabase(); // 获取SQLiteDatabase对象 27 db.execSQL("DELETE FROM account WHERE _id=?", new Object[] { id }); // 执行 28 db.close(); // 关闭 29 } 30 31 public void update(Account a) { 32 SQLiteDatabase db = helper.getWritableDatabase(); // 获取 33 db.execSQL("UPDATE account SET name=?, balance=? WHERE _id=?", new Object[] { a.getName(), a.getBalance(), a.getId() }); // 执行 34 db.close(); // 关闭 35 } 36 37 public Account query(int id) { 38 SQLiteDatabase db = helper.getReadableDatabase(); // 先调用getWriteableDatabse(), 如果出了异常, 就开一个只读的 39 Cursor c = db.rawQuery("SELECT name, balance FROM account WHERE _id=?", new String[] { id + "" }); // 执行查询语句, 得到结果集 40 Account a = null; 41 if (c.moveToNext()) { // 判断结果集是否包含下一条数据, 如果包含, 指针自动向后移动 42 String name = c.getString(0); // 从结果集中获取数据(根据列的索引获取) 43 int balance = c.getInt(c.getColumnIndex("balance")); // 从结果集中获取数据(先根据列名获取索引, 再根据索引获取数据) 44 a = new Account(id, name, balance); // 创建对象, 把数据设置到对象中 45 } 46 c.close(); 47 db.close(); 48 return a; // 返回对象 49 } 50 51 public List<Account> queryAll() { 52 SQLiteDatabase db = helper.getReadableDatabase(); 53 Cursor c = db.rawQuery("SELECT * FROM account", null); // 查询表中所有数据 54 List<Account> list = new ArrayList<Account>(); 55 while (c.moveToNext()) { 56 int id = c.getInt(0); // 获取表中的第一列(索引从0开始) 57 String name = c.getString(1); 58 int balance = c.getInt(2); 59 list.add(new Account(id, name, balance)); // 把表中的数据封装成对象 60 } 61 c.close(); 62 db.close(); 63 return list; 64 } 65 66 public Cursor queryCursor() { 67 SQLiteDatabase db = helper.getReadableDatabase(); 68 return db.rawQuery("SELECT * FROM account ORDER BY balance DESC", null); 69 } 70 71 public List<Account> queryPage(int pageSize, int pageNum) { 72 String index = (pageNum - 1) * pageSize + ""; // 翻页时的起始索引 73 String count = pageSize + ""; // 查询多少条数据 74 List<Account> list = new ArrayList<Account>(); 75 SQLiteDatabase db = helper.getReadableDatabase(); 76 Cursor c = db.rawQuery("SELECT * FROM account LIMIT ?,?", new String[] { index, count }); 77 while (c.moveToNext()) { 78 int id = c.getInt(0); 79 String name = c.getString(1); 80 int balance = c.getInt(2); 81 list.add(new Account(id, name, balance)); 82 } 83 c.close(); 84 db.close(); 85 return list; 86 } 87 88 public int queryCount() { 89 SQLiteDatabase db = helper.getReadableDatabase(); 90 Cursor c = db.rawQuery("SELECT COUNT(*) FROM account", null); 91 c.moveToNext(); 92 int count = c.getInt(0); 93 c.close(); 94 db.close(); 95 return count; 96 } 97 98 public void remit(int fromId, int toId, int amount) { 99 SQLiteDatabase db = helper.getWritableDatabase(); 100 try { 101 db.beginTransaction(); // 开启事务 102 db.execSQL("UPDATE account SET balance=balance-? WHERE _id=?", new Object[] { amount, fromId }); 103 db.execSQL("UPDATE account SET balance=balance+? WHERE _id=?", new Object[] { amount, toId }); 104 db.setTransactionSuccessful(); // 设置事务成功标记 105 } finally { 106 db.endTransaction(); // 结束事务 107 db.close(); 108 } 109 } 110 111 }
Myhelper.java
1 package com.itheima.sqlite.dao; 2 3 import android.content.Context; 4 import android.database.sqlite.SQLiteDatabase; 5 import android.database.sqlite.SQLiteOpenHelper; 6 7 public class MyHelper extends SQLiteOpenHelper { // 自定义类继承SQLiteOpenHelper 8 9 public MyHelper(Context context) { // 由于父类没有无参构造函数, 定义一个构造函数调用父类有参的构造函数 10 /* 11 * 参数1: Context代表应用程序的环境, 用来确定数据库文件的位置 12 * 参数2: 数据文件的名字 13 * 参数3: 用来创建Cursor(结果集)的工厂, 默认传null就可以 14 * 参数4: 数据库的版本, 后期用来更新数据库, 从1开始 15 */ 16 super(context, "itheima.db", null, 2); 17 } 18 19 @Override 20 public void onCreate(SQLiteDatabase db) { // 在数据库文件创建之后执行 21 System.out.println("onCreate"); 22 db.execSQL("CREATE TABLE account(_id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(20))"); // 执行SQL语句, 创建表 23 } 24 25 @Override 26 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 在数据库版本提升之后执行 27 System.out.println("onUpgrade"); 28 db.execSQL("ALTER TABLE account ADD balance INTEGER"); 29 } 30 31 }
一.SQLite数据库
1.SQLite数据库的特点
安卓手机自带, 小巧, 适合在手机中使用
不区分数据类型(主键除外)
SQL语句和MySQL几乎相同
SQLite不使用JDBC连接, 使用的是Android自有的API
每个数据库对应一个文件
* 2.创建数据库
定义类继承SQLiteOpenHelper, 实现onCreate(), onUpgrade()
创建该类对象, 调用getWritableDatabse()或者getReadableDatabse()
情况1: 数据库文件不存在, 创建文件, 打开数据库连接(得到SQLiteDatabase对象), 执行onCreate()方法
情况2: 数据库文件存在, 版本号没变, 打开数据库连接
情况3: 数据库文件存在, 版本号提升, 升级数据库, 打开数据库连接,执行onUpgrade()方法
情况4: 数据库文件存在, 版本号降低, 执行onDowngrade()方法, 方法中默认会抛出一个异常
* 3.创建表或修改表
SQLiteDatabase类的execSQL()方法可以执行一条SQL语句
如果希望创建数据库的时候就创建一些表, 那么这个操作就可以在onCreate()方法中执行
如果希望在数据库升级的时候做类似修改表添加表的操作, 可以在onUpgrade()方法中执行
*** 4.增删改查
execSQL()方法可以进行增删改操作
rawQuery()执行查询操作, 得到Cursor, 调用moveToNext()判断是否包含数据, 调用getString(), getInt()等方法获取数据
insert(), delete(), update(), query() 四个方法内部也是调用execSQL()和rawQuery()的, 它们在ContentProvider中使用更方便(明天讲)
* 5.事务管理
beginTransaction() 开启事务
setTransactionSuccessful() 设置事务成功标记
endTransaction() 结束事务.
事务结束的时候, 会把最后一个成功标记之前的操作提交, 成功标记之后的操作回滚