AnnotatedSQL lib-Androidでの自動データベース生成

Android用のアプリケーションを開発するとき、回路を作成するスクリプトを手で書くことがよくあります。

これを1回行う必要がある場合はすべて問題ありませんが、アプリケーションの開発時には、多くの場合データベースを変更する必要があります。

そして、それが複数のクラスにまたがると、列の追加/削除、型の変更などを忘れた場所で問題が発生します。 また、「ヘルプ」をコピーして貼り付けます:列を追加しました-コンマを入力するのを忘れていました。



これらの問題を解決するために、このライブラリが発明されました。







AnnotatedSQLは、注釈データベースを作成するためのコードを生成するライブラリです。 注釈はruntimeではありませんが、コンパイル時にプリプロセッサによって処理されます。 したがって、プロジェクトと最終apkには影響しません。



実際には、libは2つの部分で構成されています:注釈付きのjarとプリプロセッサ。

プロジェクトのlibsフォルダーに注釈を配置します。

プリプロセッサの使用は、IDEとプロジェクトのビルド方法に依存します。



Eclipseを使用する場合は、プラグインをプラグインフォルダーにコピーし、必要に応じてEclipseを再起動します。 次に、 Javaコンパイラ->注釈処理プロジェクトの設定に移動し、そこでコードを生成するフォルダーを選択します。 明らかに、標準のgenフォルダーを配置する必要があります。 次に、 Factory Pathに移動してプラグインを選択します。 それだけです。



IDEAの場合、プラグインは収集しませんでした。



antで使用するために、クラスパスにプリプロセッサを追加するだけで、次のようにします。

ant clean release -cp ../com.annotatedsql.AnnotatedSQL_1.0.12.jar









使用する


さらに技術的なことに移りましょう。 だから私たちはライブラリを接続する方法を知っていますが、それは何をしますか?

既に述べたように、アノテーションからデータベースを生成するか、データベースを生成するためにクラスを作成します。

いつものように、コードで使用するために、プレートの名前をテーブルとその列のインターフェースとして説明します。



たとえば、スポーツ大会の結果に関するデータを表示するアプリケーションがあります。 今のところサッカーの試合に参加してください。

明らかに、データベースにはいくつかのタグが必要です。 これはチーム、結果、そしてチャンピオンシップです。それらについて説明します。

通常、1つのクラス内のすべてのインターフェイスについて説明します。たとえば、FStoreと呼びましょう。 タブレットの説明に加えて、データベースの名前、そのバージョン、およびいくつかのユーティリティメソッドが含まれています。



 public class FStore { public static final String DB_NAME = "fmanager"; public static final int DB_VERSION = 34; .......... public static interface TeamTable{ String TABLE_NAME = "team_table"; String ID = "_id"; String TITLE = "title"; String CHEMP_ID = "chemp_id"; String IS_FAV = "is_fav"; } public static interface ChempTable{ String TABLE_NAME = "chemp_table"; String CONTENT_PATH = "chemps"; String ID = "_id"; String TITLE = "title"; } public static interface ResultsTable{ String CONTENT_PATH = "results"; String PATH_VIEW = "results_view"; String TABLE_NAME = "result_table"; String ID = "_id"; String TEAM_ID = "team_id"; String POINTS = "points"; String CHEMP_ID = "chemp_id"; String GAMES = "games"; String WINS = "wins"; String TIE = "tie"; String LOSE = "lose"; String BALLS = "balls"; String GOALS = "goals"; } ........ }
      
      







CONTENT_PATHおよびあらゆる種類のPATH_VIEWに注意を払っていませんが。 これらは、コンテンツプロバイダーにアクセスするための定数です。

したがって、回路を作成するための手作業の量を示します。

さらに、読み取り可能な形式で結果を取得するには、プレートを相互に結合する必要があります。 これはコンテンツプロバイダーで行うことができますが、ここではViewを使用することを好みます。これは、書き込み用の別の大きなsqlピースです。



作業を容易にするために、このlibが作成されました。 それでは始めましょう。



スキーマ


FStore-注釈スキーマ( "SqlSchema")でマークし、コードを含むクラスの名前を設定します。 クラスは、FStoreが存在するのと同じパッケージで生成されます



 @Schema("SqlSchema") public class FStore {
      
      







テーブル、インデックス、PrimaryKey


ラベルの説明にはテーブル注釈が設定され、テーブル名が設定されます



 @Table(ChempTable.TABLE_NAME) public static interface ChempTable{ ................ @Table(TeamTable.TABLE_NAME) public static interface TeamTable{ ............... @Table(ResultsTable.TABLE_NAME) @Index(name = "chemp_index", columns = ResultsTable.CHEMP_ID) @PrimaryKey(collumns = {ResultsTable.TEAM_ID, ResultsTable.CHEMP_ID}) public static interface ResultsTable{
      
      







表にあるように、インデックスの作成と複雑なキーをハングさせることができます。 すべてが単純なようで、説明は必要ありません。



列、PrimaryKey、Autoincrement、NotNull


これらの注釈はフィールド用であり、使用するのも明らかです。



  @Table(TeamTable.TABLE_NAME) public static interface TeamTable{ String TABLE_NAME = "team_table"; @PrimaryKey @Column(type = Type.INTEGER) String ID = "_id"; @NotNull @Column(type = Type.TEXT) String TITLE = "title"; @Column(type = Type.INTEGER) @NotNull String CHEMP_ID = "chemp_id"; @Column(type = Type.INTEGER, defVal="0") String IS_FAV = "is_fav"; }
      
      







シンプルビュー


そして、システムの最後の、非常に重要な要素であり、さほど重要ではない要素はSimpleViewです。

シンプルなビューを作成するための基本的な機能を提供します。 内部結合はまだありますが、他のものを追加します。



  @SimpleView(ResultView.VIEW_NAME) public static interface ResultView{ String VIEW_NAME = "result_view"; @From(ResultsTable.TABLE_NAME) String TABLE_RESULT = "table_result"; @Join(srcTable = TeamTable.TABLE_NAME, srcColumn = TeamTable.ID, destTable = ResultView.TABLE_RESULT, destColumn = ResultsTable.TEAM_ID) String TABLE_TEAM = "table_team"; @Join(srcTable = ChempTable.TABLE_NAME, srcColumn = ChempTable.ID, destTable = ResultView.TABLE_RESULT, destColumn = ResultsTable.CHEMP_ID) String TABLE_CHEMP = "table_chemp"; }
      
      







ビュー内の注釈を検討してください。

From-これは私たちがするタブレットです:)重要-さらに、参加するときは、テーブル名ではなく、この定数を使用する必要があります。



結合 -実際には結合のテーブル。 私たちの場合、チームとチャンピオンシップのテーブルに参加する必要があります。



srcTableはソーステーブルです。

destTableは、ビューのfrom / joinテーブルの新しい名前です。 私たちの場合



 String TABLE_RESULT = "table_result";
      
      







別の非常に重要なポイント -ビューでは、フィールド名は次のパターンに従って生成されます。

<variable_name>_<column_name>







例外は、アダプタのカーソルを使用するFromテーブルの_idフィールドです。



したがって、列インデックスを見つけるには、次のようなものを使用する必要があります



 columnPoints = cursor.getColumnIndex(ResultView.TABLE_RESULT + "_" + ResultsTable.POINTS);
      
      





少し不快ですが、これは1回ごとに行われます

 public void changeCursor(Cursor cursor) {
      
      





あなたはまだそのようなヘルパーを使用することができます



 public class ColumnMappingHelper { private HashMap<String, HashMap<String, Integer>> indexes = new HashMap<String, HashMap<String, Integer>>(); public int getColumn(Cursor c, String table, String column){ HashMap<String, Integer> columns = indexes.get(table); if(columns != null){ Integer index = columns.get(column); if(index != null) return index; } if(columns == null){ columns = new HashMap<String, Integer>(); indexes.put(table, columns); } int index = c.getColumnIndex(table + "_" + column); columns.put(column, index); return index; } }
      
      







そしてそのように使用します



 mappingHelper.getColumn(cursor, ResultView.TABLE_RESULT, ResultsTable.POINTS);
      
      







結果




生成されたファイルSqlSchema.java



 public class SqlSchema{ private static final String SQL_CREATE_RESULT_TABLE = "create table result_table( balls INTEGER, chemp_id INTEGER NOT NULL, games INTEGER NOT NULL, goals INTEGER, _id INTEGER, lose INTEGER, points INTEGER NOT NULL, team_id INTEGER NOT NULL, tie INTEGER, wins INTEGER, PRIMARY KEY( team_id, chemp_id))"; private static final String SQL_CREATE_CHEMP_TABLE = "create table chemp_table( _id INTEGER PRIMARY KEY, title TEXT)"; private static final String SQL_CREATE_TEAM_TABLE = "create table team_table( chemp_id INTEGER NOT NULL, _id INTEGER PRIMARY KEY, is_fav INTEGER DEFAULT (0), title TEXT NOT NULL)"; private static final String SQL_CREATE_CHEMP_INDEX = "create index idx_chemp_index on result_table( chemp_id)"; private static final String SQL_CREATE_RESULT_VIEW = "CREATE VIEW result_view AS SELECT table_chemp._id as table_chemp__id, table_chemp.title as table_chemp_title, table_result.balls as table_result_balls, table_result.chemp_id as table_result_chemp_id, table_result.games as table_result_games, table_result.goals as table_result_goals, table_result._id, table_result.lose as table_result_lose, table_result.points as table_result_points, table_result.team_id as table_result_team_id, table_result.tie as table_result_tie, table_result.wins as table_result_wins, table_team.chemp_id as table_team_chemp_id, table_team._id as table_team__id, table_team.is_fav as table_team_is_fav, table_team.title as table_team_title FROM result_table AS table_result JOIN chemp_table AS table_chemp ON table_chemp._id = table_result.chemp_id JOIN team_table AS table_team ON table_team._id = table_result.team_id"; public static void onCreate(final SQLiteDatabase db) { db.execSQL(SQL_CREATE_RESULT_TABLE); db.execSQL(SQL_CREATE_CHEMP_TABLE); db.execSQL(SQL_CREATE_TEAM_TABLE); db.execSQL(SQL_CREATE_SCORE_TABLE); db.execSQL(SQL_CREATE_CHEMP_INDEX); db.execSQL(SQL_CREATE_RESULT_VIEW); db.execSQL(SQL_CREATE_SCORE_VIEW); } public static void onDrop(final SQLiteDatabase db){ db.execSQL("drop table if exists result_table"); db.execSQL("drop table if exists chemp_table"); db.execSQL("drop table if exists team_table"); db.execSQL("drop table if exists score_table"); db.execSQL("drop view if exists result_view"); db.execSQL("drop view if exists score_view"); } }
      
      



VIEWのresult_viewにtable_chemp_titleとしてtable_chemp__id、table_chemp.titleとしてAS SELECT table_chemp._idを、table_result_ballsなどtable_result.ballsは、table_result.games table_result_gamesとして、table_result.goals table_result_goalsとして、table_result、table_result_chemp_idとしてtable_result.chemp_id。 public class SqlSchema{ private static final String SQL_CREATE_RESULT_TABLE = "create table result_table( balls INTEGER, chemp_id INTEGER NOT NULL, games INTEGER NOT NULL, goals INTEGER, _id INTEGER, lose INTEGER, points INTEGER NOT NULL, team_id INTEGER NOT NULL, tie INTEGER, wins INTEGER, PRIMARY KEY( team_id, chemp_id))"; private static final String SQL_CREATE_CHEMP_TABLE = "create table chemp_table( _id INTEGER PRIMARY KEY, title TEXT)"; private static final String SQL_CREATE_TEAM_TABLE = "create table team_table( chemp_id INTEGER NOT NULL, _id INTEGER PRIMARY KEY, is_fav INTEGER DEFAULT (0), title TEXT NOT NULL)"; private static final String SQL_CREATE_CHEMP_INDEX = "create index idx_chemp_index on result_table( chemp_id)"; private static final String SQL_CREATE_RESULT_VIEW = "CREATE VIEW result_view AS SELECT table_chemp._id as table_chemp__id, table_chemp.title as table_chemp_title, table_result.balls as table_result_balls, table_result.chemp_id as table_result_chemp_id, table_result.games as table_result_games, table_result.goals as table_result_goals, table_result._id, table_result.lose as table_result_lose, table_result.points as table_result_points, table_result.team_id as table_result_team_id, table_result.tie as table_result_tie, table_result.wins as table_result_wins, table_team.chemp_id as table_team_chemp_id, table_team._id as table_team__id, table_team.is_fav as table_team_is_fav, table_team.title as table_team_title FROM result_table AS table_result JOIN chemp_table AS table_chemp ON table_chemp._id = table_result.chemp_id JOIN team_table AS table_team ON table_team._id = table_result.team_id"; public static void onCreate(final SQLiteDatabase db) { db.execSQL(SQL_CREATE_RESULT_TABLE); db.execSQL(SQL_CREATE_CHEMP_TABLE); db.execSQL(SQL_CREATE_TEAM_TABLE); db.execSQL(SQL_CREATE_SCORE_TABLE); db.execSQL(SQL_CREATE_CHEMP_INDEX); db.execSQL(SQL_CREATE_RESULT_VIEW); db.execSQL(SQL_CREATE_SCORE_VIEW); } public static void onDrop(final SQLiteDatabase db){ db.execSQL("drop table if exists result_table"); db.execSQL("drop table if exists chemp_table"); db.execSQL("drop table if exists team_table"); db.execSQL("drop table if exists score_table"); db.execSQL("drop view if exists result_view"); db.execSQL("drop view if exists score_view"); } }



、table_result_pointsは、table_team_chemp_idとしてtable_team.chemp_id、table_result.wins table_result_winsとして、table_result_tieとして、table_result_team_idとしてtable_result.tieをtable_result.team_id table_team_is_favとして、table_team__idとしてtable_team.is_favをtable_team._id public class SqlSchema{ private static final String SQL_CREATE_RESULT_TABLE = "create table result_table( balls INTEGER, chemp_id INTEGER NOT NULL, games INTEGER NOT NULL, goals INTEGER, _id INTEGER, lose INTEGER, points INTEGER NOT NULL, team_id INTEGER NOT NULL, tie INTEGER, wins INTEGER, PRIMARY KEY( team_id, chemp_id))"; private static final String SQL_CREATE_CHEMP_TABLE = "create table chemp_table( _id INTEGER PRIMARY KEY, title TEXT)"; private static final String SQL_CREATE_TEAM_TABLE = "create table team_table( chemp_id INTEGER NOT NULL, _id INTEGER PRIMARY KEY, is_fav INTEGER DEFAULT (0), title TEXT NOT NULL)"; private static final String SQL_CREATE_CHEMP_INDEX = "create index idx_chemp_index on result_table( chemp_id)"; private static final String SQL_CREATE_RESULT_VIEW = "CREATE VIEW result_view AS SELECT table_chemp._id as table_chemp__id, table_chemp.title as table_chemp_title, table_result.balls as table_result_balls, table_result.chemp_id as table_result_chemp_id, table_result.games as table_result_games, table_result.goals as table_result_goals, table_result._id, table_result.lose as table_result_lose, table_result.points as table_result_points, table_result.team_id as table_result_team_id, table_result.tie as table_result_tie, table_result.wins as table_result_wins, table_team.chemp_id as table_team_chemp_id, table_team._id as table_team__id, table_team.is_fav as table_team_is_fav, table_team.title as table_team_title FROM result_table AS table_result JOIN chemp_table AS table_chemp ON table_chemp._id = table_result.chemp_id JOIN team_table AS table_team ON table_team._id = table_result.team_id"; public static void onCreate(final SQLiteDatabase db) { db.execSQL(SQL_CREATE_RESULT_TABLE); db.execSQL(SQL_CREATE_CHEMP_TABLE); db.execSQL(SQL_CREATE_TEAM_TABLE); db.execSQL(SQL_CREATE_SCORE_TABLE); db.execSQL(SQL_CREATE_CHEMP_INDEX); db.execSQL(SQL_CREATE_RESULT_VIEW); db.execSQL(SQL_CREATE_SCORE_VIEW); } public static void onDrop(final SQLiteDatabase db){ db.execSQL("drop table if exists result_table"); db.execSQL("drop table if exists chemp_table"); db.execSQL("drop table if exists team_table"); db.execSQL("drop table if exists score_table"); db.execSQL("drop view if exists result_view"); db.execSQL("drop view if exists score_view"); } }







プレートの説明から定数を使用する必要はありません。 ファイルが生成され、テーブル宣言で記述した内容に明確に準拠します



SqlSchemaの使用




  private class AnnotationSql extends SQLiteOpenHelper { public AnnotationSql(Context context) { super(context, FStore.DB_NAME, null, FStore.DB_VERSION); } @Override public void onCreate(SQLiteDatabase db) { SqlSchema.onCreate(db); init(db); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { SqlSchema.onDrop(db); onCreate(db); } }
      
      







計画


1.さまざまな種類の結合を追加する

2.結合に注釈を追加して、必要なフィールドのみをレーキします



参照資料




バイナリ: github.com/hamsterksu/Android-AnnotatedSQL-binaries

ソース: github.com/hamsterksu/Android-AnnotatedSQL



ライセンス:MIT



みんなありがとう!



更新#1 :スキーマの更新について



私はOpenHelperを生成しません。自分で作成します。 複雑なロジックを書くことを誰も気にすることなく、生成されたスクリプトはonCreateで動作します

onUpgradeでは、フィールドの追加/削除/変更を非常に簡単に記述できます。テーブルとフィールドの名前があります。

図では、メンバーを開いてから、メンバーにアクセスし、テーブルを変更した後、ビューを再作成します。



All Articles