mybatis的單引號


要生成的sql:
作用是利用postgreGIS數據庫函數計算兩點(經緯度已知)的距離。

SELECT ST_Distance(
ST_Transform(ST_GeomFromText('POINT(-87.734087560562 43.770129071141)',4326),26986),
ST_Transform(ST_GeomFromText('POINT(-87.747382933006 43.759234252055)', 4326),26986)
);

最后成功的寫法:

    <select id="selectDistance" resultType="java.lang.String" parameterType="java.util.Map">
    SELECT ST_Distance(
            <if test="lot_lat != null" >
                ST_Transform(ST_GeomFromText(<![CDATA['POINT(${lot_lat})']]> ,4326),26986),
            </if>
            <if test="parkingPointStr != null">
                ST_Transform(ST_GeomFromText(<![CDATA['${parkingPointStr}']]>, 4326),26986))
            </if>
    </select>

${lot_lat}是字符串:-87.734087560562 43.770129071141
${parkingPointStr}是字符串POINT(-87.747382933006 43.759234252055)

注意1:單引號的轉義

方式a:如上使用<![CDATA[……]]>
方式b:使用xml的轉義字符:

    <select id="selectDistance" resultType="java.lang.String" parameterType="java.util.Map">
    SELECT ST_Distance(
            <if test="lot_lat != null" >
                ST_Transform(ST_GeomFromText(&apos; POINT(${lot_lat}) &apos;,4326),26986),
            </if>
            <if test="parkingPointStr != null">
                ST_Transform(ST_GeomFromText(&apos;${parkingPointStr} &apos;, 4326),26986))
            </if>
  </select>

方式c:concat拼接的方式。
剛開始想拼接一對單引號出來,不行:

   <select id="selectDistance" resultType="java.lang.String" parameterType="java.util.Map">
        SELECT ST_Distance(
        <if test="lot_lat != null" >
            ST_Transform(ST_GeomFromText(concat(E'\'','POINT(${lot_lat})',E'\'','),4326),26986),
        </if>
        <if test="parkingPointStr != null">
            ST_Transform(ST_GeomFromText(concat(E'\'','${parkingPointStr}',E'\'','), 4326),26986))
        </if>
    </select>

后來堅持不懈,發現是這么寫:

    <select id="selectDistance" resultType="java.lang.String" parameterType="java.util.Map">
        SELECT ST_Distance(
        <if test="lot_lat != null" >
            ST_Transform(ST_GeomFromText(concat('POINT(${lot_lat})'),4326),26986),
        </if>
        <if test="parkingPointStr != null">
            ST_Transform(ST_GeomFromText(concat('${parkingPointStr}'), 4326),26986))
        </if>
    </select>

這樣也行:

    <select id="selectDistance" resultType="java.lang.String" parameterType="java.util.Map">
        SELECT ST_Distance(
        <if test="lot_lat != null" >
            ST_Transform(ST_GeomFromText(concat('POINT(',#{lot_lat},')'),4326),26986),
        </if>
        <if test="parkingPointStr != null">
            ST_Transform(ST_GeomFromText(concat('${parkingPointStr}'), 4326),26986))
        </if>
    </select>

這樣也行:

    <select id="selectDistance" resultType="java.lang.String" parameterType="java.util.Map">
        SELECT ST_Distance(
        <if test="lot_lat != null" >
            ST_Transform(ST_GeomFromText(concat('POINT(',#{lot_lat},')'),4326),26986),
        </if>
        <if test="parkingPointStr != null">
            ST_Transform(ST_GeomFromText(concat(#{parkingPointStr}), 4326),26986))
        </if>
    </select>

concat函數解析后會自帶單引號?我之前為了加上單引號還這么寫呢:SELECT concat('''','POINT(116.289573 39.892352)','''')
SELECT concat('''','POINT(116.289573 39.892352)','''')
SELECT concat('POINT(-87.747382933006 43.759234252055)')
SELECT '''' || 'POINT(-87.747382933006 43.759234252055)' || ''''

這樣不行:

    <select id="selectDistance" resultType="java.lang.String" parameterType="java.util.Map">
        SELECT ST_Distance(
        <if test="lot_lat != null" >
            ST_Transform(ST_GeomFromText('\''POINT(${lot_lat}) '\'',4326),26986),
        </if>
        <if test="parkingPointStr != null">
            ST_Transform(ST_GeomFromText('\''${parkingPointStr} '\'', 4326),26986))
        </if>
    </select>

sqlSELECT concat('\'','ddd','\'') from t_parking也有語法錯誤,應該寫為SELECT concat(E'\'','ddd',E'\'') from t_parking,postgresql轉義放在E'\要轉義的內容'里。詳見

折騰半天,發現這樣寫,最簡單

String param = "POINT(" + longitude + " " + latitude + ")";
ST_GeomFromText(#{param},4326)

注意2:單引號為什么不能用雙引號取代

sql里單引號不能被雙引號取代着用。

注意3:${} 與 #{}的區別

前者是直接把字面值加在sql里,完全是字符串替換,當作占位符。常常用來傳遞表名,字段名,如order by ${param}
mybatis在處理#{}時,會將sql中的#{}替換為?號,調用PreparedStatement的set方法來賦值,有預編譯的機制。另外,傳入的數據都當成一個字符串,會對自動傳入的數據加一個雙引號。
后注入的參數將不會再進行SQL編譯。我們知道,SQL注入是發生在編譯的過程中,因為惡意注入了某些特殊字符,最后被編譯成了惡意的執行操作。而預編譯機制則可以很好的防止SQL注入。

注意4:mybatis里寫的一條sql里可以${} 與 #{}混着用嗎?

比如這條語句:

SELECT ST_Distance(ST_Transform(ST_GeomFromText('POINT(117.343454 40.8978999)',4326),26986),ST_Transform(ST_GeomFromText('POINT(116.289573 39.892352)', 4326),26986)) 
FROM  t_parking
WHERE id='0652b36f115c42578d13ffa45c4589c8'

寫成:

    <select id="selectDistance" resultType="java.lang.String" parameterType="java.util.Map">
    SELECT ST_Distance(
            <if test="lot_lat != null" >
                ST_Transform(ST_GeomFromText(<![CDATA['POINT(${lot_lat})']]> ,4326),26986),
            </if>
            <if test="parkingPointStr != null">
                ST_Transform(ST_GeomFromText(<![CDATA['${parkingPointStr}']]>, 4326),26986))
            </if>
    </select>
	FROM t_parking
        <where>
            <if test="id != null and id != ''">
                and id = #{id,jdbcType=VARCHAR}
            </if>
        </where>

可以嗎?
當然是可以的,但${}里不能帶,jdbcType=VARCHAR
寫這樣and id = ${id,jdbcType=VARCHAR}報錯:org.postgresql.util.PSQLException: 錯誤: 語法錯誤 在輸入的末尾\n 位置
寫這樣and id = '${id,jdbcType=VARCHAR}'報錯:內部錯誤。
寫這樣and id = '${id}'當然是正確的。
寫這樣and id = ${id}當然是有語法錯誤的。

另附postgis相關資料:
https://blog.csdn.net/qq_36588972/article/details/78902195
https://blog.csdn.net/zcc0618/article/details/72972188
https://blog.csdn.net/qq_36017609/article/details/85730172
https://www.cnblogs.com/kaituorensheng/p/4647901.html

CREATE database testgis;--新建一個庫
CREATE EXTENSION postgis;--給該庫啟用PostGIS(包括柵格),出現表spatial_ref_sys
CREATE EXTENSION postgis_topology;--啟用拓撲topology庫
select ST_GeomFromText('POINT(116.289573 39.892352)', 4326); --試用
st_astext(inf_comp_components_point.geom) --得到POINT(116.289573 39.892352)字符串

給表t_parking添加一個地理屬性字段geom,坐標系是4326(epsg4326,經緯度),2維
SELECT AddGeometryColumn ('t_parking', 'geom', 4326, 'POINT', 2)

update t_parking geom set geom = ST_GeomFromText('POINT(116.289573 39.892352)', 4326) where id='0652b36f115c42578d13ffa45c4589c8'
SELECT ST_ASTEXT(geom) geom FROM t_parking where id='0652b36f115c42578d13ffa45c4589c8'

select a1.attname as column_name,t.typname as data_type,d.description as column_comment
from (select a.attname,a.attrelid,a.atttypid,a.attnum from pg_attribute a,pg_class c where c.relname = 't_parking' and a.attnum>0 and a.attrelid=c.oid)a1 left join pg_type t on a1.atttypid=t.oid left join pg_description d on d.objoid=a1.attrelid and d.objsubid=a1.attnum;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM