1

アカウント エンティティに注文のリストがあります。そのため、注文エンティティには親注文への外部キーがあります。親アカウントが最初に保存されるまで注文を保存できないようにする最善の方法は何ですか? アカウントなしでデータベースに注文が存在することは望ましくありません。よりよく説明するために、これが私の注文クラスです

@DatabaseTable
public class Order{

    private static final long serialVersionUID = 1L;

    @DatabaseField(id = true)
    private long id;

    @DatabaseField(foreign = true)
    private Account account;

}

ここに私の Account クラスがあります

@DatabaseTable
public class Account {
    private static final long serialVersionUID = 1L;

    @DatabaseField(id = true)
    private int id;

    @ForeignCollectionField
    private ForeignCollection<Order> orders;

    public ForeignCollection<Order> getOrders() {
        return orders;
    }

    public void setOrders(ForeignCollection<Order> orders) {
        this.orders = orders;
    }
}

問題は、アカウントが設定されていなくても注文を保存できることです。注文のアカウント フィールドに何らかの属性を設定して、これを防ぐ方法はありますか? 一部のコードを省略しましたが、各注文のアカウント フィールドを A1 に設定すると、特定のアカウント A1 の注文 Or1、Or2、Or3 を取得できるため、上記の関係が正常に機能していることはわかっています。

4

3 に答える 3

0

返信が遅くなり申し訳ありません。ここでいくつかのことを試してください。

あなたのaccountフィールドは、フィールドが割り当てられていることを確認するOrder必要があります。canBeNull = false

@DatabaseField(foreign = true, canBeNull = false)
private Account account;

Orderセットなしで挿入しようとすると、例外がスローAccountされます。ただし、データベースに挿入されていないaccountを含むファイルを設定できます。それを解決する方法は、フィールドを(プリミティブではなく)オブジェクトにすることです。そのため、まだ設定されていない場合はそうなります。AccountAccount.idIntegerintnull

// this is an Integer object so it is null if it has not been set
@DatabaseField(id = true)
private Integer id;

次に、Account.idフィールドが設定されていない場合、それを使用して を作成するOrderと、例外がスローされますAccount。ところで、おそらくあなたが望むように聞こえます@DatabaseField(generatedId = true)が、Integerフィールドはそのためにも機能します。

最後に、メソッドをオーバーライドして、フィールドが 0の場合、またはフィールドが0 の場合orderDao.create(...)に例外をスローすることもできます。Orderaccountnullaccount.id

// we have a custom DAO for this class
@DatabaseTable(daoClass = MyOrderDao.class)
public static class Order {
        ...
}

public static class MyOrderDao extends BaseDaoImpl<Order, Integer> {
    public MyOrderDao(ConnectionSource connectionSource) throws SQLException {
        super(connectionSource, Order.class);
    }

    @Override
    public int create(Order order) throws SQLException {
        if (order.account == null) {
            throw new SQLException("Order's account field is null");
        }
        if (order.account.id == 0) {
            throw new SQLException("Order's account field has a 0 id");
        }
        return super.create(order);
    }
}
于 2012-09-26T21:21:16.410 に答える
0

テスト データベース アプリケーションのソース コード全体を貼り付けます。これで問題が解決するはずです。

注文を行うための UI とサポートする xml ファイルを提供するアクティビティ クラスと、データベース操作を実行するための DbHandler クラスがあります。

これがアクティビティコードです。

package com.test;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.database.sqlite.SQLiteConstraintException;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class TestActivity extends Activity implements OnClickListener{

    private EditText accountId = null;
    private EditText orderNumber = null;
    private Button submit = null;

    private DBHandler dbHandler = null;


    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        setupUiElementProperties();
        dbHandler = new DBHandler(this);
    }


    private void setupUiElementProperties() {

        accountId = (EditText)findViewById(R.id.accountEditText);
        orderNumber = (EditText)findViewById(R.id.orderNoEditText);
        submit = (Button)findViewById(R.id.submit);
        submit.setOnClickListener(this);
    }


    public void onClick(View v) {

        try {

            dbHandler.placeOrder(Integer.parseInt(accountId.getText().toString().trim()), 
                    Integer.parseInt(orderNumber.getText().toString().trim()));

            showAlert("ORDER PLACED SUCCESSFULLY");
            System.out.println("DONE..");
        }catch (SQLiteConstraintException ex) {

            System.out.println("SQLITE EXCEPTIOn: " + ex.getMessage());

            showAlert("THIS ACCOUNT DOES NOT EXISTS");
        }catch (Exception e) {

            System.out.println("Exceptionn: " + e.getMessage());
        }
    }

    private void showAlert(String message) {

        new AlertDialog.Builder(TestActivity.this)
        .setTitle("Alert")
        .setMessage(message)
        .setPositiveButton("ok", new DialogInterface.OnClickListener(){
            public void onClick(DialogInterface dlg, int sumthin) {}
        })
        .show();
    }
}

これは、main.xml の xml コードです。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >


    <EditText
        android:id="@+id/accountEditText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_margin="10dp"
        android:layout_toRightOf="@+id/accountNoLabel" android:inputType="number">

        <requestFocus />
    </EditText>

    <TextView
        android:id="@+id/accountNoLabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/accountEditText"
        android:layout_alignBottom="@+id/accountEditText"
        android:layout_alignParentLeft="true"
        android:text="Account Id" android:layout_marginLeft="5dp"/>




    <EditText
        android:id="@+id/orderNoEditText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/accountEditText"
        android:layout_alignRight="@+id/accountEditText"
        android:layout_below="@+id/accountEditText" android:inputType="number"/>

    <TextView
        android:id="@+id/orderLabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/orderNoEditText"
        android:layout_alignBottom="@+id/orderNoEditText"
        android:layout_alignLeft="@+id/accountNoLabel"
        android:text="Order No" />

    <Button
        android:id="@+id/submit"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:text="Submit" />

</RelativeLayout>

そして最後に DbHandler クラス

package com.test;

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

public class DBHandler extends SQLiteOpenHelper {

    private SQLiteDatabase sqliteDatabaseInstance_ = null;

    public DBHandler(Context context){

        super(context, "TESTDATABASE.db", null, 1);
        sqliteDatabaseInstance_ = getWritableDatabase();
        sqliteDatabaseInstance_.execSQL("PRAGMA foreign_keys = ON;");
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        try {

            db.execSQL("CREATE TABLE ACCOUNT (accountId INTEGER PRIMARY KEY, name TEXT)");
            insertAccount(1234, "xyz", db);
            db.execSQL("CREATE TABLE ORDER_DETAILS (orderNo INTEGER, accountId INTEGER," +
                    "FOREIGN KEY (accountId) REFERENCES ACCOUNT(accountId))");
        }catch (SQLiteConstraintException sqliteConstraintException) {

            System.out.println("sqliteConstraintException: " + sqliteConstraintException.getMessage());
        }catch (Exception e) {

            System.out.println("Exception in DBHandler.onCreate: "+e.getMessage());
        }
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}

    public void placeOrder(int accountNo, int orderNo) throws SQLiteConstraintException{

        ContentValues cv = new ContentValues();
        cv.put("accountId", accountNo);
        cv.put("orderNo", orderNo);
        sqliteDatabaseInstance_.insertOrThrow("ORDER_DETAILS", null, cv);
    }


    private void insertAccount(int accId, String accountHolderName, SQLiteDatabase db) {

        ContentValues cv = new ContentValues();
        System.out.println("db: " + db);
        System.out.println("accountId: " + accId) ;
        System.out.println("accountHolderName: " + accountHolderName);
        cv.put("accountId", accId);
        cv.put("name", accountHolderName);
        db.insertOrThrow("ACCOUNT", null, cv);
    }
}

実際には、注文番号 (ORDER_DETAILS テーブル) を手動で追加する必要はありません。このフィールドは、自動インクリメントしてデータベースに入力する必要があります。

「アカウント」テーブルにはエントリがないため、DbHandler に insertAccount() を追加しました。この方法を使用して、アカウント ID「1234」のアカウントを追加しています。

これはあなたの出力でなければなりません:

シナリオ 1 口座番号: 1234 注文番号: 453412

アカウント ID 1234 が ACCOUNT テーブルに存在するため、このエントリがデータベースに挿入され、正常な更新のアラートが表示されます。

シナリオ 2 アカウント 2343 注文番号: 14523

外部キー制約が失敗するため、このエントリは受け入れられません。そのため、「THIS ACCOUNT DOES NOT EXIST」というアラートが表示されます。

私のデータベースはあなたが必要とするものと同じではないかもしれませんが、これがあなたを助けるのに十分であることを願っています.

SQLITEBROWSER を使用してデータを表示します。

ur db ファイルは以下にある必要があります........

ファイルエクスプローラに移動 -----> データ ------> データ ------> com.test -----> TESTDATA.db

于 2012-07-24T07:33:57.217 に答える
-1

@ user965895: あなたが ormlite にタグを付けたことを知りませんでした。私はそれについて何も知りません。私が提案したコードはSQLite用でした。Android には、利用できる軽量データベース SQLite が組み込まれています。

于 2012-07-24T09:55:00.457 に答える