每个应用程序都要使用数据,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());
				
			}
		});




就是增删改查,基本这样就结束了,奉上源码。