首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Spring JDBC 具名參數實戰:NamedParameterJdbcTemplate 讓 SQL 綁定更優雅

     編輯:Java 綜合教學

為什麼要具名參數?

  • 傳統 ? 佔位符**強依賴位置**,SQL 調整順序需同步修改綁定代碼,維護成本高。
  • 具名參數(:name)**按名稱綁定**,順序無關,可讀性強,重構安全。

核心類:NamedParameterJdbcTemplate

  • 內部封裝 JdbcTemplate,繼承其所有能力,新增命名參數支持。
  • 構造器需傳入 DataSource 或 JdbcTemplate。

Spring 配置

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"/>
</bean>
<bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
    <constructor-arg ref="dataSource"/>
</bean>

參數綁定兩大方式

方式實現類適用場景
MapMapSqlParameterSource / 普通 Map動態參數、非實體類場景
JavaBeanBeanPropertySqlParameterSource實體類屬性直接映射參數名

BaseService 封裝範例

public class BaseService {
    @Autowired protected NamedParameterJdbcTemplate npjt;

    // 查詢列表:BeanPropertyRowMapper 自動映射列名→屬性名
    public List query(String sql, Object paramObj) {
        SqlParameterSource source = new BeanPropertySqlParameterSource(paramObj);
        return npjt.query(sql, source, new BeanPropertyRowMapper<>(paramObj.getClass()));
    }

    // 增刪改:支援 Map 或 Bean
    public int execute(String sql, Object paramObj) {
        if (paramObj == null) return npjt.getJdbcOperations().update(sql);
        if (paramObj instanceof Map) return npjt.update(sql, (Map) paramObj);
        return npjt.update(sql, new BeanPropertySqlParameterSource(paramObj));
    }

    // 查詢單值(如 count)
    public int queryCount(String sql, Object paramObj) {
        SqlParameterSource source = paramObj != null ? new BeanPropertySqlParameterSource(paramObj) : null;
        return npjt.queryForObject(sql, source, Integer.class);
    }
}

實體類與 Service 實現

public class User {
    private String username, password, authorize;
    private Date createtime;
    private Boolean enabled;
    // getter/setter
}

@Service
public class UserServiceImpl extends BaseService implements UserService {
    public List queryUsers() {
        String sql = "SELECT suser AS username, spassword AS password, tcreatetime AS createtime, cisenabled AS enabled, cauthorize AS authorize FROM sys_user";
        return (List) query(sql, new User());
    }

    public MsgBean addUser(User u) {
        String sql = "INSERT INTO sys_user(suser,spassword,tcreatetime,cisenabled,cauthorize) VALUES(:username,:password,:createtime,:enabled,:authorize)";
        return execute(sql, u) > 0 ? success() : fail();
    }

    public MsgBean updateUser(User u) {
        String sql = "UPDATE sys_user SET spassword=:password, tcreatetime=:createtime, cisenabled=:enabled, cauthorize=:authorize WHERE suser=:username";
        return execute(sql, u) > 0 ? success() : fail();
    }

    public MsgBean deleteUser(String username) {
        String sql = "DELETE FROM sys_user WHERE suser = :username";
        return execute(sql, Collections.singletonMap("username", username)) > 0 ? success() : fail();
    }
}

Controller 暴露 REST API

@RestController @RequestMapping("/user")
public class UserController {
    @Autowired UserService userService;
    @GetMapping("/list") public Object list() { return userService.queryUsers(); }
    @PostMapping("/add") public MsgBean add(@RequestBody User u) { return userService.addUser(u); }
    @PutMapping("/update") public MsgBean update(@RequestBody User u) { return userService.updateUser(u); }
    @DeleteMapping("/delete") public MsgBean delete(@RequestParam String username) { return userService.deleteUser(username); }
}

關鍵優勢總結

  1. SQL 可讀性大幅提升::username 直觀語義化。
  2. 參數順序解耦:調整 SQL 字段順序無需動 Java 代碼。
  3. 實體類屬性自動映射:BeanPropertySqlParameterSource 零樣板代碼。
  4. 兼容 Map 靈活場景:動態構建參數無需實體類。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved