MyBatis学習のSQLクエリーパラメータおよび削除操作

13494 ワード

SQL文のパラメータの問題について
  • 従来のJDBCではSQLパラメータの入力には2種類あります.1つは、シリアルをスペルすることによって、sql注入が発生する可能性があります.つまり、ユーザーはor 1=1などのsql文を入力します.これにより、セキュリティの問題を引き起こし、毎回再コンパイルを行う効率が低くなります.もう1つは、プレースホルダを使用しますか.これはプリコンパイルされ、同じsqlを複数回実行しますが、パラメータが異なる場合は効率が高いです.jdbcコンパイルでは文字列しか認識されず、プレースホルダを介して?sql文を同じにすることができて、コンパイラは再びコンパイルしないで、直接実行して、sqlのスペルは、sqlが完全に同じ時だけコンパイルしないで、その他の時はすべてコンパイルする必要があって、だから効率は低いです.
  • MyBatisフレームワークにおけるSQLパラメータの入力にも2種類のスペルとプレースホルダがあり、フレームワークはsqlとプログラムコードを分離するため、パラメータプレースホルダの意味を直接確認できないため、フレームワークはプレースホルダ#{}と${}の代わりに特殊な記号を採用し、前者はパラメータに引用符を付け、後者はそのまま出力する.したがって、前者は条件クエリーのパラメータとして使用され、後者はSQL文に直接接続して実行されるため、パラメータを渡すときはプレースホルダの選択に注意しなければならない.a.1つのパラメータを渡す場合、パラメータ名は自由に書くことができ、MyBatisは直接値を取るb.複数のパラメータが必要な場合、入力されたパラメータが必要なパラメータより少ない場合、すべての値が完全に同じになる.この場合、パラメータ名は勝手に名前をつけることができるが、データが調べられず、間違いを報告しない.複数のパラメータを渡す場合はカスタムタイプで渡すことができます.sql文のパラメータはカスタムタイプの属性から値を取りますが、パラメータ名は属性の名前と同じでなければなりません.SQL実行時にはパラメータ名に基づいてオブジェクトのメソッドを反射呼び出し、同じ名前の属性が存在しない場合に異常が発生します.複数のパラメータをコレクションタイプ(Map)で渡すこともできます.sql文ではmapコレクションのkeyからパラメータ値が取得されます.したがって、パラメータの名前はmapのkeyと一致しなければなりません.mapに同じ名前のkeyが存在しない場合、パラメータは自動nullになり、同じようにデータが検索されません.各適用シーン:sqlに1つのパラメータしかない場合は基本タイプパラメータを使用し、sqlに複数のパラメータがあり、同じ意味を持つ場合はカスタムタイプパラメータを使用し、複数のパラメータ間に何の関係もない場合はmapを使用してパラメータを渡します.

  • 注意:テーブル名とカラム名、およびソートされたフィールドはプレースホルダを使用できません.テーブル名とソートされたフィールドはプレースホルダを使用するとエラーが報告されますが、カラム名がプレースホルダを使用してクエリーされた結果は正しくありません.プレースホルダは一般的に伝達条件であるため、where句で使用され、他の場合はスペル操作が必要です.この場合は特殊な符号で綴り操作を行う必要があり、すなわち${}というようにパラメータを伝達することで、パラメータはsql文の一部として実行され、すなわち綴り操作となるので、この場合はsql注入の問題に注意すべきであり、条件でパラメータを使用する場合はプレースホルダを採用しなければならず、他の場合は綴り文字を採用することができ、またユーザが入力するものであれば、3.ファジイクエリのパラメータフォーマットに関する質問:
    select * from t_user where username like '%admin%';

    adminは外部からパラメータを渡す必要があるため、パラメータのフォーマットの問題に注意する必要があります.以下のフォーマットで使用できます.
    select * from t_user where username like '%${username}%';

    ただし安全ではありません.条件の中でスペル操作を行ったので、プレースホルダを採用しなければなりません.バックグラウンドに%%を加えてパラメータを渡すことができます.
    select * from t_user where username like #{username};

    しかし不便で、Javaコードとsql文の結合性が高すぎて、それぞれ独立すべきで、この時異なるデータベースを通じて異なる方式を採用してsqlの文字列のつなぎ合わせ操作MySQL:concat(s 1,s 2,s 3.....)を実現することができます
    select * from t_user where username like concat('%',#{username},'%');

    OracleとDB 2:またはconcat(s 1,s 2,s 3....)によってつづります.
    select * from t_user where username like '%'||#{username}||'%';

    または
    SELECT * FROM t_user WHERE name like CONCAT('%',#{name},'%')  

    SQLServer:パス+パッチ
    SELECT * FROM t_user WHERE name like '%'+#{name}+'%'

    もう1つの方法はMyBatisが持っているbindラベルを使用することです.
    <select id="selectPersons" resultType="person" parameterType="person">  
          "pattern" value="'%' + _parameter.username + '%'" />  
          select id,sex,age,username,password from person where username LIKE #{pattern}  
    select>  

    4.MyBatisフレームワークの出力、つまりsqlの操作結果は、削除を増やしてデータベースに影響を与えるデータの数を返します.resultType:この属性はクエリー結果を指定したタイプのオブジェクトに変換することを表し、MyBatisフレームワークはsql向けなので、sqlとは関係なくクエリー結果を指定したタイプのオブジェクトに変換する場合、変換のルールに従ってクエリー結果フィールド名と指定したタイプの属性名を一致させ、一致に成功すると呼び出しを反射させる必要があります.マッチングが成功せず、何もしない場合、限界の場合、1つの属性がマッチングに成功しない場合、オブジェクトは作成されずnullが取得され、名前が一致しない場合も変換に成功したい場合は、名前を変更する必要があります.クエリーの結果は別名、as xxxxを使用し、クエリーの結果フィールドの名前を独立した構成で変更することもできます.次のようになります.
    <resultMap type="com.ecjtu.test.bean.User",id=userMap>
        <result column="ID" jdbcType="VARCHAR" property="id" />
        <result column="password" property="password"/>
    resultMap>
    <select id="selectUsers" resultMap="userMap">
        select * from t_user
    select>

    クエリーの結果を指定したタイプに変換:a.カスタムタイプ:(データの取得に関係がある場合に使用)クエリー結果フィールド名とカスタムタイプの属性名を1つ1つ対応b.クエリー結果をmapに変換(取得したデータ間に関係がない場合に使用)
    resultType="java.util.HashMap"

    クエリー結果フィールド名をkey、クエリー結果値をvalとしてキー値ペアを形成する形式c.基本データ型
    resultType="java.lang.String"

    クエリ結果の最初のフィールド値5.MyBatisに関するページングクエリの問題:a.論理ページングデータベース内のすべてのデータを一度にクエリし、キャッシュに配置し、指定したページ番号のデータを論理アルゴリズムで取得する.このページング方式を論理ページングと呼び、クエリの効率が速い(メモリ操作)しかし、初めてすべてのデータをクエリーするのは遅いかもしれません.データベースにどれだけのデータがあるか分からないため、データ量が大きいと遅くなり、多くのユーザーがまったく使えないデータをクエリーし、メモリを大量に消費し、サーバのパフォーマンスを低下させます.
    RowBounds rb = new RowBounds((pageNo-1)*pageSize,pageSize);
    session.selectList(sqlId,argObject,rowBounds);

    b.物理ページングはデータベース自体のページングメカニズムを採用してページングクエリー操作を実現し、物理ページングと呼ばれ、効率が低い(プロセス操作)が一般的に使用されている.この方法は私たちの業務ニーズに最も適しているからだ.結局、お客様はページをめくって欲しいデータを見たいだけで、すべてのページのデータmysql:limit 0(省略して書かない)をめくることはない.pagesize,limit startIndex,pagesize
    int pageno = 1;
    int pageSize = 5;
    int pageIndex = (pageno-1)*pageSize
    select * from t_user limit #{pageIndex},#{pageSize};

    oracle:3階層クエリーネスト+rowNum
    select * from t_user where rownum > 5 and rownum <= 10;

    Oracleではrownumが等しい以上の条件はサポートされていません
    select * from (
            select t.*, rownum as num from t_user where rownum <= 10
            )
    where num > 5

    またrownumはorder by文と一緒に使用できないため
    select * from (
            select t.*, rownum as num from(
                select * from t_user order by regdate
            )t
            where rownum <= 10)
    where num > 5

    注意:ネストされたクエリーは実は遅いので、必要に応じて選択することができます.最初のデータからソートされていないページングクエリーの場合、1つのレベルしか使用できません.ソートされていない場合は2つのレベルを使用します.3つのレベルのネストされたクエリー6.データベースの3つの用語:DDL:データベース定義言語、create drop DML:データベース操作言語、insert delete update、物事の提出とロールバックDQLに関連する:データベースクエリー言語、select削除変更操作のSQL:
    
    <insert id="addUser" parameterType="com.ecjtu.mybatis.entity.User" useGeneratedKeys="true" keyProperty="id">
        insert into user values(#{id},#{userName},#{userAge},#{userAddress})
    insert>
    
            update user set userName=#{userName},userAge=#{userAge},userAddress=#{userAddress} where id=#{id}
     
    <delete id="deleteUser" parameterType="int">
            delete from user where id=#{id}
    delete>

    テーブルのプライマリ・キーが自己成長している場合は、データを挿入した後、直ちに自己成長のプライマリ・キー値を取得する必要があります.また、MySqlの自己成長はintタイプに違いありません.自己成長のプライマリ・キーのフォーマットは次のとおりです.
    
        insert into tab_user (
        username,password
        )values(
            #{username},
            #{password},
        )
        "id" resultType="java.lant.Integer">
            select @@identity as id
        
    

    Oracle:自己成長タイプはintまたはString
    insert into tab_user(id) values(userseq.nextval)
    "id" resultType="java.lant.Integer">
            select userseq.currval from dual
    

    7.データベースに関する事物の伝統的なJDBC事物管理方式:
    try{
        conn.setAutoCommit(false);
    }catch{
        conn.rollback();
    }finally{
        conn.commit();
        conn.setAutoCommit(true);
    }

    MyBatisの下位レベルの事物管理方式:提出しないでfinally文のブロックの中でロールバックを行って、session.close()操作の中でロールバックの操作を含みました
    try{
        session.commit();
    }finally{
        session.close();
    }

    0.トランザクションの境界:Serviceレイヤ1.トランザクションの伝播動作:ネストされた複数のトランザクションの処理方法2.物事の独立性レベル:select*from t_user where id=1 for update、行レベルロック