1. 程式人生 > >Java連接數據庫 #05# SQL與代碼分離

Java連接數據庫 #05# SQL與代碼分離

trac org imp package title fir ice public ret

索引

    1. 讀取html中的SQL語句
    2. 缺陷總結

在Java連接數據庫 #04#裏是大概是這樣放sql語句的:

package org.sample.shop.db.queryrunner;

import org.sample.shop.db.queryrunner.statementfactory.StatementFactory;

// TODO sql一長可讀性變得非常非常差
public interface Statements {

    String ITEM_SAVE_ITEM = "INSERT INTO item(user_id, name, price, status, quantity) VALUES (?, ?, ?, ?, ?)";
    String ITEM_REMOVE_BY_ID 
= "DELETE FROM item WHERE id=?"; String ITEM_UPDATE_BY_ID = "UPDATE item SET name=?, price=?, status=?, quantity=? WHERE id=?"; String ITEM_GET_BY_ID = "SELECT id, user_id AS userId, name, price, status, quantity FROM item WHERE id=?"; // order String ORDER_GET_BY_UID = "SELECT id, user_id AS userId, total FROM simple_order WHERE user_id=?"; String ORDER_SAVE_ORDER
= "INSERT INTO simple_order(user_id, total) VALUES(?, ?)"; String ORDER_SAVE_ORDER_DETAIL = "INSERT INTO order_detail(order_id, item_id, user_id, quantity, price, status) VALUES(?, ?, ?, ?, ?, ?)"; // order detail String ORDER_DETAIL_GET_BY_ORDER_ID = "SELECT id, order_id AS orderId, item_id AS itemId, user_id AS userId, quantity, price, status FROM order_detail WHERE order_id=?"; }

在簡單的程序裏這樣寫還是挺方便的,然而單條sql語句一旦變長可讀性就會變得非常非常差。改起來也相當不方便。

我首先想到的解決辦法是:像mybatis一樣把sql放到單獨一個XML文件裏。於是,我簡單寫了個草稿程序添加DOM4J依賴開始嘗試。結果當我把sql字符串放到xml標簽裏卻被提示格式不對,解析起來也報錯。。。。。。

然後仔細看看,mybatis能正常解析xml依靠的是這個↓

技術分享圖片

我只是想把sql單獨放到文件裏,並且我希望:

  • 方便閱讀和修改sql語句
  • 方便Java解析文件並讀取sql語句

為了節約學習成本,我腦洞一開。。。。就投機取巧地用html + jsoup做這件事了。

讀取html中的SQL語句

sql.html:

<sql id="ITEM_LIST_BY_UID_AND_STATUS">
    SELECT *
    FROM (
    SELECT rownum AS r, id, user_id AS userId, name, price, status, quantity
    FROM item
    WHERE user_id=? AND status=?
    )temp
    WHERE r >= ? AND r < ?
</sql>
<sql id="ITEM_SAVE_ITEM">
    INSERT INTO item(user_id, name, price, status, quantity)
    VALUES (?, ?, ?, ?, ?)
</sql>
<sql id="ITEM_REMOVE_BY_ID">
    DELETE FROM item
    WHERE id=?
</sql>
<sql id="ITEM_UPDATE_BY_ID">
    UPDATE item
    SET name=?, price=?, status=?, quantity=?
    WHERE id=?
</sql>
<sql id="ITEM_GET_BY_ID">
    SELECT id, user_id AS userId, name, price, status, quantity
    FROM item
    WHERE id=?
</sql>

/

StatementFactory.java:

package org.sample.shop.db.queryrunner.statementfactory;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;

import java.io.File;
import java.io.IOException;

public class StatementFactory {
    private static final String PATHNAME = StatementFactory.class.getResource("/sql.html").getPath();
    private static final String CHAR_SET = "UTF-8";

    private static Document doc;

    static {
        File input = new File(PATHNAME);
        try {
            doc = Jsoup.parse(input, CHAR_SET, "");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String getStatement(String statementId) {
        Element sql = doc.select(statementId).first();
        return sql.text();
    }
}

/

Statements.java(原來的Sql.java):

package org.sample.shop.db.queryrunner;

import org.sample.shop.db.queryrunner.statementfactory.StatementFactory;

public interface Statements {
    // item
    String ITEM_LIST_BY_UID_AND_STATUS = StatementFactory.getStatement("#ITEM_LIST_BY_UID_AND_STATUS");
    String ITEM_SAVE_ITEM = StatementFactory.getStatement("#ITEM_SAVE_ITEM");
    String ITEM_REMOVE_BY_ID = StatementFactory.getStatement("#ITEM_REMOVE_BY_ID");
    String ITEM_UPDATE_BY_ID = StatementFactory.getStatement("#ITEM_UPDATE_BY_ID");
    String ITEM_GET_BY_ID = StatementFactory.getStatement("#ITEM_GET_BY_ID");;
}

PS. interface中常量和類中靜態域性質是一樣的!!

缺陷總結

這樣做雖然解決了一些問題,但是改進空間還是相當大的。。。

例如說實際寫的時候需要來回在4個文件跳轉:

技術分享圖片

以及Statements.java和StatementFactory.java職能其實是重合的。。只是暫時沒去把它們寫到一起。

就。。有時間再搞吧。。。。。。。。。。。。。。。。

Java連接數據庫 #05# SQL與代碼分離