首先网上关于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>
android数据库Sqlite的正确使用方法
最新推荐文章于 2024-04-30 14:08:57 发布