Spring與JDBC整合

來源:互聯網
上載者:User

這是一個Java Project

首先是自訂的串連資料庫的屬性檔案jdbc.properties

driverClassName=oracle.jdbc.OracleDriver<br />url=jdbc/:oracle/:thin/:@127.0.0.1/:1521/:jadyer<br />username=scott<br />password=jadyer<br />initialSize=1<br />maxActive=500<br />maxIdle=2<br />minIdle=1

然後是與jdbc.properties同樣位於classpath下的beans.xml檔案

<?xml version="1.0" encoding="UTF-8"?><br /><beans xmlns="http://www.springframework.org/schema/beans"<br />xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br />xmlns:context="http://www.springframework.org/schema/context"<br />xmlns:aop="http://www.springframework.org/schema/aop"<br />xmlns:tx="http://www.springframework.org/schema/tx"<br />xsi:schemaLocation="http://www.springframework.org/schema/beans</p><p>http://www.springframework.org/schema/beans/spring-beans-2.5.xsd</p><p>http://www.springframework.org/schema/context</p><p>http://www.springframework.org/schema/context/spring-context-2.5.xsd</p><p>http://www.springframework.org/schema/aop</p><p>http://www.springframework.org/schema/aop/spring-aop-2.5.xsd</p><p>http://www.springframework.org/schema/tx</p><p>http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"></p><p><!-- 將jdbc.properties中的值引入到設定檔中 --><br /><context:property-placeholder location="classpath:jdbc.properties" /><br /><!-- 也可以通過下面這種方式 --><br /><!--<br /><bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><br /><property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/><br /><property name="ignoreResourceNotFound" value="false"/><br /><property name="locations"><br /><list><br /><value>classpath:config.properties</value><br /><value>file:/app/wzf/password/ElecChnlPayCusPassword.properties</value><br /></list><br /></property><br /></bean><br /> --></p><p><!-- 配置資料來源 --><br /><bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"><br /><property name="driverClassName" value="${driverClassName}" /><br /><property name="url" value="${url}" /><br /><property name="username" value="${username}" /><br /><property name="password" value="${password}" /><br /><!-- 串連池啟動時的初始值 --><br /><property name="initialSize" value="${initialSize}" /><br /><!-- 串連池的最大值 --><br /><property name="maxActive" value="${maxActive}" /><br /><!-- 最大空閑值..經過一個高峰時間後,串連池可以慢慢將已經用不到的串連釋放一部分,一直減少到maxIdle為止 --><br /><property name="maxIdle" value="${maxIdle}" /><br /><!-- 最小空閑值..當閒置串連數少於閥值時,串連池就會預申請一些串連,以免洪峰突襲時來不及申請資料庫連接 --><br /><property name="minIdle" value="${minIdle}" /><br /></bean></p><p><!-- 聲明一個交易管理員 --><br /><!-- 這裡DataSourceTransactionManager類是Spring專門為我們提供的針對資料來源的交易管理員 --><br /><bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><br /><property name="dataSource" ref="dataSource" /><br /></bean><br /><!-- 啟動使用註解實現聲明式交易管理的支援 --><br /><tx:annotation-driven transaction-manager="txManager" /></p><p><bean id="sequence8" class="org.springframework.jdbc.support.incrementer.OracleSequenceMaxValueIncrementer"><br /><property name="incrementerName" value="SEQUENCE_PERSON_8"/><br /><property name="dataSource" ref="dataSource"/><br /></bean><br /><!-- 這裡面的SEQUENCE_PERSON_8和SEQUENCE_PERSON_12是我們在Oracle資料庫中建立的序列名 --><br /><bean id="sequence12" class="org.springframework.jdbc.support.incrementer.OracleSequenceMaxValueIncrementer"><br /><property name="incrementerName" value="SEQUENCE_PERSON_12"/><br /><property name="dataSource" ref="dataSource"/><br /></bean></p><p><bean id="personServiceImpl" class="com.jadyer.service.impl.PersonServiceImpl"><br /><property name="sequence12" ref="sequence12" /><br /><property name="dataSource" ref="dataSource" /><br /></bean><br /></beans></p><p><!-- SpringTeam Dev建議我們採用註解方式來配置事務 --></p><p><!-- 下面是使用Spring設定檔實現交易管理的範例程式碼 --><br /><!--<br />配置交易管理員【共有兩種方式:分別為注入sessionFaction或者dataSource】<br /><bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"><br /><property name="sessionFactory" ref="sessionFactory"/><br /></bean><br /><bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><br /><property name="dataSource" ref="dataSource"/><br /></bean></p><p>設定事務邊界<br />關於事務邊界的設定,不要添加到Dao上,通常設定到業務層。因為商務邏輯要調用很多方法,我們要保證它的原子性<br />這裡就是在商務邏輯介面上設定事務邊界。因為Spring預設JDK動態代理,它就是對介面做的實現,所以我們事務開啟的是介面上的方法<br />另外,層與層之間,最後通過介面來關聯,因為它是抽象的,不經常變動的<br /><aop:config><br /><aop:pointcut id="transactionPointcut" expression="execution(* com.jadyer.service..*.*(..))" /><br /><aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPointcut" /><br /></aop:config></p><p>配置事務的傳播特性<br /><tx:advice id="txAdvice" transaction-manager="txManager"><br /><tx:attributes><br /><tx:method name="get*" read-only="true"propagation="NOT_SUPPORTED" /><br /><tx:method name="add*" propagation="REQUIRED"/><br /><tx:method name="del*" propagation="REQUIRED"/><br /><tx:method name="modify*" propagation="REQUIRED"/><br /><tx:method name="*" propagation="REQUIRED" read-only="true"/><br /></tx:attributes><br /></tx:advice><br /> -->

下面是用到的實體類Person.java

package com.jadyer.model;</p><p>public class Person {<br />private Integer id;<br />private String name;<br />private Integer age;</p><p>/* 三個屬性的setter和getter略 */</p><p>public Person(){} //不要忘記預設的無參構造方法</p><p>public Person(String name, Integer age) {<br />this.name = name;<br />this.age = age;<br />}<br />}

用到的服務層介面PersonService.java

package com.jadyer.service;</p><p>import java.util.List;</p><p>import com.jadyer.model.Person;</p><p>public interface PersonService {<br />public long save(Person person);<br />public void delete(Integer personid);<br />public void update(Person person);<br />public Person getPersonById(Integer personid);<br />public List<Person> getPersons();<br />}

服務層介面的實作類別PersonServiceImpl.java

package com.jadyer.service.impl;</p><p>import java.util.List;</p><p>import javax.sql.DataSource;</p><p>import org.springframework.jdbc.core.JdbcTemplate;<br />import org.springframework.transaction.annotation.Propagation;<br />import org.springframework.transaction.annotation.Transactional;</p><p>import com.jadyer.model.Person;<br />import com.jadyer.service.PersonService;</p><p>@Transactional<br />public class PersonServiceImpl implements PersonService {<br />//private DataSource dataSource; //不建議直接對DataSource進行操作<br />private JdbcTemplate jdbcTemplate; //而是藉助JdbcTemplate<br />public void setDataSource(DataSource dataSource) {<br />this.jdbcTemplate = new JdbcTemplate(dataSource);<br />}</p><p>private OracleSequenceMaxValueIncrementer sequence12;<br />public OracleSequenceMaxValueIncrementer getSequence12() {<br />return sequence12;<br />}<br />public void setSequence12(OracleSequenceMaxValueIncrementer sequence12) {<br />this.sequence12 = sequence12;<br />}</p><p>public long save(Person person) {<br />long ID = this.sequence12.nextLongValue();<br />String sql = "insert into person values(" + ID + ", ?, ?)";<br />Object[] params = new Object[]{person.getName(), person.getAge()};<br />this.jdbcTemplate.update(sql, params);<br />return ID;<br />}</p><p>@Transactional(noRollbackFor=RuntimeException.class) //設定當該方法遇到RuntimeException時,不會復原<br />public void delete(Integer personid) {<br />this.jdbcTemplate.update("delete from person where id=?", new Object[]{personid});<br />throw new RuntimeException("運行期例外"); //為了測試noRollbackFor屬性,故添加此行代碼<br />}</p><p>public void update(Person person) {<br />String sql = "update person set name=? where id=?";<br />Object[] params = new Object[]{person.getName(), person.getId()};<br />this.jdbcTemplate.update(sql, params);<br />}</p><p>//擷取資料的方法,通常不需要交易管理。但它預設的會開啟事務,這會對效能有所影響<br />//所以一般不需要事務的情況下,我們都要為其顯式的註明,告訴Spring不要開啟事務<br />@Transactional(propagation=Propagation.NOT_SUPPORTED)<br />public Person getPersonById(Integer personId) {<br />String sql = "select * from person where id=?";<br />Object[] params = new Object[]{personId};<br />return (Person)jdbcTemplate.queryForObject(sql, params, new PersonRowMapper());<br />}</p><p>@Transactional(propagation=Propagation.NOT_SUPPORTED)<br />public List<Person> getPersons() {<br />//其中RowMapper類型的rowMapper參數的含義是:當查詢到該條記錄時,它會調用第三個對象的回調方法<br />//我們只要實現了這個回調方法,它就可以調用該回調方法了<br />return (List<Person>)jdbcTemplate.query("select * from person", new PersonRowMapper());<br />}</p><p>///**<br />// * @beused 擷取定製業務的接收時間<br />// * @author 宏宇<br />// */<br />//public String getCustomizeReceiveTime(String protocolNo) {<br />//String sql = "select info_value from t_pay_business_customize_info where state='1' and info_name='推送日期' and protocol_no = ?";<br />//try {<br />//return (String)this.getJdbcTemplate().queryForObject(sql, new Object[]{protocolNo}, String.class);<br />//} catch (EmptyResultDataAccessException e) { // 查到空記錄時,會報告此異常<br />//return "未定製";<br />//}<br />//}<br />}

然後是自訂的實現RowMapper介面的類PersonRowMapper.java

package com.jadyer.service.impl;</p><p>import java.sql.ResultSet;<br />import java.sql.SQLException;</p><p>import org.springframework.jdbc.core.RowMapper;</p><p>import com.jadyer.model.Person;</p><p>/**<br /> * 自訂的實現RowMapper介面的類<br /> */<br />public class PersonRowMapper implements RowMapper {<br />public Object mapRow(ResultSet rs, int index) throws SQLException {<br />//當外部調用該方法時,已經做了一步if(rs.next())操作了,所以這裡我們不用再rs.next()了<br />Person person = new Person(rs.getString("name"), rs.getInt("age"));<br />//注意,該句不可少。。否則personService.getPersonById(2)擷取到的Person對象中的id值將是空的<br />person.setId(rs.getInt("id"));<br />//我們的目的是要讓返回的person對象的各個屬性,都不是虛的,都是確有其值的<br />return person;<br />}<br />}

然後是使用JUnit4寫的單元測試類PersonServiceTest.java

package com.jadyer.junit;</p><p>import org.junit.BeforeClass;<br />import org.junit.Test;<br />import org.springframework.context.ApplicationContext;<br />import org.springframework.context.support.ClassPathXmlApplicationContext;</p><p>import com.jadyer.model.Person;<br />import com.jadyer.service.PersonService;</p><p>public class PersonServiceTest {<br />private static PersonService personService;</p><p>@BeforeClass<br />public static void setUpBeforeClass() throws Exception {<br />try {<br />ApplicationContext cxt = new ClassPathXmlApplicationContext("beans.xml");<br />personService = (PersonService) cxt.getBean("personServiceImpl");<br />} catch (RuntimeException e) {<br />e.printStackTrace(); //若出錯,則列印提示資訊到控制台。否則它是不會列印到控制台上的<br />}<br />}</p><p>@Test<br />public void save(){<br />personService.save(new Person("沈浪", 24));<br />personService.save(new Person("王憐花", 25));<br />}</p><p>@Test<br />public void delete(){<br />personService.delete(2);<br />}</p><p>@Test<br />public void update(){<br />Person person = personService.getPersonById(3);<br />person.setName("金無望");<br />personService.update(person);<br />}</p><p>@Test<br />public void getPersonById(){<br />Person person = personService.getPersonById(3);<br />System.out.println("編號:" + person.getId() + "/t姓名:" + person.getName());<br />}</p><p>@Test<br />public void getPersons(){<br />for(Person person : personService.getPersons()){<br />System.out.println("編號:" + person.getId() + "/t姓名:" + person.getName());<br />}<br />}<br />}

最後是資料庫指令碼檔案

--Oracle 11g<br />--建立表格<br />create table person(<br /> id number(2) primary key,<br /> name varchar(8),<br /> age number(2)<br />)</p><p>--建立序列<br />create sequence SEQUENCE_PERSON_12 increment by 1 start with 1 nomaxvalue nocycle;

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.