如何保存多列并显示单列列表视图?

时间:2018-03-23 19:26:36

标签: java android database sqlite listview

嘿,我正在尝试使用数据库助手使用数据库我能够按照吐司写入数据,但每当我获得记录列表视图时,应用程序停止工作请任何人都可以提供帮助。这是MainActivity.java的代码

package com.example.dhruv.bills;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import java.util.ArrayList;
public class bills extends AppCompatActivity {
DBAdapter dbAdapter;
ListView mrecycleview;
private static final String TAG ="bills";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bills);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    mrecycleview =(ListView) findViewById(R.id.mRecycleView);
    dbAdapter = new DBAdapter(this);
    // mlistview();
    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent i = new Intent(getApplicationContext(),Editbills.class);
            startActivity(i);
        }
    });
   // mlistview();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_bills, 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();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}
 /* private void mlistview(){
    Log.d(TAG,"mlistview:Display data in listview");
    Cursor mCursor = dbAdapter.getAllRecords();
    ArrayList<String> listData = new ArrayList<>();
    while (mCursor.moveToNext()){
        listData.add(mCursor.getString(1));
    }
    ListAdapter adapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,listData);
    mrecycleview.setAdapter(adapter);
}*/
}

这是我用来保存和读取数据库并在列表视图上显示它的DbAdapter的代码。

package com.example.dhruv.bills;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DBAdapter {
public static final String KEY_ROWID = "id";
public static final String KEY_TITLE = "title";
public static final String KEY_DUEDATE = "duedate";
public static final String KEY_COURSE = "course";
// public static final String KEY_NOTES = "notes";
private static final String TAG = "DBAdapter";

private static final String DATABASE_NAME = "billsdb";
private static final String DATABASE_TABLE = "bills";
private static final int DATABASE_VERSION = 2;

private static final String DATABASE_CREATE =
    "create table if not exists assignments (id integer primary key autoincrement, "
    + "title VARCHAR not null, duedate date, course VARCHAR );";

private final Context context;    

private DatabaseHelper DBHelper;
private SQLiteDatabase db;

public DBAdapter(Context ctx) 
{
    this.context = ctx;
    DBHelper = new DatabaseHelper(context);
}

private static class DatabaseHelper extends SQLiteOpenHelper 
{
    DatabaseHelper(Context context) 
    {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) 
    {
        try {
            db.execSQL(DATABASE_CREATE);    
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
    {
        Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                + newVersion + ", which will destroy all old data");
        db.execSQL("DROP TABLE IF EXISTS contacts");
        onCreate(db);
    }
}    

//---opens the database---
public DBAdapter open() throws SQLException 
{
    db = DBHelper.getWritableDatabase();
    return this;
}

//---closes the database---    
public void close() 
{
    DBHelper.close();
}

//---insert a record into the database---
public long insertRecord(String title, String duedate, String course) 
{
    ContentValues initialValues = new ContentValues();
    initialValues.put(KEY_TITLE, title);
    initialValues.put(KEY_DUEDATE, duedate);
    initialValues.put(KEY_COURSE, course);
    return db.insert(DATABASE_TABLE, null, initialValues);
}

//---deletes a particular record---
public boolean deleteContact(long rowId) 
{
    return db.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}

//---retrieves all the records---
public Cursor getAllRecords()
{SQLiteDatabase db = DBHelper.getWritableDatabase();
String query ="SELECT * FROM" + DATABASE_TABLE;
Cursor data = db.rawQuery(query,null);
    return data;
}

//---retrieves a particular record---
public Cursor getRecord()
{String query1 ="SELECT * FROM" + KEY_TITLE;
    Cursor mCursor = db.rawQuery(query1,null);
    if (mCursor != null) {
        mCursor.moveToFirst();
    }
    return mCursor;
}

//---updates a record---
public boolean updateRecord(long rowId, String title, String duedate, String course) 
{
    ContentValues args = new ContentValues();
    args.put(KEY_TITLE, title);
    args.put(KEY_DUEDATE, duedate);
    args.put(KEY_COURSE, course);
    return db.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
}
}

这是我得到的代码的logcat请求帮助

03-24 01:16:22.787 1096-1096/com.example.dhruv.bills E/AndroidRuntime: FATAL EXCEPTION: main
                                                                   Process: com.example.dhruv.bills, PID: 1096
                                                                   java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.dhruv.bills/com.example.dhruv.bills.bills}: android.database.sqlite.SQLiteException: near "FROMbills1": syntax error (code 1): , while compiling: SELECT * FROMbills1
                                                                       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2656)
                                                                       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2721)
                                                                       at android.app.ActivityThread.access$900(ActivityThread.java:168)
                                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393)
                                                                       at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                       at android.os.Looper.loop(Looper.java:135)
                                                                       at android.app.ActivityThread.main(ActivityThread.java:5753)
                                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                                       at java.lang.reflect.Method.invoke(Method.java:372)
                                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405)
                                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)
                                                                    Caused by: android.database.sqlite.SQLiteException: near "FROMbills1": syntax error (code 1): , while compiling: SELECT * FROMbills1
                                                                       at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
                                                                       at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1093)
                                                                       at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:670)
                                                                       at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
                                                                       at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:59)
                                                                       at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
                                                                       at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
                                                                       at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1454)
                                                                       at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1393)
                                                                       at com.example.dhruv.bills.DBAdapter.getAllRecords(DBAdapter.java:98)
                                                                       at com.example.dhruv.bills.bills.mlistview(bills.java:68)
                                                                       at com.example.dhruv.bills.bills.onCreate(bills.java:42)
                                                                       at android.app.Activity.performCreate(Activity.java:6112)
                                                                       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1117)
                                                                       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2609)
                                                                       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2721) 
                                                                       at android.app.ActivityThread.access$900(ActivityThread.java:168) 
                                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393) 
                                                                       at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                       at android.os.Looper.loop(Looper.java:135) 
                                                                       at android.app.ActivityThread.main(ActivityThread.java:5753) 
                                                                       at java.lang.reflect.Method.invoke(Native Method) 
                                                                       at java.lang.reflect.Method.invoke(Method.java:372) 
                                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405) 
                                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200) 

1 个答案:

答案 0 :(得分:1)

您在关键字FROM和表 bills1 之间省略了空格,即SQL FROMbills1应该是FROM bills1 (见下面的表格名称)

查看代码,您有两种应该更改的方法。而不是: -

//---retrieves all the records---
public Cursor getAllRecords()
{SQLiteDatabase db = DBHelper.getWritableDatabase();
String query ="SELECT * FROM" + DATABASE_TABLE;
Cursor data = db.rawQuery(query,null);
    return data;
}

//---retrieves a particular record---
public Cursor getRecord()
{String query1 ="SELECT * FROM" + KEY_TITLE;
    Cursor mCursor = db.rawQuery(query1,null);
    if (mCursor != null) {
        mCursor.moveToFirst();
    }
    return mCursor;
}
你可以: -

//---retrieves all the records---
public Cursor getAllRecords()
{SQLiteDatabase db = DBHelper.getWritableDatabase();
String query ="SELECT * FROM " + DATABASE_TABLE; //<<<< space added after FROM
Cursor data = db.rawQuery(query,null);
    return data;
}

//---retrieves a particular record---
public Cursor getRecord()
{String query1 ="SELECT * FROM " + KEY_TITLE; //<<<< space added after FROM
    Cursor mCursor = db.rawQuery(query1,null);
    if (mCursor != null) {
        mCursor.moveToFirst();
    }
    return mCursor;
}
  • 注意第二种方法会失败,因为KEY_TITLE解析为标题不是一个表格。

我无法从提供的代码中看到您如何获得表名 bills1 ,因为DATABASE_TABLE被定义为账单。此外,您的代码似乎只根据以下内容创建名为分配的表格: -

private static final String DATABASE_CREATE =
    "create table if not exists assignments (id integer primary key autoincrement, "
    + "title VARCHAR not null, duedate date, course VARCHAR );";

我建议在整个代码中只使用单个源表和列名。这样做可以在很大程度上消除这些问题。

其他

仔细看看DBAdapter类还有其他问题,这里是一个重写版本,它包含了表名和列名的单一定义,并修复了这些问题(参见注释): -

public class DBAdapter {
    public static final String KEY_ROWID = "id";
    public static final String KEY_TITLE = "title";
    public static final String KEY_DUEDATE = "duedate";
    public static final String KEY_COURSE = "course";
    // public static final String KEY_NOTES = "notes";
    private static final String TAG = "DBAdapter";

    private static final String DATABASE_NAME = "billsdb";
    private static final String DATABASE_TABLE = "bills";
    private static final int DATABASE_VERSION = 2;

    private static final String DATABASE_CREATE =
            "create table if not exists assignments (id integer primary key autoincrement, "
                    + "title VARCHAR not null, duedate date, course VARCHAR );";

    // Replaces DATABASE_CREATE using the one source definition
    private static final String TABLE_CREATE =
            "CREATE TABLE IF NOT EXISTS " + DATABASE_TABLE + "(" +
                    KEY_ROWID + " INTEGER PRIMARY KEY, " + // AUTOINCREMENT NOT REQD
                    KEY_TITLE + " DATE NOT NULL, " +
                    KEY_DUEDATE + " DATE ," +
                    KEY_COURSE + " VARCHAR " +
                    ")";

    private final Context context;

    private DatabaseHelper DBHelper;
    private SQLiteDatabase db;

    public DBAdapter(Context ctx)
    {
        this.context = ctx;
        DBHelper = new DatabaseHelper(context);
    }

    private static class DatabaseHelper extends SQLiteOpenHelper
    {
        DatabaseHelper(Context context)
        {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db)
        {
            db.execSQL(TABLE_CREATE); // NO need to encapsulate in try clause
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
        {
            Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                    + newVersion + ", which will destroy all old data");
            db.execSQL("DROP TABLE IF EXISTS contacts"); //????????
            db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
            onCreate(db);
        }
    }

    //---opens the database---
    public DBAdapter open() throws SQLException
    {
        db = DBHelper.getWritableDatabase();
        return this;
    }

    //---closes the database---
    public void close()
    {
        DBHelper.close();
    }

    //---insert a record into the database---
    public long insertRecord(String title, String duedate, String course)
    {
        ContentValues initialValues = new ContentValues();
        initialValues.put(KEY_TITLE, title);
        initialValues.put(KEY_DUEDATE, duedate);
        initialValues.put(KEY_COURSE, course);
        //return db.insert(DATABASE_TABLE, null, initialValues);
        // Will return NULL POINTER EXCEPTION as db isn't set
        // Replaces commented out line
        return DBHelper.getWritableDatabase().insert(DATABASE_TABLE,
                null,
                initialValues
        );
    }

    //---deletes a particular record---
    public boolean deleteContact(long rowId)
    {
        return db.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
    }

    //---retrieves all the records--- SEE FOLLOWING METHOD
    public Cursor getAllRecords()
    {SQLiteDatabase db = DBHelper.getWritableDatabase();
        String query ="SELECT * FROM " + DATABASE_TABLE;
        Cursor data = db.rawQuery(query,null);
        return data;
    }

    //As per getAllRecords but using query convenience method
    public Cursor getAllAsCursor() {
        return DBHelper.getWritableDatabase().query(
                DATABASE_TABLE,
                null,null,null,null,null,null
        );
    }

    //---retrieves a particular record--- THIS WILL NOT WORK - NO SUCH TABLE
    public Cursor getRecord()
    {String query1 ="SELECT * FROM" + KEY_TITLE;
        Cursor mCursor = db.rawQuery(query1,null);
        if (mCursor != null) {
            mCursor.moveToFirst();
        }
        return mCursor;
    }

    // Retrieve a row (single) according to id
    public Cursor getRecordById(long id) {
        return DBHelper.getWritableDatabase().query(
                DATABASE_TABLE,
                null,
                KEY_ROWID + "=?",
                new String[]{String.valueOf(id)},
                null,null,null
                );
    }


    //---updates a record---
    public boolean updateRecord(long rowId, String title, String duedate, String course)
    {
        ContentValues args = new ContentValues();
        args.put(KEY_TITLE, title);
        args.put(KEY_DUEDATE, duedate);
        args.put(KEY_COURSE, course);
        String whereclause = KEY_ROWID + "=?";
        String[] whereargs = new String[]{String.valueOf(rowId)};
        // Will return NULL POINTER EXCEPTION as db isn't set
        //return db.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
        // Replaces commented out line
        return DBHelper.getWritableDatabase().update(DATABASE_TABLE,
                args,
                whereclause,
                whereargs
        ) > 0;
    }
}

使用以下代码测试了上述代码(至少插入和检索数据): -

public class MainActivity extends AppCompatActivity {

    DBAdapter mDBAdapter;
    Cursor mCsr;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mDBAdapter = new DBAdapter(this);
        addSomeData();

        mCsr = mDBAdapter.getAllAsCursor();
        while (mCsr.moveToNext()) {
            Log.d("BILLDATA",
                    "Title="+mCsr.getString(mCsr.getColumnIndex(DBAdapter.KEY_TITLE)) +
                            " Due Date=" + mCsr.getString(mCsr.getColumnIndex(DBAdapter.KEY_DUEDATE)) +
                            " Course=" + mCsr.getString(mCsr.getColumnIndex(DBAdapter.KEY_COURSE))
            );
        }
        mCsr.close();
    }

    // Add some data (note will add 3 rows each time it is run)
    private void addSomeData() {
        mDBAdapter.insertRecord("Bill1","2018-10-02","English");
        mDBAdapter.insertRecord("Bill2","2018-09-03","Mathematics");
        mDBAdapter.insertRecord("Bill3","2018-11-04", "Geography");
    }
}

输出到日志(第3次运行后): -

03-23 21:34:10.164 1644-1644/so49457069bills.so49457069bills D/BILLDATA: Title=Bill1 Due Date=2018-10-02 Course=English
03-23 21:34:10.164 1644-1644/so49457069bills.so49457069bills D/BILLDATA: Title=Bill2 Due Date=2018-09-03 Course=Mathematics
03-23 21:34:10.164 1644-1644/so49457069bills.so49457069bills D/BILLDATA: Title=Bill3 Due Date=2018-11-04 Course=Geography
03-23 21:34:10.164 1644-1644/so49457069bills.so49457069bills D/BILLDATA: Title=Bill1 Due Date=2018-10-02 Course=English
03-23 21:34:10.164 1644-1644/so49457069bills.so49457069bills D/BILLDATA: Title=Bill2 Due Date=2018-09-03 Course=Mathematics
03-23 21:34:10.164 1644-1644/so49457069bills.so49457069bills D/BILLDATA: Title=Bill3 Due Date=2018-11-04 Course=Geography
03-23 21:34:10.164 1644-1644/so49457069bills.so49457069bills D/BILLDATA: Title=Bill1 Due Date=2018-10-02 Course=English
03-23 21:34:10.164 1644-1644/so49457069bills.so49457069bills D/BILLDATA: Title=Bill2 Due Date=2018-09-03 Course=Mathematics
03-23 21:34:10.164 1644-1644/so49457069bills.so49457069bills D/BILLDATA: Title=Bill3 Due Date=2018-11-04 Course=Geography

我强烈建议您在进行更改后卸载应用程序或在运行应用程序之前清除应用程序的数据。这将删除数据库,然后重新创建数据库,然后调用数据库帮助程序的onCreate方法