zoukankan      html  css  js  c++  java
  • 数据库Sqlite的分页显示。

      很久没有写东西了,一来是因为项目紧,没有多少时间,二来是因为最近越来越懒了。。。。

      今天说说数据库的分页显示问题,都是些自己在项目中碰到的问题,写在这里,留作以后复习用。。。。

      所谓数据库的分页显示,必须先要有一个数据库,先创建一个数据库。我这里用的是继承SQLiteOpenHelper的方法。具体如下:

    1 package com.android.database;
    2
    3  import android.content.ContentValues;
    4  import android.content.Context;
    5  import android.database.sqlite.SQLiteDatabase;
    6  import android.database.sqlite.SQLiteOpenHelper;
    7  import android.provider.BaseColumns;
    8  /**
    9 *
    10 * @author shangzhenxiang
    11 * 创建数据库,继承SQLiteOpenHelper。
    12 *
    13 */
    14  public class DBHelper extends SQLiteOpenHelper {
    15
    16 private static final String DATABASE_NAME = "database.db";
    17 private static final int DATABASE_VERSION = 1;
    18 private static final String TABLE_NAME = "database";
    19 public static final String FIELD_TITLE = "title";
    20
    21 public DBHelper(Context context) {
    22 super(context, DATABASE_NAME, null, DATABASE_VERSION);
    23 }
    24
    25 /**
    26 * 创建表,写一个创建表的sql语句,然后调用db.execSQL(sql);之后向表中添加几条数据。
    27 */
    28 @Override
    29 public void onCreate(SQLiteDatabase db) {
    30 String sql="Create table "+TABLE_NAME+"("+BaseColumns._ID+" integer primary key autoincrement,"
    31 + FIELD_TITLE + " text );";
    32 db.execSQL(sql);
    33
    34 //初始化数据库
    35   initDatabase(db);
    36 }
    37
    38 //向数据库的表中插入一些数据。
    39   private void initDatabase(SQLiteDatabase db) {
    40 ContentValues cv = new ContentValues();
    41 cv.put("title", "cctv1 news");
    42 db.insert(TABLE_NAME, null, cv);
    43
    44 cv.clear();
    45 cv.put("title", "cctv2 news");
    46 db.insert(TABLE_NAME, null, cv);
    47
    48 cv.clear();
    49 cv.put("title", "cctv3 news");
    50 db.insert(TABLE_NAME, null, cv);
    51
    52 cv.clear();
    53 cv.put("title", "cctv4 news");
    54 db.insert(TABLE_NAME, null, cv);
    55
    56 cv.clear();
    57 cv.put("title", "cctv5 news");
    58 db.insert(TABLE_NAME, null, cv);
    59
    60 cv.clear();
    61 cv.put("title", "cctv6 news");
    62 db.insert(TABLE_NAME, null, cv);
    63
    64 cv.clear();
    65 cv.put("title", "cctv7 news");
    66 db.insert(TABLE_NAME, null, cv);
    67
    68 cv.clear();
    69 cv.put("title", "cctv8 news");
    70 db.insert(TABLE_NAME, null, cv);
    71
    72 cv.clear();
    73 cv.put("title", "cctv9 news");
    74 db.insert(TABLE_NAME, null, cv);
    75
    76 cv.clear();
    77 cv.put("title", "cctv10 news");
    78 db.insert(TABLE_NAME, null, cv);
    79
    80 cv.clear();
    81 cv.put("news_title", "guangshui tv");
    82 db.insert(TABLE_NAME, null, cv);
    83 }
    84
    85 //这里是用于更新数据库的。
    86   @Override
    87 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    88 String sql=" DROP TABLE IF EXISTS "+TABLE_NAME;
    89 db.execSQL(sql);
    90 onCreate(db);
    91 }
    92 }

      代码注释的比较清楚,数据库很简单,只有一个id 和 title键值,id是自动增长的,是系统自动的,在创建数据库的时候,我在里面加了9跳数据,用作测试用。

      数据库写完了,那好,我们要测试一下,到底生成了数据库文件没有呢?

      这时我们要写一个测试程序,来生成数据库文件,这需要在 manifest文件中做一些处理,如下所示:

    1 <?xml version="1.0" encoding="utf-8"?>
    2  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    3 package="com.android.sqlite"
    4 android:versionCode="1"
    5 android:versionName="1.0">
    6 <uses-sdk android:minSdkVersion="8" />
    7
    8 <!-- android:targetPackage 是用来存放生成的数据库的位置的,可以和manifest中的package相同 -->
    9 <instrumentation
    10 android:name="android.test.InstrumentationTestRunner"
    11 android:targetPackage="com.android.sqlite"
    12 android:label="test for my app"/>
    13
    14 <application android:icon="@drawable/icon" android:label="@string/app_name">
    15 <!-- 这个是用来说明android测试的包 -->
    16 <uses-library android:name="android.test.runner"/>
    17 <activity android:name=".TestSqlite"
    18 android:label="@string/app_name">
    19 <intent-filter>
    20 <action android:name="android.intent.action.MAIN" />
    21 <category android:name="android.intent.category.LAUNCHER" />
    22 </intent-filter>
    23 </activity>
    24
    25 </application>
    26  </manifest>

      首先要在manifest下建一个instrumentation的东西,里面有名字,目标包:这个是存放生成的数据库文件的路径,至于标签,随便写写就可以了。

      然后我们创建一个继承自AndroidTestCase得类,在里面写一个方法。调用DBHelper里面的getReadableDatabase或者getWritableDatabase就可以生成数据库文件了,如下所示:

    1 package com.android.database;
    2
    3  import android.test.AndroidTestCase;
    4  /**
    5 *
    6 * @author shangzhenxiang
    7 *
    8 */
    9  public class DBTest extends AndroidTestCase {
    10 public void testCreateRecordedDB() throws Exception {
    11 DBHelper recordedDbHelper = new DBHelper(this.getContext());
    12 /**
    13 * 当我们调用recordedDbHelper的getWritableDatabase()或getReadableDatabase()的时候,
    14 * 都会导致数据库的生成
    15 */
    16 recordedDbHelper.getWritableDatabase();
    17  // recordedDbHelper.getReadableDatabase();
    18   }
    19 }

      生成的数据库文件在哪里呢?

      在data文件夹下的data文件夹中找到刚刚在manifest中的targetPackage:

      

      目标包中有个database的文件夹,里面就是生成的数据库文件,如下图:

      

      数据库完成了,我们需要写一个单独的类用来显示页数和每一页上的个数,如图所示:

    1 package com.android.domain;
    2
    3  public class Model {
    4
    5 /**
    6 * @author shangzhenxiang
    7 * index 用于显示页数
    8 * View_Count 用于每一页上显示的个数
    9 */
    10 private int index;
    11 private int View_Count;
    12
    13 public Model(int index, int View_Count) {
    14 this.index = index;
    15 this.View_Count = View_Count;
    16 }
    17
    18 public int getIndex() {
    19 return index;
    20 }
    21
    22 public void setIndex(int index) {
    23 this.index = index;
    24 }
    25
    26 public int getView_Count() {
    27 return View_Count;
    28 }
    29
    30 public void setView_Count(int view_Count) {
    31 View_Count = view_Count;
    32 }
    33
    34
    35 }

      我们还需要一个服务来操作数据库,就是我们常说的业务逻辑层。

      我们需要对数据库做什么操作,都可以写到这个类中:

    1 package com.android.service;
    2
    3  import java.util.ArrayList;
    4
    5  import android.content.Context;
    6  import android.database.Cursor;
    7  import android.database.sqlite.SQLiteDatabase;
    8
    9 import com.android.database.DBHelper;
    10 /**
    11 *
    12 * @author shangzhenxiang
    13 *
    14 */
    15 public class DatabaseService {
    16
    17 private Context mContext;
    18 private DBHelper dbHelper;
    19
    20 public DatabaseService(Context context) {
    21 // TODO Auto-generated constructor stub
    22 mContext = context;
    23 dbHelper = new DBHelper(mContext);
    24 }
    25
    26 //添加
    27 public void insert(String title) {
    28 SQLiteDatabase db = dbHelper.getWritableDatabase();
    29 String sql = "insert into database(title) values(?)";
    30 db.execSQL(sql, new String[]{title});
    31 }
    32
    33 //删除
    34 public void delete(String title) {
    35 SQLiteDatabase db = dbHelper.getWritableDatabase();
    36 String sql = "delete from database where title = ?";
    37 db.execSQL(sql, new String[]{title});
    38 }
    39
    40 //查找
    41 public ArrayList<String> find(int id) {
    42 SQLiteDatabase db = dbHelper.getWritableDatabase();
    43 String sql = "select * from database where _id = ? ";
    44 Cursor c = db.rawQuery(sql, new String[]{String.valueOf(id)});
    45 ArrayList<String> titles = new ArrayList<String>();
    46 if(c.moveToNext()) {
    47 String title =c.getString(c.getColumnIndexOrThrow(DBHelper.FIELD_TITLE));
    48 titles.add(title);
    49 return titles;
    50 }
    51 //不用忘记关闭Cursor。
    52 c.close();
    53 return null;
    54 }
    55
    56 //更新
    57 public void upDate(int id, String title) {
    58 SQLiteDatabase db = dbHelper.getWritableDatabase();
    59 String sql = "update database set title =? where _id = ?";
    60 db.execSQL(sql, new String[]{String.valueOf(title), String.valueOf(id)});
    61 }
    62
    63 //查询记录的总数
    64 public long getCount() {
    65 SQLiteDatabase db = dbHelper.getWritableDatabase();
    66 String sql = "select count(*) from database";
    67 Cursor c = db.rawQuery(sql, null);
    68 c.moveToFirst();
    69 long length = c.getLong(0);
    70 c.close();
    71 return length;
    72 }
    73
    74 /**
    75 * 拿到所有的记录条数
    76 * @param firstResult 从第几条数据开始查询。
    77 * @param maxResult 每页显示多少条记录。
    78 * @return 当前页的记录
    79 */
    80 public Cursor getAllItems(int firstResult, int maxResult) {
    81 SQLiteDatabase db = dbHelper.getWritableDatabase();
    82 String sql = "select * from database limit ?,?";
    83 Cursor mCursor = db.rawQuery(sql, new String[]{String.valueOf(firstResult), String.valueOf(maxResult)});
    84 return mCursor;
    85 }
    86 }

      写一个布局。里面有一个ListView和2个Button:

    1 <?xml version="1.0" encoding="utf-8"?>
    2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    3 android:orientation="vertical"
    4 android:layout_width="match_parent"
    5 android:layout_height="match_parent"
    6 >
    7 <ListView
    8 android:id="@+id/testList"
    9 android:layout_width="match_parent"
    10 android:layout_height="0dip"
    11 android:layout_weight="3"/>
    12 <LinearLayout
    13 android:orientation="horizontal"
    14 android:layout_width="match_parent"
    15 android:layout_height="0dip"
    16 android:layout_weight="1">
    17 <Button
    18 android:id="@+id/leftButton"
    19 android:layout_width="wrap_content"
    20 android:layout_height="wrap_content"
    21 android:text="@string/previous"/>
    22 <Button
    23 android:id="@+id/rightButton"
    24 android:layout_width="wrap_content"
    25 android:layout_height="wrap_content"
    26 android:text="@string/next"/>
    27 </LinearLayout>
    28 </LinearLayout>

    我们需要对这个ListView设置一个Adapter,如下:

    1 package com.android.sqlite;
    2
    3 import android.content.Context;
    4 import android.database.Cursor;
    5 import android.view.LayoutInflater;
    6 import android.view.View;
    7 import android.view.ViewGroup;
    8 import android.widget.CursorAdapter;
    9 import android.widget.TextView;
    10
    11 import com.android.domain.Model;
    12 /**
    13 *
    14 * @author shangzhenxiang
    15 *
    16 */
    17 public class TestListAdapter extends CursorAdapter {
    18
    19 private Context mContext;
    20 private Cursor mCursor;
    21 private Model mModel;
    22 private LayoutInflater mInflater;
    23
    24 public TestListAdapter(Context context, Cursor c, Model model) {
    25 super(context, c);
    26 System.out.println("c = " + c);
    27 this.mContext = context;
    28 this.mCursor = c;
    29 this.mModel = model;
    30 mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    31 }
    32
    33 @Override
    34 public View newView(Context context, Cursor cursor, ViewGroup parent) {
    35 return mInflater.inflate(R.layout.listitem, parent, false);
    36 }
    37
    38 @Override
    39 public void bindView(View view, Context context, Cursor cursor) {
    40 ViewHolder holder = null;
    41
    42 Object tag = view.getTag();
    43 if(tag instanceof ViewHolder) {
    44 holder = (ViewHolder) view.getTag();
    45 }
    46 if(holder == null) {
    47 holder = new ViewHolder();
    48 view.setTag(holder);
    49 holder.title = (TextView) view.findViewById(R.id.listitemtitle);
    50 }
    51 //将从数据库中查询到的title设为ListView的Item项。
    52 holder.title.setText(cursor.getString(cursor.getColumnIndexOrThrow("title")));
    53 }
    54
    55 static class ViewHolder {
    56 TextView title;
    57 }
    58 }

      传进去一个Model的参数和一个Cursor。Model用于显示每页的个数和第几页,Cursor用于传递数据:

      在Activity中我们对Button做监听:

      向左移的时候就将Model中的index减一,向右就加一,同时改变cursor中传进去的Model的值,刷新Adapter,刷新界面,

      同时检查Button的可用性:

    1 package com.android.sqlite;
    2
    3 import android.app.Activity;
    4 import android.database.Cursor;
    5 import android.os.Bundle;
    6 import android.view.View;
    7 import android.view.View.OnClickListener;
    8 import android.widget.Button;
    9 import android.widget.ListView;
    10
    11 import com.android.domain.Model;
    12 import com.android.service.DatabaseService;
    13 /**
    14 *
    15 * @author shangzhenxiang
    16 *
    17 */
    18 public class TestSqlite extends Activity implements OnClickListener {
    19
    20 private ListView mListView;
    21 private TestListAdapter mTestListAdapter;
    22 private DatabaseService mDatabaseService;
    23 private Cursor mCursor;
    24 private Model mModel;
    25 private Button mLeftButton;
    26 private Button mRightButton;
    27
    28 @Override
    29 public void onCreate(Bundle savedInstanceState) {
    30 super.onCreate(savedInstanceState);
    31 setContentView(R.layout.main);
    32 mListView = (ListView) findViewById(R.id.testList);
    33 //创建一个DatabaseService的对象。
    34 mDatabaseService = new DatabaseService(this);
    35 //创建一个Model的对象,表面这是首页,并且每页显示5个Item项
    36 mModel = new Model(0, 5);
    37 //mCursor查询到的是第0页的5个数据。
    38 mCursor = mDatabaseService.getAllItems(mModel.getIndex()*mModel.getView_Count(), mModel.getView_Count());
    39 System.out.println("mCursor = " + mCursor);
    40 //根据参数创建一个TestListAdapter对象,并设给ListView。
    41 mTestListAdapter = new TestListAdapter(this, mCursor, mModel);
    42 mListView.setAdapter(mTestListAdapter);
    43 mLeftButton = (Button) findViewById(R.id.leftButton);
    44 mRightButton = (Button) findViewById(R.id.rightButton);
    45 //设置Button的监听
    46 mLeftButton.setOnClickListener(this);
    47 mRightButton.setOnClickListener(this);
    48 checkButton();
    49 }
    50
    51 //在Activity 销毁的时候记得将Cursor关掉。
    52 @Override
    53 protected void onDestroy() {
    54 // TODO Auto-generated method stub
    55 super.onDestroy();
    56 mCursor.close();
    57 }
    58
    59 @Override
    60 public void onClick(View v) {
    61 // TODO Auto-generated method stub
    62 int id = v.getId();
    63 switch (id) {
    64 case R.id.leftButton:
    65 //页数向前翻一页,同时将Cursor重新查一遍,然后changeCursor,notifyDataSetChanged。
    66 //检查Button的可用性。
    67 mModel.setIndex(mModel.getIndex() - 1);
    68 mCursor = mDatabaseService.getAllItems(mModel.getIndex()*mModel.getView_Count(), mModel.getView_Count());
    69 mTestListAdapter.changeCursor(mCursor);
    70 mTestListAdapter.notifyDataSetChanged();
    71 checkButton();
    72 break;
    73
    74 //页数向后翻一页,同时将Cursor重新查一遍,然后changeCursor,notifyDataSetChanged。
    75 //检查Button的可用性。
    76 case R.id.rightButton:
    77 mModel.setIndex(mModel.getIndex() + 1);
    78 mCursor = mDatabaseService.getAllItems(mModel.getIndex()*mModel.getView_Count(), mModel.getView_Count());
    79 mTestListAdapter.changeCursor(mCursor);
    80 mTestListAdapter.notifyDataSetChanged();
    81 checkButton();
    82 break;
    83
    84 default:
    85 break;
    86 }
    87 }
    88 /**
    89 * 如果页数小于或等于0,表示在第一页,向左的按钮设为不可用,向右的按钮设为可用。
    90 * 如果总数目减前几页的数目,得到的是当前页的数目,如果比这一页要显示的少,则说明这是最后一页,向右的按钮不可用,向左的按钮可用。
    91 * 如果不是以上两种情况,则说明页数在中间,两个按钮都设为可用。
    92 */
    93 private void checkButton() {
    94 if(mModel.getIndex() <= 0) {
    95 mLeftButton.setEnabled(false);
    96 mRightButton.setEnabled(true);
    97 } else if(mDatabaseService.getCount() - mModel.getIndex()*mModel.getView_Count() <= mModel.getView_Count()) {
    98 mRightButton.setEnabled(false);
    99 mLeftButton.setEnabled(true);
    100 } else {
    101 mLeftButton.setEnabled(true);
    102 mRightButton.setEnabled(true);
    103 }
    104 }
    105 }

      代码中的注释写的比较清楚,记性不太好,留作以后复习用。

    代码:

    TestSqlite

  • 相关阅读:
    DQL2.3.开始使用Dgraph基本类型和操作
    DQL2.7.开始使用Dgraph模糊搜索
    启动时查看配置文件application.yml
    从源码角度,带你研究什么是三级缓存
    Spring Boot 在启动时进行配置文件加解密
    论Redis分布式锁的正确使用姿势
    SpringBoot中整合Redis、Ehcache使用配置切换 并且整合到Shiro中
    在项目中,如何保证幂等性
    给你的SpringBoot做埋点监控JVM应用度量框架Micrometer
    从源码层面带你实现一个自动注入注解
  • 原文地址:https://www.cnblogs.com/shang53880/p/1981749.html
Copyright © 2011-2022 走看看