手を取ってjavaのormを書くように教えてあげます(完)

7402 ワード

sqlの生成:select
前回はどのように1つのsqlの中でwhereの一部を生成するかを話して、それから私达は事をするのがとても简単で、最初のように各种のsql文を生成すればいいだけで、それから私达の必要な条件を加えるだけで、1つの完全なsqlは顺调にできました.
クエリー文を生成するsqlを書き始めます.クエリ文は大体次のようになります.
SELECT name, id, create_date, age, mark, status FROM user

ここでは,基本的なクエリ文は基本的にSELECTの後にクエリが必要なフィールドを加え,FROMとクエリするテーブル名に追随すればよいことがわかる.せいぜい后ろにORDER BY/GROUP BY/LIMITを付けておく必要があるかもしれませんが....なんて简単なのでここには书きません.(複雑すぎてsqlを直接書けばいいので、自分では必要ありません)
構想
  • は、以前に取得したマッピング関係から属性とフィールド名のマッピングを取得し、sqlを接続する.
  • はsqlを実行し、結果を取り出す.
  • はclassをインスタンス化し、classに反射された属性を使用して値を割り当てます.

  • このいくつかのステップはやはりやりやすいので、最初のステップは簡単で、前に書いたものを真似すればいいです.ここでsqlを実行するとき、私はJdbcTemplateを使っています.ここには大きな穴があります.次は私が言います.
    大小さまざまな穴.
    この穴は私が書いたこのプロジェクトを使って会社にレポートを作ったときに出会ったのです.なぜなら、データベースにはdatetimeタイプのフィールドがあるため、このフィールドはテーブルの値が0000-00-00 00:00である場合があります(この値がどのように入ったのか分かりませんが、存在/(ㄒoㄒ)/~~~)が、javaのDateタイプに変換できません.だからここは間違っています.
    SpringJdbcのColumnMapRowMapperを継承するクラスをここに書きました.
    import org.springframework.jdbc.core.ColumnMapRowMapper;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    /**
     *        
     *
     * @author hjx
     */
    public class PlusColumnMapRowMapper extends ColumnMapRowMapper {
    
        /**
         *          ,      0000-00-00 00:00:00
         *    ,       ,  null
         *
         * @param rs
         * @param index
         * @return
         * @throws SQLException
         */
        @Override
        protected Object getColumnValue(ResultSet rs, int index) throws SQLException {
            Object columnValue = null;
            try {
                columnValue = super.getColumnValue(rs, index);
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return columnValue;
    
        }
    }

    このクラスは具体的にどこで使われているのか、以下に説明します.
    インプリメンテーション
    今、上の考えをどう実現するかというと、まず最初のステップが簡単なので、書かないでください.私は直接第2歩から始めます.
  • はsqlを実行し、結果を取り出す.ここで私が使っているのはJdbcTemplateの方法で、これは私たちに1つの方法を提供しました:
     List query(String sql, Object[] args, RowMapper rowMapper)
    ここの前の2つのパラメータは比較的に理解しやすくて、1つはsqlで、1つはsqlの中のパラメータです.3つ目は、インタフェースRowMapperを伝える必要があります.このインタフェースは具体的に何をしているのかをインターネットで調べるとわかります~~この中には、
    T mapRow(ResultSet rs, int rowNum) throws SQLException
    の最初のパラメータはクエリーの結果で、2つ目は今何行目の結果で、戻り値はあなたが何を返すのかという方法があります.ここでは、この方法を書き直し、クエリの結果を必要なオブジェクトに変換する必要があります.
    /**
     *                 
     *
     * @param resultSet
     * @param rowNum
     * @return
     * @throws SQLException
     */
    @Override
    public T mapRow(ResultSet resultSet, int rowNum) throws SQLException {
        Map resultMap = columnMapRowMapper.mapRow(resultSet, rowNum);
       。。。。
    と書くことができます.この方法のcolumnMapRowMapperは、クエリー結果のrowNumを取り出し、結果をMapに変換する役割を果たしています.そのうち:key:はテーブルフィールド名です.Object:このフィールドの値.上記のPlusColumnMapRowMapperの主な役割は、値を取得するときに異常が発生した場合、nullを返すことです.このステップではsqlを実行する結果を得ました.今、結果を必要なclassに変換します.
  • 結果をclassに変換前に結果を格納するMapを手に入れました.mapを遍歴してjavaオブジェクトをインスタンス化し、フィールドと属性のマッピング関係に基づいて反射を使用して属性を1つずつsetすればいいだけです.前のステップの完全なコードを貼り付けます:
    public T mapRow(ResultSet resultSet, int rowNum) throws SQLException {
        Map resultMap = columnMapRowMapper.mapRow(resultSet, rowNum);
        T instance = getInstance(tableClass);
        for (Map.Entry entry : resultMap.entrySet()) {
            //      
            String key = entry.getKey();
            if (!columnFieldMapper.containsKey(key)) {
                continue;
            }
            Field declaredField = columnFieldMapper.get(key);
            if (declaredField == null) {
                continue;
            }
            //      
            Object value = entry.getValue();
            setFieldValue(instance, declaredField, value);
        }
        return instance;
    }
    columnFieldMapperはMapです.keyはテーブルのフィールド名です.valueは対応するclassのプロパティです.次にsetFieldValueの具体的なコードを示します.
    boolean setFieldValue(T t, Field field, Object value) {
        field.setAccessible(true);
        try {
            if (value != null) {
                field.set(t, value);
                return true;
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return false;
    }
    では、クエリーの結果をマッピング関係に基づいて必要なclassに変換できます.

  • その他
    クエリーに条件を追加する必要がある場合は、前述した生成条件のツールを使用して条件のsqlをここのsqlの後ろにつなぎ、それに応じてwhereのパラメータも順番に配列に追加すればよい.
    同様に、ORDER BY/GROUP BY/LIMITを追加する場合も同様です.主に自分のコードがどのように設計されているかを見なければなりません.自分で使っているのはORDER BYとLIMITだけです.私のgithubで見つけることができます.住所はこちらです.https://github.com/hjx601496320/JdbcPlus .
    生成sql:delete
    構想
    えっ、これは簡単すぎます.书かないよ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    私が前に書いたものを参照して、分析して、考えて、それから一歩一歩どうすればいいか、少しずつ書きました.
    ~~~
    インプリメンテーション
    君は自分で書くよ~~~.
    その他
    この一編は本当に速いですね~~
    sqlの生成:update
    最後の部分は、すぐに書き終わりました.書くのは本当に疲れるわ~~~~
    構想
    更新された文もやりやすいですが、sqlの後ろの条件は前にwhereという文章を書いたので、ここではsqlのwhereの左側の一部だけを書きます.まずupdate文を分析します.
    UPDATE user SET name = ? , id = ? , create_date = ? , age = ? , status = ? WHERE id = ?

    一般的にUPDATEテーブル名SETフィールド名=?こんな感じです.(今はWHERE右のを書かないので)
    具体的な考え方は
  • マッピング関係に基づいてsqlをアセンブリします.ここで選択できる場所は、ある属性の値がnullである場合、この属性をnullに更新するかどうかです.
  • 更新する値を取得します.
  • はsqlを実行する.

  • インプリメンテーション
  • マッピングからすべてのプロパティを取得します.このステップのコードは~~を入れず、前に書いたものと何の違いもありません.
  • は、更新する属性名と値を取得します.ここでは、更新時に値がnullの属性であることを無視する必要があるかどうかを示す3つのパラメータが必要です.boolean ignoreNull 2:更新するフィールドの順序付けされたセットを保存します.List updataColumn 3:更新するフィールドの値の順序付き集合を保存します.List valuesコードは、
    List columnNames = new ArrayList<>(entityTableRowMapper.getColumnNames());
    Map columnFieldMapper = entityTableRowMapper.getColumnFieldMapper();
    List values = new ArrayList<>();
    for (int i = 0; i < columnNames.size(); i++) {
        String columnName = columnNames.get(i);
        if (!sqlColumns.contains(columnName)) {
            continue;
        }
        Field field = columnFieldMapper.get(columnName);
        Object value = EntityUtils.getValue(entity, field);
        //  class    null,      null,  
        if (ignoreNull && value == null) {
            continue;
        }
        updataColumn.add(columnName);
        values.add(value);
    }
  • 受け取ったデータに基づいてsqlを組み立てて上に必要なデータを手に入れた後、テーブルの名前を手に入れる必要があります.このステップはマッピング関係から直接取ればいいです.次はsqlをパッチワークするコード:
    StringBuilder sql = new StringBuilder();
    sql.append("UPDATE ").append(getTableName()).append(StringUtils.SPACE);
    sql.append("SET ");
    for (int i = 0; i < updataColumn.size(); i++) {
        String column = updataColumn.get(i);
        if (i == 0) {
            sql.append(StringUtils.append(column, " = ? "));
        } else {
            sql.append(StringUtils.append(", ", column, " = ? "));
        }
    }
    これでいいのですが、大体このような:
    UPDATE user SET name = ? , id = ? , create_date = ? , age = ? , status = ? 
    条件なら、前に書いたwhereで生成すればいいのですが、whereの値は集合valuesの後ろに加えればいいのです.
  • はsqlを実行する.簡単すぎて書けない~
  • 最後に
    やっと書き終わった.
    やはり,コードはgithub上にあるので,すべてのコードを上に書かず,主に説明構想を主とする.また、ブログを書き始めたばかりで、よく分からないことがあるかもしれません.文化のない損をしたな~~~~
    このプロジェクトには、複雑なクエリーや関数の実行など、まだ実現されていない機能がたくさんあります.私はそれを書いていません.一つは必要ありません.これは普段は主にレポートをエクスポートするときに使うので、二つ目は自分でプロジェクトを書くとこれらのものは全然使いません.javaで書ける私はjavaで書きました.データベースは、私にとってデータを保存すればいいので、データ処理のことはjavaに任せてください.
    しまった
    posted @
    2019-01-28 14:11  何がむだに読むのか(
    ...)コメント(
    ...)コレクションの編集
    コメントを更新ページを更新して上部に戻る
    Copyright © 2019何白
    Powered by .NET Core 3.0.0-preview9-19423-09 on Linux