(1)了解SQLite数据库的基本作用;
(2)掌握数据库操作辅助类:SQLiteDatabase的使用;
(3)可以使用命令操作SQLite数据库;
(4)可以完成数据库的CRUD操作;
(5)掌握数据库查询及Cursor接口的使用。

在Android当中,本身提供了一种微型的嵌入式数据库叫做SQLite,同样可以执行SQL语句,对于不熟悉sql和jdbc的小伙伴,还是需要去自学一下。




下面我们首先使用一段代码演示如何取得数据库表操作。
- package com.example.sqliteopenhelper;
-
- import android.content.Context;
- import android.database.sqlite.SQLiteDatabase;
- import android.database.sqlite.SQLiteDatabase.CursorFactory;
- import android.database.sqlite.SQLiteOpenHelper;
-
- public class MySQLiteOpenHelper extends SQLiteOpenHelper {
- public static final String DATABASENAME="wancy";//数据库名称
- public static final int DATABASEVERSION=1;//版本号
- public static final String TABLENAME = "DH10";//数据库表名
-
- public MySQLiteOpenHelper(Context context) {
- super(context, DATABASENAME, null, DATABASEVERSION);
- // TODO Auto-generated constructor stub
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- String sql = "create table "+TABLENAME+" (id INTEGER PRIMARY KEY,"+
- "name VARCHAR(50) NOT NULL,"+"birthday DATE NOT NULL)";
- db.execSQL(sql);
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- String sql = "drop table if exists "+TABLENAME;//当退出的时候删除表
- db.execSQL(sql);
- this.onCreate(db);
- }
-
- }
以上要注意一点,在SQLite当中如果想要让某个字段自动增长,那么在创建表的时候使用“INTEGER PRIMARY KEY”声明即可。
那么这样的话一个数据库辅助类已经定义好了,那么我们下面在Activity当中去调用此类的方法。
- package com.example.sqliteproject;
-
- import com.example.sqliteopenhelper.MySQLiteOpenHelper;
-
- import android.os.Bundle;
- import android.app.Activity;
- import android.view.Menu;
-
- public class SQLiteActivity extends Activity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_sqlite);
-
- MySQLiteOpenHelper helper = new MySQLiteOpenHelper(this);
- helper.getWritableDatabase();//表示以读写的形式打开数据库
-
- }
-
-
- }
现在已经取得了数据库的连接了,如果以上代码没有错误,运行之后就可以在文件列表当中找到数据表.FileExplorer/data/data/数据库辅助类所在的包/database。根据代码,可以发现,如果数据库不存在,那么会自动调用onCreate方法去创建表,如果数据库已经存在了,但是版本号发生了改变,将会调用onUpgrade方法,现将原来的表删除之后,在去创建新的表。
·使用SQLite数据库并完成数据库的更新操作。
- public void insert(String name,String birthday){
- SQLiteDatabase db = super.getWritableDatabase();//取得数据库操作对象
- String sql = "insert into "+TABLENAME+" (name,birthday) values ('"+name+"',"+birthday+")";
- db.execSQL(sql);
- db.close();
- }
- public void update(int id,String name,String birthday){
- SQLiteDatabase db = super.getWritableDatabase();//取得数据库操作对象
- String sql = "update "+TABLENAME+" set name='"+name+"',birthday="+birthday+" where id="+id;
- db.execSQL(sql);
- db.close();
- }
- public void delete(int id){
- SQLiteDatabase db = super.getWritableDatabase();//取得数据库操作对象
- String sql = "delete from "+TABLENAME+" where id="+id;
- db.execSQL(sql);
- db.close();
- }
以上增删改三个方法写完之后,就可以在Activity当中去进行调用。
- package com.example.sqliteproject;
-
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.Toast;
-
- import com.example.sqliteopenhelper.MySQLiteOpenHelper;
-
- public class SQLiteActivity extends Activity {
- MySQLiteOpenHelper helper=null;
- Button insert,update,del = null;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_sqlite);
-
- insert=(Button) super.findViewById(R.id.insert);
- update = (Button) super.findViewById(R.id.update);
- del = (Button) super.findViewById(R.id.del);
- helper = new MySQLiteOpenHelper(this);
- helper.getWritableDatabase();//表示以读写的形式打开数据库
- insert.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- helper.insert("毛栗子", "1995-01-05");
- Toast.makeText(SQLiteActivity.this, "新增成功", 0).show();
- }
- });
- update.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- helper.update(1, "大白兔", "1995-01-05");
- Toast.makeText(SQLiteActivity.this, "修改成功", 0).show();
- }
- });
- del.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- helper.delete(1);
- Toast.makeText(SQLiteActivity.this, "删除成功", 0).show();
- }
- });
- }
-
-
- }
-
以上的程序,所有数据都是固定的,这在实际开发当中显然是不科学的,因为我们至少也要使用编辑框进行数据的编辑才是符合实际,而且使用字符串拼凑sql这种形式也是存在问题的,那么我们可以使用占位符的形式来处理这种问题。
- public void insert(String name,String birthday){
- SQLiteDatabase db = super.getWritableDatabase();//取得数据库操作对象
- java.sql.Date date = null;
- try {
- date = new java.sql.Date(new SimpleDateFormat("yyyy-MM-dd").parse(birthday).getTime());
- } catch (ParseException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- String sql = "insert into "+TABLENAME+" (name,birthday) values (?,?)";//使用占位符
- Object args[] = new Object[]{name,birthday};
- db.execSQL(sql,args);
- db.close();
- }
对于以上程序,只是换了另一种操作方法来解决拼凑的问题,功能上没有变化。
对于拼凑sql和使用占位符,可以形成一个共识:
肯定是使用占位符更好一些。
在android当中,还对数据的封装提供了一个ContentValues类。 可以理解为一个Map集合,有key和value,唯一不同的是ContentValues中的key必须是字符串。以后的操作就可以直接通过key取得value。并将value设置到sql语句当中。
- public void insert(String name,String birthday){
- SQLiteDatabase db = super.getWritableDatabase();//取得数据库操作对象
- ContentValues cv = new ContentValues();
- cv.put("name", name);
- cv.put("birthday", birthday);
- db.insert(TABLENAME, null, cv);//进行新增操作
- db.close();
- }
- public void update(int id,String name,String birthday){
- SQLiteDatabase db = super.getWritableDatabase();//取得数据库操作对象
- ContentValues cv = new ContentValues();
- cv.put("name", name);
- cv.put("birthday", birthday);
- String whereClause = " id=?";
- String whereArgs[]= new String[]{String.valueOf(id)};
- db.update(TABLENAME, cv, whereClause, whereArgs);//更新操作
- db.close();
- }
- public void delete(int id){
- SQLiteDatabase db = super.getWritableDatabase();//取得数据库操作对象
- String whereClause = " id=?";
- String whereArgs[]= new String[]{String.valueOf(id)};
- db.delete(TABLENAME, whereClause, whereArgs);//删除操作
- db.close();
- }
那么对于使用占位符和ContentValues进行数据库更新操作,两种方式并没有严格的优劣之分,但是对于不会sql的开发人员来说,使用ContentValues更好的。
·数据库查询机Cursor接口



在JDBC中ResultSet接口不呢是的功能就是依靠一个next()方法一动指针向下取数据,是到了JDBC2.0之后才能够向上取数据,但是我们一般也不去用这种向上取的形式。
Cursor接口,出现的比ResultSet晚,所有操作机制有些不同。
- package com.example.sqliteproject;
-
- import java.util.ArrayList;
- import java.util.List;
-
- import android.database.Cursor;
- import android.database.sqlite.SQLiteDatabase;
-
- public class DH10Cursor {
- private static final String TABLENAME="PR10";
- private SQLiteDatabase db =null;
- public DH10Cursor(SQLiteDatabase db) {
- super();
- this.db = db;
- }
-
- public List
find(){ - List
all = new ArrayList(); - String sql = "select id,name,birthday from "+TABLENAME;
- Cursor result = this.db.rawQuery(sql, null);//执行查询语句
- //采用循环的形式去结果集中的数据
- for(result.moveToFirst();!result.isAfterLast();result.moveToNext()){
- all.add(result.getInt(0)+"====="+result.getString(1)+"====="+result.getString(2));
- }
- result.close();
- db.close();
- return all;
- }
- }
-
"http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:id="@+id/mylayout"
- tools:context=".SQLiteActivity" >
-
-
- android:id="@+id/insert"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="新增"
- />
-
- android:id="@+id/update"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="修改"
- />
-
- android:id="@+id/del"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="删除"
- />
-
- android:id="@+id/query"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="查询"
- />
-
-
- package com.example.sqliteproject;
-
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.ArrayAdapter;
- import android.widget.Button;
- import android.widget.LinearLayout;
- import android.widget.ListView;
- import android.widget.Toast;
-
- import com.example.sqliteopenhelper.MySQLiteOpenHelper;
-
- public class SQLiteActivity extends Activity {
- MySQLiteOpenHelper helper=null;
- Button insert,update,del,query = null;
- ListView listView = null;
- LinearLayout myLayout = null;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_sqlite);
- helper = new MySQLiteOpenHelper(this);
- insert=(Button) super.findViewById(R.id.insert);
- update = (Button) super.findViewById(R.id.update);
- del = (Button) super.findViewById(R.id.del);
- query = (Button) super.findViewById(R.id.query);
- myLayout = (LinearLayout) super.findViewById(R.id.mylayout);
- query.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- SQLiteActivity.this.listView = new ListView(SQLiteActivity.this);
- listView.setAdapter(new ArrayAdapter
(SQLiteActivity.this, android.R.layout.simple_list_item_1, - new DH10Cursor(SQLiteActivity.this.helper.getWritableDatabase()).find()));
- myLayout.addView(listView);
-
- }
- });
-
-
- insert.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- helper.insert("毛栗子", "1995-01-05");
- Toast.makeText(SQLiteActivity.this, "新增成功", 0).show();
- }
- });
- update.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- helper.update(1, "大白兔", "1995-01-05");
- Toast.makeText(SQLiteActivity.this, "修改成功", 0).show();
- }
- });
- del.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- helper.delete(1);
- Toast.makeText(SQLiteActivity.this, "删除成功", 0).show();
- }
- });
- }
-
-
- }
-
需要注意一下Cursor的下标是从0开始的有别于ResultSet
·模糊查询
·使用sql语句完成模糊查询
- public List
find(){ - List
all = new ArrayList(); - String sql = "select id,name,birthday from "+TABLENAME+" where name like ?";
- String args[] = new String[]{"%栗%"};
- Cursor result = this.db.rawQuery(sql, args);//执行查询语句
- //采用循环的形式去结果集中的数据
- for(result.moveToFirst();!result.isAfterLast();result.moveToNext()){
- all.add(result.getInt(0)+"====="+result.getString(1)+"====="+result.getString(2));
- }
- result.close();
- db.close();
- return all;
- }
·使用query方法完成
- public List
find(){ - List
all = new ArrayList(); - //String sql = "select id,name,birthday from "+TABLENAME+" where name like ?";
- String selection = "name like ?";
- String args[] = new String[]{"%栗%"};
- String columns[] = new String[]{"id","name","birthday"};
- Cursor result = this.db.query(TABLENAME, columns, selection, args, null, null, null);//执行查询语句
- //采用循环的形式去结果集中的数据
- for(result.moveToFirst();!result.isAfterLast();result.moveToNext()){
- all.add(result.getInt(0)+"====="+result.getString(1)+"====="+result.getString(2));
- }
- result.close();
- db.close();
- return all;
- }
既然模糊查询已经能够完成了,那么还有一种功能可以往下去实现,那就是数据的分页。如果想要实现数据的部分显示,这个语句和Mysql中的查询方式是非常相似,使用limit完成。下面我们进行一些简单的分页操作。
- public List
find(){ - int currentPage = 1;//当前页码
- int lineSize = 5;//每页显示的数据量
- List
all = new ArrayList(); - String sql = "select id,name,birthday from "+TABLENAME+" limit ?,?";
- String args[] = new String[]{String.valueOf((currentPage-1)*lineSize),String.valueOf(currentPage*lineSize)};
- Cursor result = this.db.rawQuery(sql, args);
- //采用循环的形式去结果集中的数据
- for(result.moveToFirst();!result.isAfterLast();result.moveToNext()){
- all.add(result.getInt(0)+"====="+result.getString(1)+"====="+result.getString(2));
- }
- result.close();
- db.close();
- return all;
- }
·使用ListView来实现滑动分页
Android中有这样一个操作,只需要手指进行上下滑动,屏幕自动滚动,到达最后一条数据的时候,提示:请稍等,数据正在加载......。这个操作需要使用SimpleAdapter来完成,因为在这个适配器中有下面这样一个方法。
pulibc void notifyDataSetChanged()
表示如果在SimpleAdapter中的填充数据集合list内容一旦发生变化,就会立刻通知ListView进行及时新数据加载,当数据加载底部的时候,需要提示一个信息,而这个信息可以通过ListView组件里的方法去添加
public void addFooterView(View v)
现在还剩下一个问题,需要去监听滚动事件,需要使用如下接口:

首先顶一个ListView的布局模板。
- "1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android" - android:id="@+id/mylayout"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
-
-
- android:id="@+id/id"
- android:layout_width="50px"
- android:layout_height="wrap_content"
- android:textSize="30px"
- />
-
- android:id="@+id/name"
- android:layout_width="120px"
- android:layout_height="wrap_content"
- android:textSize="30px"
- />
-
- android:id="@+id/birthday"
- android:layout_width="130px"
- android:layout_height="wrap_content"
- android:textSize="30px"
- />
-
-
-
现在我们需进行查询操作,需要返回一共有多少笔数据,修改一下查询的类
- package com.example.sqliteproject;
-
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
-
- import android.database.Cursor;
- import android.database.sqlite.SQLiteDatabase;
-
- public class DH10Cursor {
- private static final String TABLENAME="DH10";
- private SQLiteDatabase db =null;
- public DH10Cursor(SQLiteDatabase db) {
- super();
- this.db = db;
- }
-
- public List
- List
- String sql = "select id,name,birthday from "+TABLENAME+" limit ?,?";
- String args[] = new String[]{String.valueOf((currentPage-1)*lineSize),String.valueOf(currentPage*lineSize)};
- Cursor result = this.db.rawQuery(sql, args);
- for(result.moveToFirst();!result.isAfterLast();result.moveToNext()){
- Map
map = new HashMap(); - map.put("id", result.getInt(0));
- map.put("name", result.getString(1));
- map.put("birthday", result.getString(2));
- list.add(map);
- }
- return list;
- }
-
- public int getCount(){
- int count = 0;
- String sql = "select count(id) from "+TABLENAME;
- Cursor result = this.db.rawQuery(sql, null);
- for(result.moveToFirst();!result.isAfterLast();result.moveToNext()){
- count = result.getInt(0);//取得数据的总笔数
- }
- return count;
- }
- }
-
下面写一下主布局文件,这个比较简单,直接放一个线性布局管理器就可以了。
- "1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android" - android:id="@+id/mainlayout"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
-
-
-
现在只剩下Activity
- package com.example.sqliteproject;
-
- import java.util.List;
- import java.util.Map;
-
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.Gravity;
- import android.widget.AbsListView;
- import android.widget.AbsListView.OnScrollListener;
- import android.widget.LinearLayout;
- import android.widget.LinearLayout.LayoutParams;
- import android.widget.ListView;
- import android.widget.SimpleAdapter;
- import android.widget.TextView;
-
- import com.example.sqliteopenhelper.MySQLiteOpenHelper;
-
- public class SQLiteActivity extends Activity {
- MySQLiteOpenHelper helper=null;
- ListView listView = null;
- LinearLayout mainLayout = null;
- int currentPage = 1;
- int lineSize = 5;
- int count = 0;
- int pageSize = 1;//总页数
- int lastItem = 0;//保存最后一个记录点
- SimpleAdapter adapter = null;
- TextView tv = null;//底部信息
- LinearLayout loadLayout = null;//底部提示框布局
- List
> list = null; - LayoutParams lp= new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- super.setContentView(R.layout.listview_main);
- this.mainLayout=(LinearLayout) super.findViewById(R.id.mainlayout);
- this.loadLayout=new LinearLayout(this);
- this.tv = new TextView(this);
- tv.setText("数据加载中,请稍后。。。");
- tv.setGravity(Gravity.CENTER);
- tv.setTextSize(30);
- loadLayout.addView(this.tv,this.lp);
- loadLayout.setGravity(Gravity.CENTER);
- this.showAllData();
- }
-
- private void showAllData(){
- this.helper = new MySQLiteOpenHelper(this);
- this.listView = new ListView(this);
- DH10Cursor cursor = new DH10Cursor(this.helper.getWritableDatabase());//获得一个查询操作对象
- this.count = cursor.getCount();//取得总数据笔数
- this.list = cursor.find(currentPage, lineSize);
- this.adapter = new SimpleAdapter(this, list, R.layout.listview_item_layout,
- new String[]{"id","name","birthday"},new int[]{R.id.id,R.id.name,R.id.birthday});//实例化适配器对象
- SQLiteActivity.this.listView.addFooterView(SQLiteActivity.this.loadLayout);
- this.listView.setAdapter(adapter);
- this.listView.setOnScrollListener(new OnScrollListener() {
-
- @Override
- public void onScrollStateChanged(AbsListView view, int scrollState) {
- if(SQLiteActivity.this.lastItem==SQLiteActivity.this.adapter.getCount()//表示当前记录已经在最底部
- &&SQLiteActivity.this.currentPage
this.pageSize//当前页要小于总页数 - &&scrollState==OnScrollListener.SCROLL_STATE_IDLE//屏幕不再滚动
- ){
- SQLiteActivity.this.currentPage++;
- SQLiteActivity.this.listView.setSelection(SQLiteActivity.this.lastItem);//设置显示位置
- SQLiteActivity.this.listView.addFooterView(SQLiteActivity.this.loadLayout);
- SQLiteActivity.this.appendData();
- }
-
- }
-
- @Override
- public void onScroll(AbsListView view, int firstVisibleItem,
- int visibleItemCount, int totalItemCount) {
- SQLiteActivity.this.lastItem = firstVisibleItem+visibleItemCount-1;
- }
- });
- mainLayout.addView(this.listView);
- if(this.count%this.lineSize==0){
- this.pageSize = this.count/this.lineSize;
- }else{
- this.pageSize = this.count/this.lineSize+1;
- }
- }
- private void appendData(){//更新数据方法
- DH10Cursor cursor = new DH10Cursor(this.helper.getWritableDatabase());
- List
> newData = cursor.find(currentPage, lineSize); - this.list.addAll(newData);
- this.adapter.notifyDataSetChanged();//适配器重新加载集合数据
- }
- }
以上就是整个实现下滑屏幕实现分页加载数据的程序。

事务的处理是针对数据库而已,以后的开发当中,只要针对增删改,都需要用事务进行处理。
- public void insert(String name,String birthday){
- SQLiteDatabase db = super.getWritableDatabase();//取得数据库操作对象
- db.beginTransaction();//开启事务
- try{
- ContentValues cv = new ContentValues();
- cv.put("name", name);
- cv.put("birthday", birthday);
- db.insert(TABLENAME, null, cv);//进行新增操作
- db.setTransactionSuccessful();//正确执行,否则回滚
- }catch(Exception e){
- db.endTransaction();//事务关闭
- db.close();
- }
-
- }
1.3 小结
(1)SQLite数据库是一个专门用于嵌入式设备的数据库;
(2)SQLite支持SQL语句的操作;
(3)可以使用SQLiteOpenHelper类完成数据库的操作;
(4)所有的查询数据使用Cursor进行接收;
-
相关阅读:
几个实用的MySQL内置函数使用方法
基于PHP实现微信客服欢迎语发送
Flask框架——项目可安装化
自动驾驶系列(六)——谈谈车载人机交互技术
DQL where查询
搭建Windows7 openssh服务器 jenkins slave 就可以自动起来了
总结tab栏切换实现的方法,以及增加滚动实现tab栏切换的效果
I Pa?sWorD
【教育创新,智慧引领】璞公英教学平台精准引领个性化教育!
我的AI存储实践及思考
-
原文地址:https://blog.csdn.net/weixin_41830242/article/details/132717434