每个应用程序都要使用数据,Android应用程序也不例外,Android使用开源的、与操作系统无关的SQL数据库—SQLite。Android提供了SQLiteDatabase代表一个数据库(底层就是一个数据库文件),一旦应用程序获得了代表指定数据库的SQliteDatabase对象,接下来就可通过SQLiteDatabase对象来管理、操作数据库了
正如前面提到的,SQLiteDatabase的exeSQL方法可执行任意SQL语句,包括带占位符dSQL语句。但由于该方法没有返回值,一般用于执行DDL语句。
下面的程序示范了如何在Android应用中操作SQlite数据库,该程序提供了两个文本框,用户可以在文本框中输入内容,当用户单击“add”按钮时这两个文本框输入内容,也可以删除,修改和查询。
一 数据库方面
下面是建数据库,Android提供了SQliteDatabase代表一个数据库,一旦应用程序获得了代表指定数据库的SQliteDatabase对象,接下来就可通过SQLiteDattabase对象来管理、操作数据库了。
package com.example.text5;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.util.Log;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class MyDbHelper extends SQLiteOpenHelper{
private static final String DB_NAME = "student.db"; // 数据库名称
private static final int version = 2; // 数据库版本
public MyDbHelper(Context context, String name, CursorFactory factory, int version) {
super(context, name, factory, version);
}
public MyDbHelper(Context context) {
super(context, DB_NAME, null, version);
}
/**
* 当MyDBHelper对象被创建时,该方法被调用,该方法主要是来作一些初始化的数据,比如建表操作
*/
@Override
public void onCreate(SQLiteDatabase db) {
Log.d("sqlite", "***MyDBHelper's onCreate()....");
// 创建表
String createSQL = "create table come(id integer primary key,age int,name varchar(20) not null)";
db.execSQL(createSQL);
}
/**
* 修改操作
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
String dropSQL = "drop table come";
db.execSQL(dropSQL);
onCreate(db);
Log.d("sqlite", "***MyDBHelper's onUpgrade()....");
}
}
在程序中获取SQLiteDatabase对象之后,接下来就可调用SQLiteDatabase的如下方法来操作数据库了,直接看代码
首先初始化,一些准备工作
private MyDbHelper dbHelper;
private SQLiteDatabase db;
private List<Student> mDatas = new ArrayList<Student>();
public ComeModle(Context context) {
// TODO Auto-generated constructor stub
dbHelper = new MyDbHelper(context, "yuyin.db", null, 2);
try {
// 打开数据库
db = dbHelper.getWritableDatabase();
} catch (Exception e) {
// TODO: handle exception
db = dbHelper.getReadableDatabase();
}
}
增加操作
public void save(String age,String name){
String sql="insert into come(age,name) values (?,?)";
db.execSQL(sql, new String[]{age,name});
}
删除操作
public void delete(int id){
String sql ="delete from come where id =?";
db.execSQL(sql, new String[]{String.valueOf(id)});
}
public void update(int id,String age,String name){
String sql="update come set age=?,name=? where id=?";
db.execSQL(sql, new String[]{age,name,String.valueOf(id)});
db.close();
// ContentValues values =new ContentValues();
// values.put("age", age);
// values.put("name", name);
// db.update("come", values, "id=?", new String[]{String.valueOf(id)});
// db.close();
}
查询操作,其实语句一样,只是返回不同的类型
public List<Student> select(){
String sql="select * from come ";
Cursor cursor=db.rawQuery(sql,null);
while(cursor.moveToNext()){
int age=cursor.getInt(0);
String name=cursor.getString(1);
Student mStudent=new Student(age,name);
mDatas.add(mStudent);
}
return mDatas;
}
/**
* 返回类型Student
* @return
*/
public Student selectWithStudent(){
Student mStudent = null;
String sql="select * from come ";
Cursor cursor=db.rawQuery(sql,null);
while(cursor.moveToNext()){
int age=cursor.getInt(cursor.getColumnIndex("age"));
String name=cursor.getString(cursor.getColumnIndex("name"));
mStudent=new Student(age,name);
// mDatas.add(mStudent);
}
return mStudent;
}
/**
* 为获取Id等值,返回类型是Cursor
* @return
*/
public Cursor selectWithCursor(){
String sql="select * from come ";
Cursor cursor=db.rawQuery(sql,null);
// while(cursor.moveToNext()){
// int age=cursor.getInt(cursor.getColumnIndex("age"));
// String name=cursor.getString(cursor.getColumnIndex("name"));
// Student mStudent=new Student(age,name);
// mDatas.add(mStudent);
// }
return cursor;
}
上面的查询方法都是返回一个Cursor对象,Android中的Cursor类似于JDBC的ResultSet,Cursor同样提供了如下方法来移动查询结果的记录指针。
1)move(int offset):将记录指针向上或者向下移动指定的行数。offset为正数就是向下移动,为负数就是向上移动
2)boolean moveToFirst():将记录指针移动带第一行,如果成功则返回ture;
3)boolean moveToLast():将指针移动到最后一行,如果移动成功则返回ture;
4)boolean moveToNext():将指针移动到下一行,如果成功移动则返回ture;
5)boolean moveToPosition(int position):将记录移动到指定的行,如果成功则返回ture;
6)boolean moveToPrevious():将记录指针移动到上一行,如果成功则返回ture;
一旦将记录指针移动到指定行之后,接下来就可以调用Cursor的getXxx()方法获取该行指定列的数据。
二 适配器以及定义类
首先定义一个简单的Student类()
package com.example.text5;
public class Student {
private int age;
private String name;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
写一个适配器BaseAdapter
package com.example.text5;
import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class NotifyAdapter extends BaseAdapter {
private List<Student> mData;
private LayoutInflater mInflater;
public NotifyAdapter(Context context, List<Student> data) {
this.mData = data;
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return mData.size();
}
@Override
public Object getItem(int position) {
return mData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
// 判断是否缓存
if (convertView == null) {
holder = new ViewHolder();
// 通过LayoutInflater实例化布局
convertView = mInflater.inflate(R.layout.stu_item, null);
holder.age = (TextView) convertView.findViewById(R.id.agelist);
holder.name = (TextView) convertView.findViewById(R.id.namelist);
convertView.setTag(holder);
} else {
// 通过tag找到缓存的布局
holder = (ViewHolder) convertView.getTag();
}
// 设置布局中控件要显示的视图
Student mStudent=mData.get(position);
holder.age.setText(String.valueOf(mStudent.getAge()));;
holder.name.setText(mStudent.getName());
return convertView;
}
public final class ViewHolder {
public TextView age;
public TextView name;
}
}
写一个简单的布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.text5.MainActivity" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/agelist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="年龄" />
<EditText
android:id="@+id/age"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10" />
<TextView
android:id="@+id/namelist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="姓名" />
<EditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/add"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="add" />
<Button
android:id="@+id/delete"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="删" />
<Button
android:id="@+id/update"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="改" />
<Button
android:id="@+id/select"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="select" />
</LinearLayout>
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
首先初始化一下变量,这里重点讲一下如何通过点击获取Listview里面数据库的数据
mListview.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Cursor cursor = (Cursor)mListview.getItemAtPosition(position);
// STU_ID=cursor.getInt(cursor.getColumnIndex("id"));
mCursor.moveToPosition(position);
STU_ID=mCursor.getInt(0);
age.setText(mCursor.getString(1));
name.setText(mCursor.getString(2));
Log.d(TAG, "STU_ID:"+STU_ID);
}
});
这其实的Listview的点击事件,接下来通过moveToPosition方法,确定移动的行的数据,接下来就是获取。
以下是以下测试操作
add.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String mAge=age.getEditableText().toString();
String mName=name.getEditableText().toString();
if(age.equals("")||name.equals("")){
Toast.makeText(MainActivity.this, "年级姓名不能为空", Toast.LENGTH_LONG).show();
return;
}else{
mComeModle.save(mAge, mName);
age.setText("");
name.setText("");
Toast.makeText(MainActivity.this, "保存ok",Toast.LENGTH_LONG).show();
}
}
});
delete.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(STU_ID == 0){
return;
}
mComeModle.delete(STU_ID);
age.setText("");
name.setText("");
mAdapter.notifyDataSetChanged();
Log.d(TAG, "当前id:"+STU_ID);
}
});
update.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String mAge=age.getEditableText().toString();
String mName=name.getEditableText().toString();
if(("").equals(age)||("").equals(name)){
Toast.makeText(MainActivity.this, "年级姓名不能为空", Toast.LENGTH_LONG).show();
return;
}
mComeModle.update(STU_ID, mAge, mName);
age.setText("");
name.setText("");
Toast.makeText(MainActivity.this, "更新成功", Toast.LENGTH_LONG).show();
Log.d(TAG, "update");
}
});
select.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mDatas=mComeModle.select();
mAdapter=new NotifyAdapter(MainActivity.this, mDatas);
mListview.setAdapter(mAdapter);
// mAdapter.notifyDataSetChanged();
Log.d(TAG, "mDatas:"+mDatas.size());
}
});
就是增删改查,基本这样就结束了,奉上源码。