Spring JDBC是Spring所提供的持久層技術(shù),它以一種更直接、更簡(jiǎn)單的方式使用JDBC API。在Spring JDBC里,用戶僅需要做那些必不可殺的事兒,而將資源獲取、Statement創(chuàng)建、異常處理、資源釋放等繁雜的工作交給Spring。
創(chuàng)新互聯(lián)主營(yíng)上虞網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,app軟件開(kāi)發(fā)公司,上虞h5成都小程序開(kāi)發(fā)搭建,上虞網(wǎng)站營(yíng)銷(xiāo)推廣歡迎上虞等地區(qū)企業(yè)咨詢
雖然ORM的框架已經(jīng)很成熟,但是JDBC靈活直接的特性依舊讓它有自己的用武之地。
本節(jié)的主要內(nèi)容:使用JdbcTemplate模板類(lèi)進(jìn)行CRUD數(shù)據(jù)操作、BLOB和CLOB類(lèi)型數(shù)據(jù)的操作,支持命名參數(shù)綁定NamedParameterJdbcTemplate模擬類(lèi)的使用。
1.在DAO中使用JdbcTemplate
一般情況下,在XML中配置好JdbcTemplate,然后在DAO中注入即可
Spring配置文件中定義的JdbcTemplate并注入DAO中
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <!-- 注解掃描包 --> <context:component-scan base-package="com.online"/> <context:property-placeholder location="classpath:/jdbc.properties"/> <!-- 配置數(shù)據(jù)源信息 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${dataSource.driverClassName}"/> <property name="url" value="${dataSource.url}"/> <property name="username" value="${dataSource.username}"></property> <property name="password" value="${dataSource.password}"></property> </bean> <!-- 定義JDBC模板Bean --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> </beans>
//@Repository聲明一個(gè)DAO @Repository public class AdminDao implements IAdminDao { private static Logger logger=Logger.getLogger(AdminDao.class); private static final long serialVersionUID = 1L; //@Autowired注入JdbcTemplate實(shí)例聲明一個(gè)DAO @Autowired private JdbcTemplate jdbcTemplate; @Override public Admin getAdminByNamAndPassword(String adminId, String password) { // TODO Auto-generated method stub String sql="select adminId,adminName,adminPassword,adminHead,MAX(FROM_UNIXTIME(lastvisittime,'%Y-%m-%d %H:%m:%S')),lastvisitip from zzia_admin left join zzia_login_log on adminId=userId " + "where adminName='"+adminId+"' and adminPassword='"+password+"' "; final Admin a=new Admin(); this.jdbcTemplate.query(sql, new RowCallbackHandler() { @Override public void proce***ow(ResultSet rs) throws SQLException { // TODO Auto-generated method stub a.setAdminId(rs.getInt(1)); a.setAdminName(rs.getString(2)); a.setAdminPassword(rs.getString(3)); a.setAdminHead(rs.getString(4)); a.setLastVisitTime(rs.getString(5)); a.setLastVisitIp(rs.getString(6)); } }); return a; }
2.基本的數(shù)據(jù)操作
數(shù)據(jù)的增刪查改以及存儲(chǔ)過(guò)程調(diào)用是最基本的數(shù)據(jù)庫(kù)操作,JdbcTemplate提供了眾多的方法,通過(guò)JdbcTemplate用戶可以用簡(jiǎn)單的方法完成這些數(shù)據(jù)操作
2.1更改數(shù)據(jù)
JdbcTemplate提供了若干update()方法,允許用戶對(duì)數(shù)據(jù)表記錄進(jìn)行更改和刪除操作
update示例:
public class TestJdbcTemplate { ...//這里省略jdbcTemplate的定義 private static final String sql = "insert into jf_user(user_name,user_pwd,user_age) values(?,?,?)"; public static void addUser(User user) { Object[] params = new Object[]{user.getUsername(),user.getUserpwd(),user.getUserage()}; int update = jdbcTemplate.update(sql, params); if(update > 0){ System.out.println("插入成功"); } } }
2.2、返回?cái)?shù)據(jù)庫(kù)的表自增主鍵值
用戶經(jīng)常使用數(shù)據(jù)的子增字段作為表主鍵,即主鍵值不在應(yīng)用層產(chǎn)生,而是在新增記錄時(shí),由數(shù)據(jù)庫(kù)產(chǎn)生。這樣,應(yīng)用層在保存對(duì)象前并不知道對(duì)象主鍵值,而只有在保存數(shù)據(jù)后才能從數(shù)據(jù)庫(kù)中返回主鍵值。在很多情況下,需要獲取新對(duì)象持久化后的主鍵值。在Hibernate、JPA等ORM框架中,新對(duì)象在持久化后,主鍵值會(huì)自動(dòng)綁定到對(duì)象上,給程序的開(kāi)發(fā)帶來(lái)了很多方便。
Spring提供了一個(gè)可以返回新增記錄對(duì)應(yīng)主鍵值的方法。int update(PreparedStatementCreator psc,KeyHolder generatedKeyHolder);org.springframework.jdbc.support.KeyHolder是一個(gè)回調(diào)接口,spring使用它保存新增記錄對(duì)應(yīng)的主鍵。Spring為KeyHolder接口指代了一個(gè)通用的實(shí)現(xiàn)類(lèi)GeneratedKeyHolder,該類(lèi)返回新增記錄時(shí)的自增長(zhǎng)主鍵值。假設(shè)希望在新增對(duì)象后,將主鍵值加載到對(duì)象中,則代碼示例
public static void addUserWithKeyHolder(final User user){ final String sql = "insert into jf_user(user_name,user_pwd,user_age) values(?,?,?)"; KeyHolder keyHolder = new GeneratedKeyHolder(); jdbcTemplate.update(new PreparedStatementCreator() { @Override public PreparedStatement createPreparedStatement(Connection con) throws SQLException { PreparedStatement ps = con.prepareStatement(sql); ps.setString(1, user.getUsername()); ps.setString(2, user.getUserpwd()); ps.setString(3, user.getUserage()); return ps; } }, keyHolder); user.setSerialNo(keyHolder.getKey().intValue()); }
如果數(shù)據(jù)庫(kù)并發(fā)率比較高,如在插入記錄后執(zhí)行查詢主鍵之前,數(shù)據(jù)庫(kù)又執(zhí)行了如果條插入記錄,那么通過(guò)數(shù)據(jù)查詢語(yǔ)句新增主鍵值將會(huì)只返回最后一條插入的主鍵值。因此,使用查詢語(yǔ)句獲取的主鍵值是不安全的,這也是為什么有些數(shù)據(jù)庫(kù)(如Oracle)故意不提供自增鍵,而是只提供序列的原因,序列強(qiáng)制要求用戶在新增記錄前,先獲取主鍵值。Oracle通過(guò)SELECT <SEQUENCE_NAME>.nextval FROM DUAL獲取序列的下一個(gè)值。
2.3、批量更改數(shù)據(jù)
如果需要一次性插入或更新多條記錄,可以使用jdbcTemplate的batchUpdate方法
batchUpdate示例:
public static void addUsers(final List<User> users){ final String sql = "insert into jf_user(user_name,user_pwd,user_age) values(?,?,?)"; jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() { @Override public void setValues(PreparedStatement ps, int i) throws SQLException { // TODO Auto-generated method stub User user = users.get(i); ps.setString(1, user.getUsername()); ps.setString(2, user.getUserpwd()); ps.setString(3, user.getUserage()); } @Override public int getBatchSize() { // TODO Auto-generated method stub return users.size(); } }); }
2.4、查詢數(shù)據(jù)
2.4.1、使用RowCallbackHandler處理結(jié)果集
Spring提供了org.springframework.jdbc.core.RowCallbackHandler回調(diào)接口,通過(guò)該接口可以定義如何從結(jié)果集中獲取數(shù)據(jù)。
RowCallbackHandler示例:
/** * @Title: getUserBySerialNo * @Description: TODO 獲取單個(gè)結(jié)果集 * @param @param serialNo * @param @return 設(shè)定文件 * @return User 返回類(lèi)型 * @throws */ public User getUserBySerialNo(final int serialNo){ String sql = "SELECT serial_no,user_name,user_pwd,user_age FROM jf_user.jf_users WHERE serial_no = ?"; final User user = new User(); jdbcTemplate.query(sql, new Object[]{serialNo},new RowCallbackHandler() { @Override public void proce***ow(ResultSet rs) throws SQLException { user.setSerialNo(serialNo); user.setUsername(rs.getString("user_name")); user.setUserpwd(rs.getString("user_pwd")); user.setUserage(rs.getString("user_age")); } }); return user; } /** * @Title: getUsers * @Description: TODO 獲取多個(gè)結(jié)果集 * @param @param fromSerialNo * @param @param toSerialNo * @param @return 設(shè)定文件 * @return List<User> 返回類(lèi)型 * @throws */ public List<User> getUsers(final int fromSerialNo,final int toSerialNo){ String sql = "SELECT serial_no,user_name,user_pwd,user_age FROM jf_user.jf_users WHERE serial_no between ? and ?"; final List<User> users = new ArrayList<>(); jdbcTemplate.query(sql, new Object[]{fromSerialNo,toSerialNo}, new RowCallbackHandler() { @Override public void proce***ow(ResultSet rs) throws SQLException { // TODO Auto-generated method stub User user = new User(); user.setSerialNo(rs.getInt("serial_no")); user.setUsername(rs.getString("user_name")); user.setUserpwd(rs.getString("user_pwd")); user.setUserage(rs.getString("user_age")); users.add(user); } }); return users; }
2.4.2、使用RowMapper<T>處理結(jié)果集
Spring也提供了一個(gè)和RowCallbackHandler功能類(lèi)似的RowMapper<T>接口,它也可以使用RowMapper<T>定義結(jié)果集邏輯映射,在結(jié)果集為多行記錄時(shí),該接口更容易使用。
RowMapper<T>代碼示例
/** * @Title: getUsersOnRowMapper * @Description: TODO 利用RowMapper<T>映射多行數(shù)據(jù) * @param @param fromSerialNo * @param @param toSerialNo * @param @return 設(shè)定文件 * @return List<User> 返回類(lèi)型 * @throws */ public List<User> getUsersOnRowMapper(final int fromSerialNo,final int toSerialNo){ String sql = "SELECT serial_no,user_name,user_pwd,user_age FROM jf_user.jf_users WHERE serial_no between ? and ?"; return jdbcTemplate.query(sql, new Object[]{fromSerialNo,toSerialNo},new RowMapper<User>(){ @Override public User mapRow(ResultSet rs, int rowNum) throws SQLException { // TODO Auto-generated method stub User user = new User(); user.setSerialNo(rs.getInt("serial_no")); user.setUsername(rs.getString("user_name")); user.setUserpwd(rs.getString("user_pwd")); user.setUserage(rs.getString("user_age")); return user; } }); }
2.5、查詢單值數(shù)據(jù)
如果查詢的結(jié)果集僅有一個(gè)值,如SELECT COUNT(*) FROM jf_users等,就可以使用更簡(jiǎn)單的方式獲取結(jié)果的值。JdbcTemplate為獲取結(jié)果集中的單值數(shù)據(jù)提供了3組方法,分別用于獲取int、long的單值,其他類(lèi)型的單值以O(shè)bject類(lèi)型返回
2.6、調(diào)用存儲(chǔ)過(guò)程
JdbcTemplate提供了2個(gè)調(diào)用存儲(chǔ)過(guò)程的接口方法:
<T> T execute(String callString,CallableStatementCallback<T> action);
<T> T execute(CallableStatementCreator csc,CallableStatementCallback<T> cs);
調(diào)用存儲(chǔ)過(guò)程示例:
CREATE PROCEDURE P_GET_VIEW_POINT_NUM(IN in_serialNO,INT,OUT out_num INT) BEGIN SELECT COUNT(*) INTO out_num FROM jf_user WHERE serialNO = in_serialNo; END;
/** * @Title: getUserCounts * @Description: TODO JdbcTemplate調(diào)用存儲(chǔ)過(guò)程 * @param @param serailNo * @param @return 設(shè)定文件 * @return int 返回類(lèi)型 * @throws */ public int getUserCounts(final int serailNo){ String sql = "{call P_GET_VIEW_POINT_NUM(?,?)}"; String execute = jdbcTemplate.execute(sql, new CallableStatementCallback() { @Override public Object doInCallableStatement(final CallableStatement cs) throws SQLException, DataAccessException { // TODO Auto-generated method stub cs.setInt(1, serailNo); cs.registerOutParameter(2, Types.INTEGER); cs.execute(); return cs.getInt(2); } }); return Integer.valueOf(execute); }
本文標(biāo)題:SpringJDBC訪問(wèn)數(shù)據(jù)庫(kù)
鏈接URL:http://chinadenli.net/article44/ieihhe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供、企業(yè)網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、網(wǎng)頁(yè)設(shè)計(jì)公司、App設(shè)計(jì)、微信公眾號(hào)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)