Android 原生数据库 SQLite 应用
简介:SQLite 是一个开源的嵌入式关系数据库,它能够缩小用用程序的治理数据开销,SQLite 可移植性好,很容易应用,很少,高效而牢靠。
一:SQLiteOpenHelper 类(SQLite 数据库操作类)
作用:治理数据库(创立,减少,删,修,改)& 版本控制。
两个重要的办法
onCreate(SQLiteDatabase db) 创立数据库 创立数据库时主动调用
onUpgrade(SQLiteDatabase db, int oldVersion,int newVersion) 降级数据库
其余办法
1.getWritableDatabase() 创立或者关上能够读 / 写的数据库 返回 SQLiteDatabase 对象
2.getReadableDatabase() 创立或关上可读的数据库 返回 SQLiteDatabase 对象
3. 拿到返回 SQLiteDatabase 对象能够执行
1.execSQL(sql) 通过执行 sql 语句能够进行增删改操作,不能执行查问操作
2.query(),rawQuery()查询数据库
3.insert()插入数据
4.delete()删除数据
5.close()敞开所有关上的数据库对象
4. 对于“增、删、改(更新)”这类对表内容变换的操作,需先调用 getWritableDatabase()取得一个可写数据库对象,在执行的时候调用通用的 execSQL(String sql)或对应的操作 API 办法:insert()、delete()、update()
5. 对“查”,须要调用 getReadableDatabase()取得一个可读的数据库对象,而后应用 query()或 rawQuery()办法 查询数据库不能应用 execSQL 办法
public class DBHelper extends SQLiteOpenHelper {
private static final String DBname = "rocky.db";
private static final int DBversion = 3;
private static final String TAG = "DBHelper";
/* 参数阐明:* 第一参数:上下文
* 第二参数:数据库文件名称
* 第三参数:null 代表默认的游标工厂
* 第四参数:数据库的版本号(数据库版本号只增不减)*/
public DBHelper(Context context) {super(context, DBname, null, DBversion);
}
/*
* 数据库创立的调用,只有在 app 第一次装置时才会调用这个办法
* * 创立一个如果表不存在就创立它 UserInfo
* integer primary key autoincrement * varchar(20) 存储变长数据
* char(10) 存储定长数据
* text 存储可变长度的非 Unicode 数据 */
@Override
public void onCreate(SQLiteDatabase db) {db.execSQL("CREATE TABLE IF NOT EXISTS UserInfo(_id INTEGER PRIMARY KEY AUTOINCREMENT,name varchar(20),phone varchar(20))");
Log.d(TAG, "onCreate");
}
/*
* 数据库降级是调用
* 当初数据库版本是 3,oldVersion 是 2
* 减少了一个字段 category_id 类型 text */
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {Log.d(TAG, "onUpgrade"+"oldVersion"+oldVersion+"newVersion"+newVersion);
switch (oldVersion){
case 2:
db.execSQL("alter table UserInfo add category_id text");
break; }
}
}
二:创立数据拜访接口 Dao
1. 什么是 Dao
Dao(Data Access Object)是一个数据拜访接口,加载业务逻辑与数据资源两头。Dao 是把对数据库的操作全副封装在外面。Dao 把底层的数据拜访逻辑和高层的业务逻辑离开。
public class DemoDao {
private DBHelper helper;
public DemoDao(Context context) {helper = new DBHelper(context);
}
/*
* 增加一条记录
* name 联系人姓名
* phone 联系人电话
* return 返回是增加在数据库的行号 -1 代表失败 */
public long add(String name, String phone, String category_id) {// 获取操作数据库的实例,getWritableDatabase()磁盘满了,关上会报错,getReadableDatabase()磁盘满了,只会返回一个只读的数据库对象
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", name);
values.put("phone", phone);
values.put("category_id", category_id);
// 向表中插入一条数据
long rowid = db.insert("UserInfo", null, values);
// 开释数据库资源
db.close();
return rowid;
}
/*
* 依据姓名删除一条记录
* name 要删除的联系人姓名
* return 返回 0 代表没有删除任何记录,返回整形 int 代表删除了几条数据 */
public int delete(String name) {SQLiteDatabase db = helper.getWritableDatabase();
int rowcount = db.delete("UserInfo", "name=?", new String[]{name});
db.close();
return rowcount;
}
/*
* 批改联系人电话号码
* new 新的电话号码
* name 要批改的联系人姓名
* return 0 代表一行也没有更新胜利 >0 整数代表是更新了多少行记录 */
public int update(String newphone, String name) {SQLiteDatabase db = helper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("phone", newphone);
int rowcount = db.update("UserInfo", values, "name=?", new String[]{name});
db.close();
return rowcount;
}
/*
* 查问联系人的电话号码
* name 联系人
* return 电话号码 */
public String getPhoneNumber(String name) {
String phone = null;
SQLiteDatabase db = helper.getReadableDatabase();
//Cursor
Cursor cursor = db.query("UserInfo", new String[]{"phone"}, "name=?", new String[]{name}, null, null, null);
if (cursor.moveToNext()) {
// 如果光标能够挪动到下一位,代表就是查问到了数据
phone = cursor.getString(0);
}
cursor.close();
db.close();
return phone;
}
/*
* * 获取所有的数据 */
public String getAll(){
String allTable ="";
SQLiteDatabase db=helper.getReadableDatabase();
Cursor cursor=db.rawQuery("select name from sqlite_master where type='table'order by name",null);
while (cursor.moveToNext()){
// 遍历出表名
String name=cursor.getString(0);
allTable+=name+".......";
}
return allTable;
}
}
三:应用 SQLiteOpenHelper 在 Application 创立的时候创立,也能够在应用具体应用时候去创立
public class App extends Application {
@Override
public void onCreate() {super.onCreate();
initSqlite();}
private void initSqlite() {DBHelper dbHelper=new DBHelper(this);
}
}
四:Activity 的 view 点击应用执行具体相干操作
public class NineActivity extends AppCompatActivity {
private DemoDao demoDao;
private EditText mEtName;
private EditText mEtPhone;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nine);
mEtName=findViewById(R.id.mEtName);
mEtPhone=findViewById(R.id.mEtPhone);
demoDao=new DemoDao(this);
}
public void add(View view){String name=mEtName.getText().toString();
String phone=mEtPhone.getText().toString();
String category_id="dddd";
long add=demoDao.add(name,phone,category_id);
if (add!=-1){Toast.makeText(this,"增加胜利"+add,Toast.LENGTH_LONG).show();}
}
public void delete(View view){String name = mEtName.getText().toString();
int delete = demoDao.delete(name);
if (delete != 0){Toast.makeText(this, "删除胜利" + delete, Toast.LENGTH_LONG).show();}
}
public void update(View view){String name=mEtName.getText().toString();
String phone=mEtPhone.getText().toString();
// 依据 phone 更新 name
int update=demoDao.update(phone,name);
if (update!=0){Toast.makeText(this,"更新胜利"+update,Toast.LENGTH_LONG).show();}
}
public void query(View view){
/*
* 依据姓名查问手机号 */
String name=mEtName.getText().toString();
String phoneNumber=demoDao.getPhoneNumber(name);
if (!TextUtils.isEmpty(phoneNumber)){Toast.makeText(this,"查问胜利"+phoneNumber,Toast.LENGTH_LONG).show();}
// 查问所有表名
/* String all=demoDao.getAll();
if (!TextUtils.isEmpty(all)){Toast.makeText(this,"查问胜利 ---"+all,Toast.LENGTH_LONG).show();}*/
}
}
五:针对 SQLite 查问语句相干参数
Cursor cursor = db.query("UserInfo", new String[]{"phone"}, "name=?", new String[]{name}, null, null, null);
query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit)办法各参数的含意:
1.table:表名。相当于 select 语句 from 关键字前面的局部。如果是多表联结查问,能够用逗号将两个表名离开。
2.columns:要查问进去的列名 。相当于 select 语句 select 关键字前面的局部。
3.selection:查问条件子句, 相当于 select 语句 where 关键字前面的局部,在条件子句容许应用占位符“?”
4.selectionArgs:对应于 selection 语句中占位符的值,值在数组中的地位与占位符在语句中的地位必须统一,否则就会有异样。
5.groupBy:相当于 select 语句 group by 关键字前面的局部
6.having:相当于 select 语句 having 关键字前面的局部
7.orderBy:相当于 select 语句 order by 关键字前面的局部,如:personid desc, age asc;
8.limit:指定偏移量和获取的记录数,相当于 select 语句 limit 关键字前面的局部。
六:留神:
phone = cursor.getString(cursor.getColumnIndex(“Phone”));// 列明是 phone,故起因是 getColumnIndex 辨别大小写
Caused by: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.