Spring JDBC 框架中, 綁定 SQL 參數的另一種選擇:具名參數(named parameter)

来源:http://www.cnblogs.com/wzqkalil/archive/2016/03/26/5322360.html
-Advertisement-
Play Games

使用spring的jdbcTemplate 使用具名參數 在JDBC用法中,SQL參數是用占位符?表示,並且受到位置的限制,定位參數的問題在於,一旦參數的位置發生變化,必須改變參數的綁定,在Spring JDBC中,綁定SQL參數的另一種選擇是使用具名參數,SQL具名參數是按照名稱綁定,而不是位置綁 ...


 

使用spring的jdbcTemplate-----使用具名參數

在JDBC用法中,SQL參數是用占位符?表示,並且受到位置的限制,定位參數的問題在於,一旦參數的位置發生變化,必須改變參數的綁定,在Spring JDBC中,綁定SQL參數的另一種選擇是使用具名參數,SQL具名參數是按照名稱綁定,而不是位置綁定。

 

什麼是具名參數?

具名參數: SQL 按名稱(以冒號開頭)而不是按位置進行指定. 具名參數更易於維護, 也提升了可讀性. 具名參數由框架類在運行時用占位符取代

具名參數只在 NamedParameterJdbcTemplate 中得到支持。(SImpleJdbcTemplate已過時了)

 NamedParameterJdbcTemplate內部包含了一個JdbcTemplate,所以JdbcTemplate能做的事情NamedParameterJdbcTemplate都能幹,NamedParameterJdbcTemplate相對於JdbcTemplate主要增加了參數可以命名的功能。 

 

如何配置?

applicationContext.xml里的配置

<!-- 配置jdbc模板類 -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
 
    <!-- 配置 NamedParameterJdbcTemplate,該對象可以使用具名參數。
    但它沒有無參構造器,所以必須為其制定構造參數,這裡指定的是出c3p0數據源
    -->
    <bean id="namedParameterJdbcTemplate"
        class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
        <constructor-arg ref="dataSource"></constructor-arg>
    </bean>

 

 

實例:

public class BaseService {

    // JdbcTemplate 對象作為構造器參數初始化
    @Autowired
    protected NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    /**
     * 數據查詢
     * 
     * @param sql
     * @param object
     * @return
     */
    @SuppressWarnings("rawtypes")
    public List<?> query(String sql, Object object) {

        // BeanPropertySqlParameterSource封裝了一個JavaBean對象,通過JavaBean對象屬性來決定命名參數的值
        SqlParameterSource source = new BeanPropertySqlParameterSource(object);

        @SuppressWarnings("unchecked")
        // BeanPropertyRowMapper自動將一行數據映射到指定類的實例中 它首先將這個類實例化,然後通過名稱匹配的方式,映射到屬性中去
        List<?> list = namedParameterJdbcTemplate.query(sql, source, new BeanPropertyRowMapper(object.getClass()));
        return list;
    }

    /**
     * 數據添加、刪除、修改
     * 
     * @param sql
     * @param object
     * @return
     */
    @SuppressWarnings("unchecked")
    public int excute(String sql, Object object) {
        if (object != null) {
            // 判斷類型
            if (object instanceof Map) {
                return namedParameterJdbcTemplate.update(sql, (Map<String, ?>) object);
            } else {
                BeanPropertySqlParameterSource source = new BeanPropertySqlParameterSource(object);
                // 返回對象
                return namedParameterJdbcTemplate.update(sql, source);
            }
        } else {
            return namedParameterJdbcTemplate.getJdbcOperations().update(sql);
        }
    }

    /**
     * 查詢記錄數
     * 
     * @param sql
     * @param object
     * @return
     */
    public int queryCount(String sql, Object object) {
        BeanPropertySqlParameterSource source = null;
        if (object != null) {
            source = new BeanPropertySqlParameterSource(object);
        }
        return namedParameterJdbcTemplate.queryForObject(sql, source, Integer.class);
    }
}

 

 

 NamedParameterJdbcTemplate類是基於JdbcTemplate類,並對它進行了封裝從而支持命名參數特性。

 

NamedParameterJdbcTemplate主要提供以下三類方法:execute方法、query及queryForXXX方法、update及batchUpdate方法。

 

1)NamedParameterJdbcTemplate初始化:可以使用DataSource或JdbcTemplate 對象作為構造器參數初始化;

2)insert into test(name) values(:name):其中“:name”就是命名參數;

3) update(insertSql, paramMap):其中paramMap是一個Map類型,包含鍵為“name”,值為“name5”的鍵值對,也就是為命名參數設值的數據;

4)query(selectSql, paramMap, new RowCallbackHandler()……):類似於JdbcTemplate中介紹的,唯一不同是需要傳入paramMap來為命名參數設值;

5)update(deleteSql, paramSource):類似於“update(insertSql, paramMap)”,但使用SqlParameterSource參數來為命名參數設值,此處使用MapSqlParameterSource實現,其就是簡單封裝java.util.Map。

 

NamedParameterJdbcTemplate類為命名參數設值有兩種方式:java.util.Map和SqlParameterSource:

1)java.util.Map:使用Map鍵數據來對於命名參數,而Map值數據用於設值;

2)SqlParameterSource:可以使用SqlParameterSource實現作為來實現為命名參數設值,預設有MapSqlParameterSource和BeanPropertySqlParameterSource實現;MapSqlParameterSource實現非常簡單,只是封裝了java.util.Map;而BeanPropertySqlParameterSource封裝了一個

JavaBean對象,通過JavaBean對象屬性來決定命名參數的值。

 

/**
 * 用戶 服務類介面實現
 */
@Service
public class IUserServiceImpl extends BaseService implements IUserService {

    public final static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(IUserServiceImpl.class);

    /**
     * 查詢用戶
     */
    @Override
    public Object queryUser(String sql, Object object) {
        User user = new User();
        sql = "select suser as username,spassword as password,tcreatetime as createtime,cisenabled as enabled,cauthorize as authorize from sys_user";
     
// String sqls = "select suser as username,spassword as password,tcreatetime as createtime,cisenabled as enabled,cauthorize as authorize from sys_user where suser like '%:username%'"; // 替換掉sql語句的條件 // sqls = sqls.replace(":username", user.getUsername()); @SuppressWarnings("unchecked") List<User> list = (List<User>) query(sql, user); return list; } /** * 添加用戶 */ @Override public MsgBean addUser(User user) { MsgBean msg = new MsgBean(); try { String sql = " insert into sys_user (suser,spassword,tcreatetime,cisenabled,cauthorize) values(:username,:password,:createtime,:enabled,:authorize)"; // 添加新用戶是自動取得時間 // user.setCreatetime(DateUtil.getCurDate(null)); excute(sql, user); msg.setFlag(true); msg.setText("ok"); } catch (Exception e) { logger.error("出錯的原因。。。" + e.getMessage()); } return msg; } /** * 修改用戶 */ @Override public MsgBean updateUser(User user) { MsgBean msg = new MsgBean(); try { String sql = " update sys_user set spassword=:password,tcreatetime=:createtime,cisenabled=:enabled,cauthorize=:authorize where suser=:username"; excute(sql, user); msg.setFlag(true); msg.setText("ok"); } catch (Exception e) { logger.error("出錯的原因。。。" + e.getMessage()); } return msg; } /** * 刪除用戶 */ @Override public MsgBean deleteUser(String username) { MsgBean msg = new MsgBean(); try { String sql = "delete from sys_user where suser =':username'"; if (username != null && username.length() != 0) { sql = sql.replace(":username", username); }else { msg.setFlag(false); msg.setText("未知原因,刪除失敗"); return msg; } excute(sql, null); msg.setFlag(true); msg.setText("ok"); } catch (Exception e) { logger.error("出錯的原因。。。" + e.getMessage()); } return msg; }
}

 

User是用戶實體類,MsgBean工具實體類裡面有flag和text兩個參數,又來輸出信息的 

 

/**
 * 用戶控制層
 */
@Controller
public class UserController {
    private static final Log logger = LogFactory.getLog(UserController.class);

    @Autowired
    private IUserService userService;

    /**
     * 用戶查詢
     * 
     * @param request
     * @param response
     * @return
     */
    @ResponseBody
    @RequestMapping("/queryuser")
    public Object queryUserList(HttpServletRequest request, HttpServletResponse response) {

        User user = new User();
        // 模糊查詢傳來的值
        // String username = request.getParameter("username");
        // // 判斷字元串是否為空
        // if (StringUtil.isBlank(username)) {
        // // 若為空替換為空字元串
        // username = "";
        // }
        // user.setUsername(username);

        Object obj = userService.queryUser(null, user);
        return obj;
    }

    /**
     * 用戶添加
     * 
     * @param user
     * @return
     */
    @ResponseBody
    @RequestMapping("/adduser")
    public MsgBean addUser(User user) {
        MsgBean msg = null;
        try {
            msg = userService.addUser(user);
        } catch (Exception e) {
            logger.error("出錯的原因 :" + e.getMessage());
        }
        return msg;

    }

    /**
     * 用戶修改
     * 
     * @param user
     * @return
     */
    @ResponseBody
    @RequestMapping("/updateuser")
    public MsgBean updateUser(User user) {
        MsgBean msg = null;
        try {
            msg = userService.updateUser(user);
        } catch (Exception e) {
            logger.error("出錯的原因 :" + e.getMessage());
        }
        return msg;
    }

    /**
     * 用戶刪除
     * 
     * @param username
     * @return
     */
    @ResponseBody
    @RequestMapping("/deleteuser")
    public MsgBean deleteUser(@RequestParam("username") String username) {
        MsgBean msg = null;
        try {
            msg = userService.deleteUser(username);
        } catch (Exception e) {
            logger.error("出錯的原因 :" + e.getMessage());
        }
        return msg;
    }
}

 

上述代碼寫好後,可以運行,因為沒有前端jsp文件,所以可以直接在訪問的網址後面加上?然後打上參數


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本系列目錄: 《1、搜索有聲小說》 《2、分析詳細頁地址》 《3、批量下載mp3》 本篇是大結局,看過前兩篇的放心吧,不會有第四篇了,軟體的下載地址,軟體完成的效果大家自己看吧。 一、查找mp3文件的下載地址 我們首先要獲取其下載地址,在評書的詳細頁中沒有找到,我們進入播放頁面,看看能找到什麼,如下 ...
  • 百度:ef5 mysql http://my.oschina.net/u/170703/blog/210814?p=1 百度:dotconnect for mysql 破解 可以找到極限軟體網站上的 dcmysql的破解版 {"創建 entityFramework 的配置節處理程式時出錯: 未能載入 ...
  • 本篇之所以起這樣一個名字,是因為重點並非如何自定義控制項,不涉及創建CustomControl和UserControl使用的Template和XAML概念。而是通過繼承的方法來擴展一個現有的類,在繼承的子類中增加屬性和擴展行為。 我們在《UWP開發入門(七)——下拉刷新》中提到過嵌套ScrollVie ...
  • 一、Git簡介 1.Git是什麼 Git是分散式版本控制系統 2.Git有什麼特點 (1)Git是分散式的SCM,SVN是集中式的 (2)Git每個歷史版本存儲完整的文件,SVN存儲文件差異 (3)Git可離線完成大部分操作,SVN則相反 (4)Git有著更優雅的分支和合併實現 (5)Git有著更強... ...
  • 學習如何在MVC項目中配置AutoMapper。 一:首先在MVC項目中引用AutoMapper的DLL文件,接著創建一個介面,這裡面我們需要定義兩個方法,介面裡面的方法只能定義不能實現,也沒有什麼修飾符,實現介面的類必須實現裡面全部的方法。 定義介面IStartupTask,裡面有兩個方法。 pu... ...
  • 一、開發環境 編譯器:VS2013 .Net版本:4.5 二、開發過程 1.畫一條直線 private void btnDrawLine_Click(object sender, EventArgs e) { //創建一個畫圖圖面 Graphics g = this.CreateGraphics()... ...
  • 由於項目升級到了.NetFramework 4.6.1,開發工具轉向了vs2015,趁機嘗試下C#6.0.結果在網上搜的一些教程總結的不是太完整,有的代碼隨著vs正式版的發佈也有所修改.那些個教程也沒更新.所以把自己學習到的記錄一下. 1.自動屬性初始化(Auto-property initiali ...
  • 生日悖論,指如果一個房間里有23個或23個以上的人,那麼至少有兩個人的生日相同的概率要大於50%,準確的說是50.7左右,這就意味著在一個典型的標準小學班級(30人)中,存在兩人生日相同的可能性更高。對於60或者更多的人,這種概率要大於99%。從引起邏輯矛盾的角度來說生日悖論並不是一種悖論,從這個數 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...