傳統JDBC技術
下面的代碼只是一個使用JDBC連接的示例,實際應用中不會這樣用,一是代碼繁瑣,一是效率低。而Spring在持久層提供了更好的支持,對JDBC進行了良好的封裝。
public class HelloWorld {
Connection conn = null;
Statement stml = null;
{
try {
//獲取數據連接
Class.forName(com.microsoft.jdbc.sqlserver.SQLServerDriver);
conn.DriverManager.getConnection(jdbc:microsoft:sqlserver:\\localhost:1433\stdb,admin,admin);
//開始啓動事務
conn.setAutoCommit(false);
stml = conn.createStatement();
//執行相應操作
stml.executeUpdate("insert into hello values(1,'gf','HelloWorld')");
//執行成功則提交事務
conn.commit();
} catch (SQLException e) {
if (conn != null) {
try {
//執行不成功,則回滾
conn.rollback();
} catch (SQLException ex) {
System.out.println("數據連接有異常" + ex);
}
}
} finally {
//假如stmt不爲空,則關閉 stmt
if (stml != null) {
try {
stml.close();
} catch (SQLException ex) {
System.out.println("執行操作有異常" + ex);
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException ex) {
System.out.println("數據連接有異常" + ex);
}
}
}
}
}
通過XML實現DataSource(數據源)注入
Spring提供了3種XML實現數據源注入的方式:使用Spring自帶的DriverManagerDataSource、使用DBCP連接池、使用Tomcat提供的JNDI。
(1)使用Spring自帶的DriverManagerDataSource
使用DriverManagerDataSource在效率上和直接使用JDBC沒有多大區別。配置文檔和對於的java程序示例如下:
<?xml version="1.0" encoding="UTF8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!--設定dataSource-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!--使用SQL Server數據集-->
<property name="driverClassName">
<value>com.microsoft.jdbc.sqlserver.SQLServerDriver</value>
</property>
<!--設定URL-->
<property name="url">
<value>jdbc:microsoft:sqlserver://localhost:1433/stdb</value>
</property>
<!--設定用戶名-->
<property name="name">
<value>admin</value>
</property>
<!--設定密碼-->
<property name="msg">
<value>admin</value>
</property>
</bean>
<!--設定transactionManager-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<!--示例中的一個DAO-->
<bean id="helloDAO" class="com.gc.action.HelloDAO">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
</bean>
</beans>
public class HelloDAO {
private DataSource dataSource;
private PlatformTransactionManager transactionManager;
//通過依賴注入來完成管理
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
//使用TransactionTemplate對create()方法進行事務管理
public int create(String msg) {
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
//調用TransactionTemplate的execute()方法,並覆寫TransactionCallback類的doInTransaction()方法,在該方法裏進行對數據庫的新增操作
Object result = transactionTemplate.execute(
new TransactionCallback() {
@Override
public Object doInTransaction(TransactionStatus status) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
Object resultObject = jdbcTemplate.update("INSERT INTO hello VALUES(1,'gf','HelloWorld')");
return resultObject;
}
});
}
}
(2)使用DBCP連接池
Spring提供了DBCP連接池的支持,可以直接在配置文檔中配置DBCP數據庫連接池。
<?xml version="1.0" encoding="UTF8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!--設定dataSource-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<!--使用SQL Server數據集-->
<property name="driverClassName">
<value>com.microsoft.jdbc.sqlserver.SQLServerDriver</value>
</property>
<!--設定URL-->
<property name="url">
<value>jdbc:microsoft:sqlserver://localhost:1433/stdb</value>
</property>
<!--設定用戶名-->
<property name="name">
<value>admin</value>
</property>
<!--設定密碼-->
<property name="msg">
<value>admin</value>
</property>
</bean>
<!--設定transactionManager-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<!--示例中的一個DAO-->
<bean id="helloDAO" class="com.gc.action.HelloDAO">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
</bean>
</beans>
(3)使用Tomcat提供的JNDI
與使用DBCP連接池相比,使用Spring來進行Web開發,更多的使用Web容器提供的數據庫連接池功能。如使用Romcat容器,及Tomcat提供的JNDI的配置。
首先在Tomcat的server.xml中添加以下代碼:
<Context path="/myApp" reloadable="true" docBase="D:\eclipse\workspace\myApp" workDir="D:\eclipse\workspace\myApp\work">
<Resource name="jdbc/opendb" auth="Container"
type="javax.sql.DataSource"
factory="org.apache.tomcat.dbcp.BasicDataSourceFactory"
driverClassName="com.microsoft.jdbc.sqlserver.SQLServerDriver"
url="jdbc:microsoft:sqlserver://localhost:1433/stdb"
<!--設定用戶名-->
name="admin"
<!--設定密碼-->
msg="admin"
<!--設定最大連接數-->
maxActive="10000"
<!--設定最大空閒時間-->
maxIdle="10000"
<!--設定最大等待時間-->
maxWait="10000"
removeAbandoned="true"
removeAbandonedTimeout="10"
logAbandoned="true"
/>
</Context>
Spring配置如下:
<?xml version="1.0" encoding="UTF8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!--設定dataSource-->
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>jndi/opendb</value>
</property>
</bean>
<!--設定transactionManager-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<!--示例中的一個DAO-->
<bean id="helloDAO" class="com.gc.action.HelloDAO">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
</bean>
</beans>
使用JdbcTemplate訪問數據
(1)Template模式簡介
Template模式:就是在父類中定義一個操作中算法的骨架或者說操作順序,而將一些步驟的具體實現延遲到子類中。這個模式可能是最簡單的模式了。
(1)父類骨架代碼
package com.gc.action;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.support.DefaultTransactionDefinition;
public abstract class Transaction{
//事務處理的骨架代碼,指明事務處理的操作順序
public Object execute() throws TransactionException {
this.transactionManager.getTransaction(this);
Object result = null;
try {
} catch (Error err) {
// Transactional code throw error -> rollback
this.transactionManager.rollback(this);
throw err;
}
this.transactionManager.commit(this);
return result;
}
//負責傳入具體的事務
public abstract Object doInTransaction();
}
(2)子類具體要進行事務處理的代碼
public class SubTransaction extends Transaction {
//負責傳入具體的事務
public Object doInTransaction() {
//具體對數據庫進行增刪改的代碼
}
}
(2)事務處理中的TransactionTemplate的實現方式
TransactionTemplate事務處理代碼:
public class TransactionTemplate extends DefaultTransactionDefinition implements InitializingBean {
private PlatformTransactionManager transactionManager = null;
//通過依賴注入
public TransactionTemplate(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public PlatformTransactionManager getTransactionManager() {
return transactionManager;
}
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
//執行完畢後調用
public void afterPropertiesSet() {
if (this.transactionManager == null) {
throw new IllegalAnnotationException("transactionManager is required");
}
}
//進行事務處理的骨架,指明瞭事務處理的順序
public Object execute(TransactionCallback action) throws TransactionException {
TransactionStatus status = this.transactionManager.getTransaction(this);
Object result = null;
try {
//執行具體的方法
result = action.doInTransaction(status);
} catch (RuntimeException ex) {
// Transactional code threw application exception -> roolback
rollbackOnException(status,ex);
throw ex;
} catch (Error err) {
// Transactional code threw error -> roolback
rollbackOnException(status,err);
throw err;
}
this.transactionManager.commit(status);
return result;
}
//如果有異常就rollback
private void rollbackOnException(TransactionStatus status, Throwable ex) throws TransactionException{
try {
this.transactionManager.rollback(status);
} catch (RuntimeException ex2) {
throw ex2;
} catch (Error err) {
throw err;
}
}
}
這裏的TransactionTemplate沒有抽象類,在它的execute()方法裏定義事務處理的骨架代碼。但是execute()方法裏的TransactionCallback參數卻是個接口,在這個接口中定義了doInTransaction()方法。
public interface TransactionCallback {
Object doInTransaction(TransactionStatus status);
}
只要實現這個接口,並在doInTransaction()方法裏編寫具體要進行事務處理的代碼就可以了。
public class HelloDAO {
private DataSource dataSource;
private PlatformTransactionManager transactionManager;
//通過依賴注入來完成管理
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
//使用TransactionTemplate對create()方法進行事務管理
public int create(String msg) {
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
//調用TransactionTemplate的execute()方法,並覆寫TransactionCallback類的doInTransaction()方法,在該方法裏進行對數據庫的新增操作
Object result = transactionTemplate.execute(
new TransactionCallback() {
@Override
public Object doInTransaction(TransactionStatus status) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
Object resultObject = jdbcTemplate.update("INSERT INTO hello VALUES(1,'gf','HelloWorld')");
return resultObject;
}
});
}
}
(3)JdbcTemplate的實現方式
JdbaTemplate封裝了傳統JDBC的功能,也實現了Template模式。但與TransactionTemplate有些不同。
import jdk.nashorn.internal.runtime.Context.ThrowErrorManager;
public class JdbcTemplate extends JdbcAccessor implements JdbcOperations{
......
//使用回調方法
public Object execute(ConnectionCallback action) throws DataAccessException {
Connection con = DataSourceUtils.getConnection(getDataSource());
try {
Connection conToUse = con;
if (this.nativeJdbcExtractor != null) {
//Extract native JDBC Connection, castable t OracleConnection or the like.
conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
}
else {
//創建一個連接代理
conToUse = createConnectionProxy(con);
}
return action.doInConnection(conToUse);
} catch (SQLException ex) {
// 釋放連接
DataSourceUtils.releaseConnection(con, getDataSource());
con = null;
throw getExceptionTranslator().translate("ConnectionCallback", getSql(action), ex);
} finally {
DataSourceUtils.releaseConnection(con, getDataSource());
}
}
//使用回調方法
public Object execute(StatementCallback action) throws DataAccessException {
Connection con = DataSourceUtils.getConnection(getDataSource());
Statement stml = null;
try {
Connection conToUse = con;
if (this.nativeJdbcExtractor != null && this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativeStatements()) {
//Extract native JDBC Connection, castable t OracleConnection or the like.
conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
}
//創建Statement
stml = conToUse.createStatement();
applyStatementSetting(stml);
Statement stmlToUse = stml;
if (this.nativeJdbcExtractor != null) {
stmlToUse = this.nativeJdbcExtractor.getNativeStatement(stml);
}
//初始化Statement
Object result = action.doInStatement(stmlToUse);
SQLWarning warning = stml.getWarnings();
throwExceptionOnWarningIfNotIgnoringWarnings(warning);
return result;
} catch (SQLException ex) {
// 釋放連接
DataSourceUtils.releaseConnection(con, getDataSource());
con = null;
throw getExceptionTranslator().translate("ConnectionCallback", getSql(action), ex);
} finally {
DataSourceUtils.releaseConnection(con, getDataSource());
}
}
......
}
從上面JdbaTemplate的部分代碼可以看出,JdbaTemplate與TransactionTemplate類似,都有execute()方法,並且execute()方法是一個接口。但是JdbaTemplate不需要在代碼中使用回調方法,可以只是把SQL語句傳入,直接執行。當然,也可以使用回調方法。
JdbaTemplate的使用:
(1)首先編寫配置文檔,然後通過程序使用JdbaTemplate,並於事務處理結合在一起。
<?xml version="1.0" encoding="UTF8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!--設定dataSource-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!--使用SQL Server數據集-->
<property name="driverClassName">
<value>com.microsoft.jdbc.sqlserver.SQLServerDriver</value>
</property>
<!--設定URL-->
<property name="url">
<value>jdbc:microsoft:sqlserver://localhost:1433/stdb</value>
</property>
<!--設定用戶名-->
<property name="name">
<value>admin</value>
</property>
<!--設定密碼-->
<property name="msg">
<value>admin</value>
</property>
</bean>
<!--設定transactionManager-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<!--示例中的一個DAO-->
<bean id="helloDAO" class="com.gc.action.HelloDAO">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
</bean>
</beans>
public class HelloDAO {
private DataSource dataSource;
private PlatformTransactionManager transactionManager;
//通過依賴注入來完成管理
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
//使用JdbcTemplate
public void create(String msg) {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();//默認事務定義
TransactionStatus status = transactionManager.getTransaction(def);//聲明事務開始
try {
//使用JdbcTemplate往數據庫裏新增數據
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.update("INSERT INTO hello VALUES(1,'gf','HelloWorld')");
} catch (DataAccessException ex) {
// 也可以執行status.setRollbackOnly();
transactionManager.rollback(status);
throw ex;
} finally {
transactionManager.commit(status);
}
}
}
把配置文檔中定義的dataSource通過JdbcTemplate的構造方法進行注入,然後直接執行JdbcTemplate的update()方法即可實現對數據庫的操作。需要兩行代碼實現對數據庫的操作。
(2)還可以把配置文檔中定義的dataSource通過JdbcTemplate的構造方法進行注入也省略掉,直接在配置文檔中配置,並使JdbcTemplate依賴於dataSource。這樣只需要一行代碼就可以實現對數據庫的操作。
<?xml version="1.0" encoding="UTF8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!--設定dataSource-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!--使用SQL Server數據集-->
<property name="driverClassName">
<value>com.microsoft.jdbc.sqlserver.SQLServerDriver</value>
</property>
<!--設定URL-->
<property name="url">
<value>jdbc:microsoft:sqlserver://localhost:1433/stdb</value>
</property>
<!--設定用戶名-->
<property name="name">
<value>admin</value>
</property>
<!--設定密碼-->
<property name="msg">
<value>admin</value>
</property>
</bean>
<!--設定transactionManager-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<!--設定jdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<!--示例中的一個DAO-->
<bean id="helloDAO" class="com.gc.action.HelloDAO">
<!--依賴注入jdbcTemplate-->
<property name="jdbcTemplate">
<ref bean="jdbcTemplate"/>
</property>
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
</bean>
</beans>
public class HelloDAO {
private JdbcTemplate jdbcTemplate;
private PlatformTransactionManager transactionManager;
//通過依賴注入來完成管理
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
//使用JdbcTemplate
public void create(String msg) {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();//默認事務定義
TransactionStatus status = transactionManager.getTransaction(def);//聲明事務開始
try {
//使用JdbcTemplate往數據庫裏新增數據
jdbcTemplate.update("INSERT INTO hello VALUES(1,'gf','HelloWorld')");
} catch (DataAccessException ex) {
// 也可以執行status.setRollbackOnly();
transactionManager.rollback(status);
throw ex;
} finally {
transactionManager.commit(status);
}
}
}
(3)當然,既然構造方法的數據注入可以通過修改配置文件實現,那麼要執行的SQL語句當然也可以通過配置文檔進行配置,這樣如果需要修改SQL語句,就不需要改變代碼,只需要修改配置文檔就可以了。
<?xml version="1.0" encoding="UTF8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!--設定dataSource-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!--使用SQL Server數據集-->
<property name="driverClassName">
<value>com.microsoft.jdbc.sqlserver.SQLServerDriver</value>
</property>
<!--設定URL-->
<property name="url">
<value>jdbc:microsoft:sqlserver://localhost:1433/stdb</value>
</property>
<!--設定用戶名-->
<property name="name">
<value>admin</value>
</property>
<!--設定密碼-->
<property name="msg">
<value>admin</value>
</property>
</bean>
<!--設定transactionManager-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<!--設定jdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<!--示例中的一個DAO-->
<bean id="helloDAO" class="com.gc.action.HelloDAO">
<!--依賴注入jdbcTemplate-->
<property name="jdbcTemplate">
<ref bean="jdbcTemplate"/>
</property>
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="sql">
<value>INSERT INTO hello VALUES(1,'gf','HelloWorld')</value>
</property>
</bean>
</beans>
public class HelloDAO {
private JdbcTemplate jdbcTemplate;
private PlatformTransactionManager transactionManager;
private String sql;
//通過依賴注入來完成管理
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public void setSql(String sql) {
this.sql = sql;
}
//使用JdbcTemplate
public void create(String msg) {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();//默認事務定義
TransactionStatus status = transactionManager.getTransaction(def);//聲明事務開始
try {
//使用JdbcTemplate往數據庫裏新增數據
jdbcTemplate.update(this.sql);
} catch (DataAccessException ex) {
// 也可以執行status.setRollbackOnly();
transactionManager.rollback(status);
throw ex;
} finally {
transactionManager.commit(status);
}
}
}
以上三種方法,代碼量逐漸減少,並且都通過依賴注入實現。
(4)使用JdbaTemplate查詢數據庫
JdbaTemplate提供了很多用來查詢數據庫的方法:queryForMap()、queryForLong()、queryForInt()、queryForList()等。
List rows = jdbcTemplate.queryForList("select * from hello");
Iterator it = rows.iterator();
//通過Iterator獲取list的值
while(it.hasNext()){
Map map = (Map)it.next();
String id = map.get("id");
String name = map.get("name");
String mag = map.get("mag");
}
int count = jdbcTemplate.queryForInt("select count(*) from hello");
(5)使用JdbaTemplate更改數據庫
JdbcTemplate中的update()方法使進行數據庫更愛的常用方式。
jdbcTemplate.update("insert into hello values(1,'gf','HelloWorld')");
jdbcTemplate.update("insert into hello values(?,?,?,)",new Object[]{1,'gf','HelloWorld'});
jdbcTemplate.update("insert into hello values(?,?,?,)",
new PreparedStatementSetter(){
public void setValues(PreparedStatement ps) throws SQLException {
ps.setInt(1,1);
ps.setInt(2,'gf');
ps.setInt(3,'HelloWorld');
}
}
);
jdbcTemplate.update("update hello set name='gf',msg='HelloWorld' where id=1");
jdbcTemplate.update("update hello set name=?,msg=? where id=?",new Object[]{'gf','HelloWorld',1});
使用ORM工具訪問數據
(1)ORM簡述
ORM(Object-Relational Mapping):對象關係映射。
因爲開發人員使用的技術是面向對象技術,而使用的數據庫卻是關係型數據庫。使用ORM,通過在對象和關係型之間建立起一座橋樑。Hibernate、iBatis就是這樣的ORM工具。
ORM包括以下四個部分:
- 一個對持久類對象進行CRUD操作的API。
- 一個語言或API用來規定與類和類屬性相關的查詢。
- 一個規定mapping metadata的工具。
- 一種技術可以讓ORM的實現同事務對象一起進行dirty checking,lazy association fetching以及其他的優化操作。
ORM模型的簡單性簡化了數據庫查詢過程。使用ORM查詢工具,用戶可以訪問期望數據,而不必理解數據庫的底層結構。
(2)使用Hibernate
Hibernate主要應用在持久層方面。
Spring與Hibernate結合在一起:
- 加入Hibernate後的Spring的配置文檔
- Hibernate的配置文件Hello.hbm.xml
- 存放數據的類Hello
- HelloDAO的編寫
<?xml version="1.0" encoding="UTF8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!--設定dataSource-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!--使用SQL Server數據集-->
<property name="driverClassName">
<value>com.microsoft.jdbc.sqlserver.SQLServerDriver</value>
</property>
<!--設定URL-->
<property name="url">
<value>jdbc:microsoft:sqlserver://localhost:1433/stdb</value>
</property>
<!--設定用戶名-->
<property name="name">
<value>admin</value>
</property>
<!--設定密碼-->
<property name="msg">
<value>admin</value>
</property>
</bean>
<!--使用Hibernate的sessionFactory-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource">
<ref local="dataSource"/>
</property>
<property name="mappingResources">
<list>
<value>com/gc/gction/Hello.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<!--設定方言-->
<prop key="hibernate.dialect">
net.sf.hibernate.dialect.SQLServerDialect
</prop>
<!--是否顯示sql-->
<prop key="hibernate.show_sql">
true
</prop>
</props>
</property>
</bean>
<!--設定transactionManager-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<!--示例中的一個DAO-->
<bean id="helloDAO" class="com.gc.action.HelloDAO">
<!--依賴注入jdbcTemplate-->
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
</bean>
</beans>
<!--Hello.hbm.xml-->
<hibernate-mapping>
<class name="com.gc.action.Hello" table="hello" dynamic-update="false" dynamic-insert="false">
<id name="id" column="id" type="java.lang.Integer"/>
<property name="name"
type="java.lang.String"
update="true"
insert="true"
access="property"
<!--欄位名稱爲msg-->
column="msg"
<!--字段長度爲50-->
length="50"/>
<property name="msg"
type="java.lang.String"
update="true"
insert="true"
access="property"
<!--欄位名稱爲name-->
column="name"
<!--字段長度爲50-->
length="50"/>
</class>
</hibernate-mapping>
/**
* @hibernate.class table="hello"
*/
public class Hello {
public Integer id;
public String name;
public String msg;
/**
* @hibernate.id
* column="id"
* type="java.lang.Integer"
*/
public Integer getID() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
/**
* @hibernate.property column="msg" length="50"
*/
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
/**
* @hibernate.property column="name" length="50"
*/
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
在HelloDAO中使用SessionFactory,並和事務處理結合。
public class HelloDAO {
private SessionFactory sessionFactory;
private PlatformTransactionManager transactionManager;
private String sql;
//通過依賴注入來完成管理
public void setSessionFactory(DataSource sessionFactory) {
this.sessionFactory = sessionFactory;
}
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
//使用HibernateTemplate
public void create(String msg) {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();//默認事務定義
TransactionStatus status = transactionManager.getTransaction(def);//聲明事務開始
try {
HibernateTemplate hibernateTemplate = new HibernateTemplate(sessionFactory);
//定義一個Hello
Hello hello = new Hello();
hello.setId(1);
hello.setName("gf");
hello.setMsg("HelloWorld");
//保存或更新hello
hibernateTemplate.saveOrUpdate(hello);
} catch (DataAccessException ex) {
// 也可以執行status.setRollbackOnly();
transactionManager.rollback(status);
throw ex;
} finally {
transactionManager.commit(status);
}
}
}
(3)使用iBatis
iBatis主要應用在持久層方面。
Spring與Hibernate結合在一起:
- 加入iBatis後的Spring的配置文檔
- iBatis的配置文件sqlMapConfig.xml
- 存放數據的類Hello
- HelloDAO的編寫
<?xml version="1.0" encoding="UTF8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!--設定dataSource-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!--使用SQL Server數據集-->
<property name="driverClassName">
<value>com.microsoft.jdbc.sqlserver.SQLServerDriver</value>
</property>
<!--設定URL-->
<property name="url">
<value>jdbc:microsoft:sqlserver://localhost:1433/stdb</value>
</property>
<!--設定用戶名-->
<property name="name">
<value>admin</value>
</property>
<!--設定密碼-->
<property name="msg">
<value>admin</value>
</property>
</bean>
<!--使用iBatis-->
<bean id="sqlMap" class="org.springframework.orm.iBatis.SqlMapClientFactoryBean">
<property name="configLocation">
<value>WEB-INF/sqlMapConfig.xml</value>
</property>
</bean>
<!--設定transactionManager-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<!--示例中的一個DAO-->
<bean id="helloDAO" class="com.gc.action.HelloDAO">
<!--依賴注入jdbcTemplate-->
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="sqlMap">
<ref bean="sqlMap"/>
</property>
</bean>
</beans>
<!--sqlMapConfig.xml-->
<sqlMapConfig>
<sqlMap resource="com/gc/action/Hello.xml"/>
</sqlMapConfig>
<!--Hello.xml-->
<sqlMap namespace="Hello">
<typeAlias alias="hello" type="com.gc.action.Hello" />
<insert id="insertHello" parameterClass="hello">
insert into hello (id,name,msg) values(#id#,#name#,#msg#)
</insert>
</sqlMap>
public class Hello {
public Integer id;
public String name;
public String msg;
public Integer getID() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//HelloDAO.java
public class HelloDAO extends SqlMapClientDaoSupport {
private PlatformTransactionManager transactionManager;
//通過依賴注入來完成管理
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
//使用getSqlMapClientTemplate
public void create(String msg) {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();//默認事務定義
TransactionStatus status = transactionManager.getTransaction(def);//聲明事務開始
try {
//定義一個Hello
Hello hello = new Hello();
hello.setId(1);
hello.setName("gf");
hello.setMsg("HelloWorld");
//保存或更新hello
getSqlMapClientTemplate().update("insertHello",hello);
} catch (DataAccessException ex) {
// 也可以執行status.setRollbackOnly();
transactionManager.rollback(status);
throw ex;
} finally {
transactionManager.commit(status);
}
}
}