在独立Java应用程序中使用Tomcat JDBC连接池
在需要數(shù)據(jù)訪問權限的獨立Java應用程序中使用JDBC連接池時,大多數(shù)開發(fā)人員將使用commons-dbcp或c3p0 。 在本教程中,我們將討論在獨立Java應用程序中的Apache Tomcat Web容器中使用JDBC連接池。
Tomcat 7的新功能之一是tomcat-jdbc連接池,它替代了commons-dbcp連接池。 下面列出了tomcat-jdbc相對于commons-dbcp和其他連接池庫的主要優(yōu)點:- 支持高度并發(fā)的環(huán)境和多核/ CPU系統(tǒng)
- Commons-dbcp是單線程的,速度很慢
- Commons-dbcp很復雜(超過60個類),而tomcat-jdbc核心僅包含8個類
- 支持異步連接檢索
- XA連接支持
- 連接池對象公開了可以注冊用于監(jiān)視目的的MBean
- 支持common-dbcp中的大多數(shù)屬性,以及許多增強的屬性
- 支持JDBC攔截器
- Spring Framework 3.1.1
- 休眠4.1.3
- Spring Data JPA 1.1.0
- Tomcat JDBC連接池7.0.27
- H2數(shù)據(jù)庫1.3.167
- 番石榴12.0
依存關系
項目依賴項由Maven管理。 以下是項目的POM文件(pom.xml)的片段。清單1 –項目依賴性
<properties><maven.test.failure.ignore>true</maven.test.failure.ignore><spring.framework.version>3.1.1.RELEASE</spring.framework.version><hibernate.version>4.1.3.Final</hibernate.version><spring.data.jpa.version>1.1.0.RELEASE</spring.data.jpa.version><tomcat.dbcp.version>7.0.27</tomcat.dbcp.version><h2.version>1.3.167</h2.version><slf4j.version>1.6.4</slf4j.version><log4j.version>1.2.16</log4j.version><guava.version>12.0</guava.version> </properties><dependencies><!-- Hibernate --><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-entitymanager</artifactId> <version>${hibernate.version}</version></dependency><!-- Spring Framework --><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>${spring.framework.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>${spring.framework.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-orm</artifactId><version>${spring.framework.version}</version></dependency><!-- Spring Data JPA --><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-jpa</artifactId><version>${spring.data.jpa.version}</version></dependency><!-- Tomcat DBCP --><dependency><groupId>org.apache.tomcat</groupId><artifactId>tomcat-jdbc</artifactId><version>${tomcat.dbcp.version}</version></dependency><!-- Logging --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>${slf4j.version}</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>jcl-over-slf4j</artifactId><version>${slf4j.version}</version><scope>runtime</scope></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>${slf4j.version}</version><scope>runtime</scope></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>${log4j.version}</version></dependency><!-- Others --><dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><version>${h2.version}</version></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>${guava.version}</version></dependency> </dependencies>領域對象模型
對象模型是一個簡單的聯(lián)系信息模型。 每個聯(lián)系人都有其名字,姓氏和出生日期。 同樣,每個聯(lián)系人將與零個或多個愛好(例如游泳,慢跑,閱讀等)相關聯(lián)。 在DOM中,有兩個主要類,即Contact和Hobby類。 清單2和3分別顯示了這些類的代碼清單。清單2 – Contact類
@Entity @Table(name = "contact") public class Contact {private Long id;private int version;private String firstName;private String lastName;private Date birthDate;private Set<Hobby> hobbies = new HashSet<Hobby>();@Id@GeneratedValue(strategy=GenerationType.IDENTITY)@Column(name = "ID")public Long getId() {return id;}public void setId(Long id) {this.id = id;}@Version@Column(name = "VERSION")public int getVersion() {return version;}public void setVersion(int version) {this.version = version;}@Column(name = "FIRST_NAME")public String getFirstName() {return firstName;}public void setFirstName(String firstName) {this.firstName = firstName;}@Column(name = "LAST_NAME")public String getLastName() {return lastName;}public void setLastName(String lastName) {this.lastName = lastName;}@Column(name = "BIRTH_DATE")@Temporal(TemporalType.DATE)public Date getBirthDate() {return birthDate;}public void setBirthDate(Date birthDate) {this.birthDate = birthDate;} @ManyToMany@JoinTable(name = "contact_hobby_detail", joinColumns = @JoinColumn(name = "CONTACT_ID"), inverseJoinColumns = @JoinColumn(name = "HOBBY_ID"))public Set<hobby> getHobbies() {return this.hobbies;}public void setHobbies(Set<hobby> hobbies) {this.hobbies = hobbies;} public String toString() { return "Contact - Id: " + id + ", First name: " + firstName + ", Last name: " + lastName + ", Birthday: " + birthDate;} }清單3 – Hobby類
@Entity @Table(name = "hobby") public class Hobby {private String hobbyId;private Set<Contact> contacts = new HashSet<Contact>();public Hobby() {}public Hobby(String hobbyId) {this.hobbyId = hobbyId;}public Hobby(String hobbyId, Set<Contact> contacts) {this.hobbyId = hobbyId;this.contacts = contacts;}@Id@Column(name = "HOBBY_ID")public String getHobbyId() {return this.hobbyId;}public void setHobbyId(String hobbyId) {this.hobbyId = hobbyId;}@ManyToMany@JoinTable(name = "contact_hobby_detail", joinColumns = @JoinColumn(name = "HOBBY_ID"), inverseJoinColumns = @JoinColumn(name = "CONTACT_ID"))public Set<Contact> getContacts() {return this.contacts;}public void setContacts(Set<Contact> contacts) {this.contacts = contacts;} } 在清單2和3中,注意到Contact和Hobby類之間存在多對多關系。數(shù)據(jù)庫架構
在本教程中,我們將使用H2內(nèi)存數(shù)據(jù)庫。 有3個表:
- 聯(lián)系人:該表存儲聯(lián)系人信息
- HOBBY:該表存儲可用于該應用程序的興趣愛好列表
- CONTACT_HOBBY_DETAIL:對Contact和Hobby類之間的多對多關系進行建模
清單4 –數(shù)據(jù)庫模式創(chuàng)建腳本(schema.sql)
DROP TABLE IF EXISTS CONTACT;CREATE TABLE CONTACT (ID INT NOT NULL AUTO_INCREMENT,FIRST_NAME VARCHAR(60) NOT NULL,LAST_NAME VARCHAR(40) NOT NULL,BIRTH_DATE DATE,VERSION INT NOT NULL DEFAULT 0,UNIQUE UQ_CONTACT_1 (FIRST_NAME, LAST_NAME),PRIMARY KEY (ID) );CREATE TABLE HOBBY (HOBBY_ID VARCHAR(20) NOT NULL,PRIMARY KEY (HOBBY_ID) );CREATE TABLE CONTACT_HOBBY_DETAIL (CONTACT_ID INT NOT NULL,HOBBY_ID VARCHAR(20) NOT NULL,PRIMARY KEY (CONTACT_ID, HOBBY_ID),CONSTRAINT FK_CONTACT_HOBBY_DETAIL_1 FOREIGN KEY (CONTACT_ID)REFERENCES CONTACT (ID) ON DELETE CASCADE,CONSTRAINT FK_CONTACT_HOBBY_DETAIL_2 FOREIGN KEY (HOBBY_ID)REFERENCES HOBBY (HOBBY_ID) );清單5 –測試數(shù)據(jù)填充腳本(test-data.sql)
insert into contact (first_name, last_name, birth_date) values ('Clarence', 'Ho', '1980-07-30'); insert into contact (first_name, last_name, birth_date) values ('Scott', 'Tiger', '1990-11-02');insert into hobby (hobby_id) values ('Swimming'); insert into hobby (hobby_id) values ('Jogging'); insert into hobby (hobby_id) values ('Programming'); insert into hobby (hobby_id) values ('Movies'); insert into hobby (hobby_id) values ('Reading');insert into contact_hobby_detail(contact_id, hobby_id) values (1, 'Swimming'); insert into contact_hobby_detail(contact_id, hobby_id) values (1, 'Movies'); insert into contact_hobby_detail(contact_id, hobby_id) values (2, 'Swimming');服務層
在服務層中,存在2個接口:
- ContactService:提供用于訪問聯(lián)系信息的服務
- HobbyService:提供用于訪問愛好信息的服務
清單6和7分別顯示了ContactService和HobbyService接口。
清單6 – ContactService接口
public interface ContactService {public List<Contact> findAll();public Contact findById(Long id);public Contact save(Contact contact);}清單7 – HobbyService接口
public interface HobbyService {public List<Hobby> findAll();}彈簧配置
讓我們看一下Spring配置。 清單8顯示了數(shù)據(jù)源,事務和JPA配置。
清單8 – Spring JPA配置(datasource-tx-jpa.xml)
<!--Tomcat JDBC connection pool configutation --> <bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource"><property name="driverClassName" value="org.h2.Driver" /><property name="url" value="jdbc:h2:mem:testdb" /><property name="username" value="sa" /><property name="password" value="" /> </bean><!--Intialize the database schema with test data --> <jdbc:initialize-database data-source="dataSource"><jdbc:script location="classpath:schema.sql"/><jdbc:script location="classpath:test-data.sql"/> </jdbc:initialize-database><bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"><property name="entityManagerFactory" ref="emf"/> </bean><tx:annotation-driven transaction-manager="transactionManager" /><bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"><property name="dataSource" ref="dataSource" /><property name="jpaVendorAdapter"><bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/></property><property name="packagesToScan" value="com.skywidesoft.tomcat.dbcp.tutorial.domain"/><property name="jpaProperties"><props><prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop><prop key="hibernate.max_fetch_depth">3</prop><prop key="hibernate.jdbc.fetch_size">50</prop><prop key="hibernate.jdbc.batch_size">10</prop><prop key="hibernate.show_sql">true</prop></props></property> </bean>?<context:annotation-config/><!--Spring Data JPA Repository Configuration --> <jpa:repositories base-package="com.skywidesoft.tomcat.dbcp.tutorial.repository"entity-manager-factory-ref="emf"transaction-manager-ref="transactionManager"/>下面列出了清單8中配置的一些要點:
- 對于dataSource bean,使用org.apache.tomcat.jdbc.pool.DataSource類為基礎連接提供JDBC DataSource接口。 您將看到配置與使用commons-dbcp基本上相同。
- <jdbc:initialize-database>標記是Spring 3.1對使用數(shù)據(jù)庫架構和測試數(shù)據(jù)初始化數(shù)據(jù)庫的支持
- <jpa:repositories>標記用于配置Spring Data JPA的存儲庫抽象。
清單9顯示了Spring應用程序上下文配置。
清單9 – Spring應用程序上下文(app-context.xml)
<import resource="classpath:datasource-tx-jpa.xml"/><context:component-scan base-package="com.skywidesoft.tomcat.dbcp.tutorial.service.jpa"/>Spring Data JPA存儲庫抽象
Spring Data JPA的存儲庫抽象為開發(fā)基于JPA的數(shù)據(jù)訪問應用程序提供了一種簡化的方法。 有關詳細信息,請訪問項目網(wǎng)站 。 存儲庫抽象層是使用Java界面開發(fā)的。 清單10和11分別顯示了ContactRepository和HobbyRepository接口的代碼清單。清單10 – ContactRepository接口
public interface ContactRepository extends CrudRepository<Contact, Long>{}清單11 – HobbyRepository接口
public interface HobbyRepository extends CrudRepository<Hobby, String>{}請注意,該接口只是擴展了Spring Data Common的CrudRepository <T,ID>接口,該接口已經(jīng)提供了常見的數(shù)據(jù)訪問操作(例如findAll,findOne,保存,刪除等)。
JPA實施類
下一步是開發(fā)清單6和7中的服務層接口的JPA實現(xiàn)。這些類采用Spring Framework的注解用于Spring bean聲明,依賴項的自動裝配和事務需求等。清單12和13顯示了ContactServiceImpl和HobbyServiceImpl類。清單12 – ContactServiceImpl類
@Service("contactService") @Repository @Transactional public class ContactServiceImpl implements ContactService {final static Logger logger = LoggerFactory.getLogger(ContactServiceImpl.class);@Autowiredprivate ContactRepository contactRepository;@Transactional(readOnly=true)public List<Contact> findAll() {logger.info("Finding all contacts");return Lists.newArrayList(contactRepository.findAll());}@Transactional(readOnly=true)public Contact findById(Long id) {return contactRepository.findOne(id);}public Contact save(Contact contact) {return contactRepository.save(contact);}}清單13 – HobbyServiceImpl類
@Service("hobbyService") @Repository @Transactional public class HobbyServiceImpl implements HobbyService {@Autowiredprivate HobbyRepository hobbyRepository;@Transactional(readOnly=true)public List<Hobby> findAll() {return Lists.newArrayList(hobbyRepository.findAll());}}測試中
讓我們看看實際的應用程序。 清單14顯示了ContactServiceTest類,該類僅從app-context.xml文件中引導Spring應用程序上下文,查找contactService bean,并調(diào)用findAll操作以從數(shù)據(jù)庫中檢索所有聯(lián)系人。清單14 – ContactServiceTest類
public class ContactServiceTest {public static void main(String[] args) {GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();ctx.load("classpath:app-context.xml");ctx.refresh();ContactService contactService = ctx.getBean("contactService", ContactService.class);List<Contact> contacts = contactService.findAll(); for (Contact contact: contacts) {System.out.println(contact);} }} 運行上面的類將在控制臺輸出窗口中產(chǎn)生以下輸出(省略了其他不相關的輸出): 2012-05-25 13:35:43,552 INFO [com.skywidesoft.tomcat.dbcp.tutorial.service.jpa.ContactServiceImpl] -
<Finding all contacts>
contact0_.BIRTH_DATE as BIRTH2_0_, contact0_.FIRST_NAME as FIRST3_0_,
結論
本教程介紹了如何在獨立的Java應用程序中使用Tomcat的JDBC連接池。 Tomcat的JDBC連接池替代了commons-dbcp連接池,提供了更快,功能更豐富的JDBC連接池解決方案。 它的簡潔設計,高性能,對高度并發(fā)環(huán)境的支持以及多核/ cpu系統(tǒng)使其成為Tomcat Web容器和獨立Java應用程序環(huán)境中的JDBC連接池提供程序的極具吸引力的選擇。下載完整的Eclipse Maven Project 。
參考:來自我們的W4G合作伙伴 Clarence Ho的 獨立Java應用程序中的Tomcat JDBC連接池使用 。
Clarence Ho是APress的Pro Spring 3的主要作者。 借助Pro Spring 3 ,您將學習Spring的基礎知識和核心主題,并獲得作者關于遠程處理, Hibernate和EJB的見解和實際經(jīng)驗。 除了基礎知識之外,您還將學習如何利用Spring框架構建企業(yè)Java應用程序的各個層或部分,例如事務,Web和表示層,部署等。 完整的示例應用程序使您可以應用本書中介紹的許多技術,并了解它們?nèi)绾螀f(xié)同工作。
APress已為Java Code Geeks的讀者提供了優(yōu)惠券代碼。 優(yōu)惠券代碼為: SPR76 ,有效期至2012年7月6日 。 該代碼僅可從apress.com獲得40%的電子書折扣 。
翻譯自: https://www.javacodegeeks.com/2012/06/using-tomcat-jdbc-connection-pool-in.html
總結
以上是生活随笔為你收集整理的在独立Java应用程序中使用Tomcat JDBC连接池的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蓝齐儿历史原型是谁(康熙女儿蓝齐儿真实历
- 下一篇: 对JavaFX Mobile应用程序进行