android数据库Sqlite的正确使用方法

首先网上关于sqlite的帖子有很多,但大多都是如何使用相关的类和方法,代码也比较不规范,这里是专门针对新人教你如何在应用中使用sqlite数据库的。只是给大家一个示范,具体怎么用可以根据自己的应用需要具体分析。

绝大多数语言中使用数据都遵循这样一个过程,连接—打开—执行—关闭。但是android中省略了“连接”这一过程,这是因为android内置的数据库对安全性要求不高。

应用程序中操作数据库至少应当有五个类。第一,使用数据context类,第二,model类,第三,继承了SQLiteOpenHelper的类,第四,操作某个数据表的数据操作类,第五,管理数据库操作类的工具类。

他们各自的用途是:

一,首先你创建个数据库肯定不是用来逗我玩的。既然创建了数据库,就一定会用到数据库中的数据。对数据的应用可以是向数据库中插入数据,也可以是从数据 库中获取数据。而context类就可以是数据的来源或者数据应用的位置,这个context可以是activity,比如让用户输入账户信息并存储到数据库中,也可以是server, 比如后台从数据库中获取music的uri并根据uri来播放音乐。你可以根据软件的功能来分析哪些数据应当存储到数据库中。

二,这个没什么好说的,从第一次接触面向对象程序设计就应该知道model是什么了吧。model就是对程序要操作的某个对象的抽象设计,其包含对象的各个属性和 相关的方法。举例来说,就是绝大多数程序都有用户这个对象,这个对象含有用户名,密码,昵称,注册日期等属性,这就是一个model。程序中的每一个model都对应 数据库中的一个数据表,每一个属性对应数据库中的一个字段。原则上来说,model类的名称应当是和表名完全相同的,model中的属性名必须和数据表中对应的字段是 完全相同的,其数据类型应当和数据表中的数据类型相同或相近。(数据库没有String,可以是nvarchar(n))

三,SQLiteOpenHelper是一个抽象类,我们可以写一个类来继承它。这个类的主要功能是创建数据库,打开数据库,和更新数据库。绝大多数程序员会在这个类的 类名末尾加上Helper字样。

四,具体的数据库操作类,每个表对应一个,主要用来执行数据库语句和相关的直接操作数据库的方法,类名一般是model名(表名)加Dao(如果model名中有“t b_”或类似标识符应去除)。比如“MusicDao”。

五,工具类,主要执行一些逻辑上的操作,比如判断从数据库提取的数据是否是我们想要的数据,或者对从用户那里传来的数据进行加工,变成数据库接受的数据 等等。要说明的是,只有工具类可以使用相关的数据库操作类中的方法,而context类也只能通过工具类来对数据库进行操作,应杜绝类似从activity中直接调用数据 库的行为。(尽管网上有很多的教程这么做)。也不允许在context中进行算法相关的方法,跟逻辑或是算法相关的部分应当放到工具类或是管理类中去。context的工 作应该是接收数据,和显示(使用)数据,而不是对数据的处理。

下面从具体的案例中来理解这个过程:

我要做的就是设计一个登陆界面,然后把用户输入的个人信息保存到数据库中,再从另一个界面中获取并显示数据库中的数据。

首先新建项目,并新建一个包,包名就叫model,在这个包下新建model类(开发程序时应当先设计数据库,这里省略了这一过程)user中有用户名,密码,昵称三 个属性。程序如下,细心的可能发现有些方法可能根本没用或者永远不会用到,但我还是写了,因为这是一个model应有的规范。代码如下

 

package com.me.user.model;

public class Tb_user {
	private String name;
	private String password;
	private String nickname;
	
	public Tb_user(String name,String password,String nickname){
		this.name=name;
		this.password=password;
		this.nickname=nickname;
	}
	public String getName(){
		return this.name;
	}
	public void setName(String name){
		this.name=name;
	}
	
	public String getPassword(){
		return this.password;
	}
	public void setPassword(String password){
		this.password=password;
	}
	
	public String getNickname(){
		return this.nickname;
	}
	public void setNickname(String nickname){
		this.nickname=nickname;
	}
	
	public String toString(){
		return null;
	}
}

然后新建一个包,包名可以叫db,并在这个包下新建一个类来继承SQLiteOpenHelper类,继承后会有一个构造函数和两个方法,首先是构造函数中的四个参数,第 一个context,略过,第二个是数据库名称,第三个同样可以略过,如果有兴趣自行百度,第四个是数据库版本(你创建的数据库的版本,用来更新数据库用的),因 为我们没有必要每次打开数据库都指定数据库的名称和版本,所以新建一个构造方法。两个方法中,onCreate是第一次使用这个类时(数据库不存在时)调用的方法, 用来新建数据库,在这里你可以写新建数据表的sql语句。onUpgrade更新数据库时调用的方法(具体的说就是比如第一次建立数据库时版本为1,当你改为2并重新执行 程序就会调用这个方法,可以更改数据表的定义),还有一个方法onOpen是每次打开数据库时执行的。这里我新建了一个数据表。代码如下

package com.me.user.db;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class UserHelper extends SQLiteOpenHelper{
	
	private final static String DB_NAME="User.db";
	private final static int DB_VERSION=1;
	
	public UserHelper(Context context){
		super(context,DB_NAME,null,DB_VERSION);
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		db.execSQL("create table tb_user(name nvarchar(20),password nvarchar(20),nickname nvarchar(20))");	
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// TODO 自动生成的方法存根
		
	}

}<span style="font-family: Arial, Helvetica, sans-serif;"> </span>

然后就是数据库操作类。同样在db这个包下新建一个类,名叫userDao。一共有两个方法,即add和select,分别进行数据的添加和查询。我们对数据库的操作绝大 多数都是增删改查,其中只有查会有返回值,当我们需要处理大量数据时,可以使用事务来完成,这样可以节省时间。(事实上,对数据库的操作应当放到另一个线程 中执行,防止程序因为长时间等待而假死,这里我为了代码的简化没有那么做)事务的另一个作用是同步完成两个操作,比如把A用户删除,并且增加B用户,(如果A 用户没有删除则不增加B或者如果B没有增加则不删除A)可以用事务来包括这两个语句,两个语句中的任何一个执行失败,则两个都不执行。对于数据库的优化还包括 索引和视图等,可以自行百度。代码如下

package com.me.user.db;

import java.util.ArrayList;

import com.me.user.model.Tb_user;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

public class UserDao {
	private UserHelper mhelper;
	private SQLiteDatabase mdb;
	private Cursor cursor;
	
	public UserDao(Context context){
		mhelper=new UserHelper(context);
		mdb=mhelper.getWritableDatabase();
	}
	
	public void add(Tb_user user){
		mdb.execSQL("insert into tb_user values(?,?,?)",new Object[]{
				user.getName(),
				user.getPassword(),
				user.getNickname()
		});
	}
	
	public ArrayList<Tb_user> select(){
		Tb_user user=new Tb_user(null,null, null);
		ArrayList<Tb_user> users=new ArrayList<Tb_user>();
		cursor=mdb.rawQuery("select * from tb_user",null);
		while(cursor.moveToNext()){
			user.setName(cursor.getString(cursor.getColumnIndex("name")));
			user.setPassword(cursor.getString(cursor.getColumnIndex("password")));
			user.setNickname(cursor.getString(cursor.getColumnIndex("nickname")));
			users.add(user);
			cursor.moveToNext();
		}
		return users;
	}
	
	public void close(){
		mdb.close();
	}
}

然后是工具类,就是正常的java类,负责处理逻辑和算法部分,代码如下

package com.me.user.util;

import java.util.ArrayList;

import com.me.user.db.UserDao;
import com.me.user.model.Tb_user;

import android.content.Context;

public class UserDaoUtil {
	private UserDao mUserDao;
	private Tb_user mUser;
	
	public UserDaoUtil(Context context){
		mUserDao=new UserDao(context);
		mUser=new Tb_user(null, null, null);
	}
	
	public void addNewUser(String name,String password,String nickname){
		mUser.setName(name);
		mUser.setPassword(password);
		mUser.setNickname(nickname);
		mUserDao.add(mUser);
		mUserDao.close();
	}
	
	public Tb_user getFirstUser(){
		ArrayList<Tb_user> users=new ArrayList<Tb_user>();
		users=mUserDao.select();
		if(users.get(0)!=null){
			mUser=users.get(0);
		}
		return mUser;
		
	}
}



 

最后是context类,这里我用了两个activity分别用于注册和显示第一个用户(不管你注册多少次都只显示第一个用户,这是因为程序没有完善)。代码同样很简单,代码如下

第一个

package com.me.user;

import com.me.user.util.UserDaoUtil;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;


public class MainActivity extends Activity {
	
	private EditText mName;
	private EditText mPassword;
	private EditText mNickname;
	private TextView mText;
	
	private Button mEnter;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
        mEnter.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO 自动生成的方法存根
				if(mName.getText().toString()!=null&&mPassword.getText().toString()!=null&&mNickname.getText().toString()!=null){
					UserDaoUtil util=new UserDaoUtil(MainActivity.this);
					util.addNewUser(mName.getText().toString(), mPassword.getText().toString(), mNickname.getText().toString());
					Intent intent=new Intent(MainActivity.this,NextActivity.class);
					startActivity(intent);
				}else{
					mText.setText("输入的值不能为空");
				}
			}
		});
    }

    private void init() {
		mName=(EditText)findViewById(R.id.user_name);
		mPassword=(EditText)findViewById(R.id.user_password);
		mNickname=(EditText)findViewById(R.id.user_nickname);
		mEnter=(Button)findViewById(R.id.enter);
		mText=(TextView)findViewById(R.id.text);
		
	}

	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}
<span style="white-space:pre">		</span>第二个
<pre name="code" class="java">package com.me.user;

import com.me.user.model.Tb_user;
import com.me.user.util.UserDaoUtil;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

public class NextActivity extends Activity {
	
	private TextView mUser;
	private TextView mPassword;
	private TextView mNickname;
	
	private Tb_user tb_user;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_next);
		init();
		getData();
		setData();
	}

	private void setData() {
		mUser.setText(tb_user.getName());
		mPassword.setText(tb_user.getPassword());
		mNickname.setText(tb_user.getNickname());
	}

	private void getData() {
		UserDaoUtil util=new UserDaoUtil(NextActivity.this);
		tb_user=new Tb_user(null, null, null);
		tb_user=util.getFirstUser();
	}

	private void init() {
		mUser=(TextView)findViewById(R.id.txt_user);
		mPassword=(TextView)findViewById(R.id.txt_password);
		mNickname=(TextView)findViewById(R.id.txt_nickname);
		
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.next, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
}
<span style="white-space:pre">		</span>xml分别如下
<pre name="code" class="html"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="请注册"
        android:textSize="24sp"
        android:gravity="center"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:text="请输入用户名和:"
        android:textSize="20sp"
        android:gravity="bottom"/>
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="24sp"
        android:id="@+id/user_name"
        />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="请输入密码:"
        android:textSize="20sp"/>
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="24sp"
        android:password="true"
        android:id="@+id/user_password"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="请输入昵称:"
        android:textSize="20sp"/>
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="24sp"
        android:id="@+id/user_nickname"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="确认"
        android:textSize="20sp"
        android:id="@+id/enter"
        android:layout_gravity="center"/>
    <TextView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/text"
        android:textSize="20sp"
        />


</LinearLayout>
<span style="white-space:pre">		</span>和
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="数据库中的第一个用户是"
        android:textSize="24sp"
        android:gravity="center"/>
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="用户名:"
            android:textSize="24sp"/>
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/txt_user"
            android:textSize="24sp"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="密    码:"
            android:textSize="24sp"/>
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/txt_password"
            android:textSize="24sp"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="昵    称:"
            android:textSize="24sp"/>
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/txt_nickname"
            android:textSize="24sp"/>
    </LinearLayout>

</LinearLayout>





 



                
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值