使用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文件,所以可以直接在訪問的網址後面加上?然後打上參數