spring学习2 Spring与hibernate的结合
Spring+Hibernate例程- -
本文中的Spring+Hibernate的例程只是从一个最简单的组合方面下手来做的,并未涉及比较具体或是复杂的内容,毕竟单就Spring或是Hibernate来讲,每一个都不是三言两语就可以说明白的,原理简单,但是一旦涉及到应用上,考虑的方方面面以及要处理的内容就变得多起来,况且框架本身还有比较庞大的API,不过这个需要在不断使用的过程中才能慢慢熟练起来。
本文的软件开发流程如下:
- 调查并分析需求,从中建立模块以及实体
- 根据实体设计表结构,从而在数据库中建表
- 由数据表得到类,然后构造映射文件
- 通过框架进行业务逻辑编写和处理
其中,由数据表得到类,这个有些工具可以生成带有XDoclet标记的源文件,然后通过XDoclet来生成hbm文件,本例中Hibernate的相关管理直接给Spring了,所以并没有建立Hibernate单独的配置文件,本文认为,一般性的应用如此已经足够,当然,如果复杂起来的话,则需要针对各个框架进行深入的研究和学习。
本文例程假定表结构已经确定,并且忽略由表到类和由类到映射文件的过程,只是一组代码,不过,下面会专门研究一下如何由表到类的过程,里面还要包括XDoclet的标记,希望有相应的开源且免费的工具可用吧。
环境:
-
Eclipse 3.2
-
MySQL 4.1
步骤如下:
1. 下载Spring和Hibernate,本文下载文件如下:
-
spring-framework-2.0.1-with-dependencies.zip
http://www.springframework.org -
hibernate-3.2.2.ga.zip
http://www.hibernate.org/
并解压至随便位置,只是为了方便从里面找相应的包来用。
2. 本例中要用到的相关包列表如下,都可以从上面两个压缩包中找到。
-
antlr-2.7.6.jar
-
aopalliance.jar
-
asm.jar
-
cglib-2.1.3.jar
-
commons-collections.jar
-
commons-dbcp.jar
-
commons-logging.jar
-
commons-pool.jar
-
dom4j-1.6.1.jar
-
hibernate3.jar
-
jta.jar
-
mysql-connector-java-3.1.12-bin.jar
-
spring-aop.jar
-
spring-beans.jar
-
spring-context.jar
-
spring-core.jar
-
spring-dao.jar
-
spring-hibernate3.jar
-
spring-jdbc.jar
3. 建立数据表,本例只使用两个简单的表示范一个新增的操作,是tbl_customer和tbl_account两个表,其构造的SQL如下:
DROP TABLE IF EXISTS `tbl_customer`;
DROP TABLE IF EXISTS `tbl_account`;
CREATE TABLE `tbl_customer` (
`customer_id` int(11) unsigned NOT NULL auto_increment,
`customer_email` varchar(82) NOT NULL default '',
`customer_password` varchar(10) NOT NULL default '',
`customer_userid` varchar(12) NOT NULL default '',
`customer_firstname` varchar(25) NOT NULL default '',
`customer_lastname` varchar(25) NOT NULL default '',
PRIMARY KEY (`customer_id`),
UNIQUE KEY `customer_userid` (`customer_userid`)
) TYPE=MyISAM;
CREATE TABLE `tbl_account` (
`account_id` int(11) unsigned NOT NULL auto_increment,
`customer_id` int(11) NOT NULL default '0',
`account_name` varchar(50) NOT NULL default '',
`account_type` varchar(20) NOT NULL default '',
`create_date` date NOT NULL default '0000-00-00',
`update_date` date NOT NULL default '0000-00-00',
`account_balance` double(15,3) NOT NULL default '0.000',
PRIMARY KEY (`account_id`)
) TYPE=MyISAM;
4. 构造相关类Account和Customer,如下(注:在这里,没有加入XDoclet的内容,原因在于这个例程早于XDoclet例程的建立,而且这会还没有由表到类好的解决方案):
Customer.java
package net.ofbase.hibernate.example;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.Set;
public class Customer {
private Long id = new Long(-1);
private String userId;
private String password;
private String email;
private String firstName;
private String lastName;
private BigDecimal balance;
private Set accounts = new HashSet();
public String getEmail() {return email;}
public void setEmail(String email) {this.email = email;}
public String getPassword() { return password;}
public void setPassword(String password) { this.password = password;}
public Long getId() {return id;}
public void setId(Long id) {this.id = id;}
public Set getAccounts() {return accounts;}
public void setAccounts(Set accounts) {this.accounts = accounts;}
public void addAccount(Account account) {
account.setCustomer(this);
accounts.add(account);
}
public BigDecimal getBalance() {return balance;}
public void setBalance(BigDecimal balance) {this.balance = balance;}
public String getFirstName() {return firstName;}
public void setFirstName(String firstName) {this.firstName = firstName;}
public String getLastName() {return lastName;}
public void setLastName(String lastName) { this.lastName = lastName;}
public String getUserId() {return userId;}
public void setUserId(String userId) {this.userId = userId;}
}
Account.java
package net.ofbase.hibernate.example;
import java.util.Date;
public class Account {
private Long id = new Long(-1);
private String accountName;
private String type;
private Double balance;
private Date createDate;
private Date updateDate;
private Customer customer;
public String getAccountName() {return accountName;}
public void setAccountName(String accountName) {this.accountName = accountName;}
public Date getCreateDate() {return createDate;}
public void setCreateDate(Date createDate) {this.createDate = createDate;}
public Long getId() {return id;}
public void setId(Long id) {this.id = id;}
public String getType() {return type;}
public void setType(String type) {this.type = type;}
public Date getUpdateDate() {return updateDate;}
public void setUpdateDate(Date updateDate) {this.updateDate = updateDate;}
public Customer getCustomer() { return customer;}
public void setCustomer(Customer customer) {this.customer = customer;}
public Double getBalance() {return balance;}
public void setBalance(Double balance) {this.balance = balance;}
}
5. 相应的两个hbm文件。
Customer.hbm.xml
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="net.ofbase.hibernate.example.Customer"
table="TBL_CUSTOMER" dynamic-update="false" dynamic-insert="false">
<id name="id" column="CUSTOMER_ID" type="java.lang.Long"
unsaved-value="-1">
<generator class="native" />
</id>
<set name="accounts" inverse="true"
cascade="all-delete-orphan">
<key column="CUSTOMER_ID" />
<one-to-many class="net.ofbase.hibernate.example.Account" />
</set>
<property name="email" type="string" update="false"
insert="true" column="CUSTOMER_EMAIL" length="82" not-null="true" />
<property name="password" type="string" update="false"
insert="true" column="CUSTOMER_PASSWORD" length="10" not-null="true" />
<property name="userId" type="string" update="false"
insert="true" column="CUSTOMER_USERID" length="12" not-null="true"
unique="true" />
<property name="firstName" type="string" update="false"
insert="true" column="CUSTOMER_FIRSTNAME" length="25"
not-null="true" />
<property name="lastName" type="string" update="false"
insert="true" column="CUSTOMER_LASTNAME" length="25" not-null="true" />
</class>
</hibernate-mapping>
Account.hbm.xml
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="net.ofbase.hibernate.example.Account" table="TBL_ACCOUNT"
dynamic-update="false" dynamic-insert="false">
<id name="id" column="ACCOUNT_ID" type="java.lang.Long"
unsaved-value="-1">
<generator class="native" />
</id>
<many-to-one name="customer" column="CUSTOMER_ID"
class="net.ofbase.hibernate.example.Customer" not-null="true" />
<property name="accountName" type="string" update="false"
insert="true" column="ACCOUNT_NAME" length="50" not-null="true" />
<property name="type" type="string" update="false" insert="true"
column="ACCOUNT_TYPE" length="1" not-null="true" />
<property name="createDate" type="date" update="false"
insert="true" column="CREATE_DATE" not-null="true" />
<property name="updateDate" type="date" update="true"
insert="true" not-null="true" column="UPDATE_DATE" />
<property name="balance" type="double" update="true"
insert="true" column="ACCOUNT_BALANCE" not-null="true" />
</class>
</hibernate-mapping>
6. Spring之配置文件spring-hibernate-bean.xml。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="ds"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>
jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=gb2312
</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>maude</value>
</property>
</bean>
<!-- Hibernate SessionFactory,定义了,用以传给继承HibernateDaoSupport的类 -->
<bean id="hibernateSessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref local="ds" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<!-- 这里需要包括所有的O-R映射文件 -->
<property name="mappingResources">
<list>
<value>Customer.hbm.xml</value>
<value>Account.hbm.xml</value>
</list>
</property>
</bean>
<!-- 将session factory传递给UserDAO -->
<bean id="customerDAOTarget"
class="net.ofbase.hibernate.example.impl.CustomerDAOImpl">
<property name="sessionFactory">
<ref local="hibernateSessionFactory" />
</property>
</bean>
<bean id="tm"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="hibernateSessionFactory" />
</property>
</bean>
<bean id="userDAO"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="tm" />
</property>
<property name="target">
<ref local="customerDAOTarget" />
</property>
<property name="transactionAttributes">
<props>
<prop key="addCustomer">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>
7. 建立DAO接口。
AccountDAO.java
package net.ofbase.hibernate.example;
public interface AccountDAO {
public abstract void addAccount(Account account);
}
CustomerDAO.java
package net.ofbase.hibernate.example;
public interface CustomerDAO {
public abstract void addCustomer(Customer customer);
public abstract Customer getCustomerAccountInfo(Customer customer);
}
8. 实现这两个DAO接口以用于操作数据。
CustomerDAOImpl.java
package net.ofbase.hibernate.example.impl;
import java.util.List;
import net.ofbase.hibernate.example.Customer;
import net.ofbase.hibernate.example.CustomerDAO;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public class CustomerDAOImpl extends HibernateDaoSupport implements CustomerDAO {
/** 保存实例 */
public void addCustomer(Customer customer) {getHibernateTemplate().save(customer);}
public Customer getCustomerAccountInfo(Customer customer) {
Customer cust = null;
List list = getHibernateTemplate().find(
"from Customer customer where customer.userId = ?", customer.getUserId());
if (list.size() > 0)
cust = (Customer) list.get(0);
return cust;
}
}
AccountDAOImpl.java
package net.ofbase.hibernate.example.impl;
import net.ofbase.hibernate.example.Account;
import net.ofbase.hibernate.example.AccountDAO;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public class AccountDAOImpl extends HibernateDaoSupport implements AccountDAO {
public void addAccount(Account account) {getHibernateTemplate().save(account);}
}
9. 建立测试程序Main.java。
package net.ofbase.hibernate.example;
import java.util.Date;
import net.ofbase.hibernate.example.impl.CustomerDAOImpl;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.orm.hibernate3.LocalSessionFactoryBean;
public class Main {
public static ClassPathXmlApplicationContext appContext = null;
public static void main(String[] args) {
try {
// 取得Spring上下文
ClassPathXmlApplicationContext appContext =
new ClassPathXmlApplicationContext(
new String[] { "spring-hibernate-bean.xml" });
// 实例化Customer
Customer customer = new Customer();
customer.setEmail("base.x@126.com");
customer.setUserId("base");
customer.setPassword("123456");
customer.setFirstName("Base");
customer.setLastName("Xia");
// 实例化Account
Account acc = new Account();
acc.setAccountName("base");
acc.setType("C");
acc.setCreateDate(new Date());
acc.setUpdateDate(new Date());
acc.setBalance(new Double(500.00));
// 这里还有一个关联关系
customer.addAccount(acc);
// 打出DAO实例,并且进行有一对多关联的新增动作
CustomerDAOImpl customerDAOImpl =
(CustomerDAOImpl) appContext.getBean("customerDAOTarget");
customerDAOImpl.addCustomer(customer);
// 由数据库中取回存储的值
Customer o = customerDAOImpl.getCustomerAccountInfo(customer);
System.out.println("找到客户,其用户ID值是 " + o.getUserId());
} catch (Exception e) {
e.printStackTrace();
}
}
private static void createDatabaseSchema() throws Exception {
LocalSessionFactoryBean sessionFactory = (LocalSessionFactoryBean) appContext
.getBean("&frameworkSessionFactory");
sessionFactory.dropDatabaseSchema();
sessionFactory.createDatabaseSchema();
}
}
10. 运行Main.java,可以得到如下提示:
……
Hibernate: insert into TBL_CUSTOMER (CUSTOMER_EMAIL, CUSTOMER_PASSWORD, CUSTOMER_USERID, CUSTOMER_FIRSTNAME, CUSTOMER_LASTNAME) values (?, ?, ?, ?, ?)
Hibernate: insert into TBL_ACCOUNT (CUSTOMER_ID, ACCOUNT_NAME, ACCOUNT_TYPE, CREATE_DATE, UPDATE_DATE, ACCOUNT_BALANCE) values (?, ?, ?, ?, ?, ?)
Hibernate: select customer0_.CUSTOMER_ID as CUSTOMER1_0_, customer0_.CUSTOMER_EMAIL as CUSTOMER2_0_, customer0_.CUSTOMER_PASSWORD as CUSTOMER3_0_, customer0_.CUSTOMER_USERID as CUSTOMER4_0_, customer0_.CUSTOMER_FIRSTNAME as CUSTOMER5_0_, customer0_.CUSTOMER_LASTNAME as CUSTOMER6_0_ from TBL_CUSTOMER customer0_ where customer0_.CUSTOMER_USERID=?
找到客户,其用户ID值是 base
11. 检查一下数据库,里面已经有数据了。
本例的业务逻辑很简单,在实际使用中还需要参考一些相关的资料,不过Spring和Hibernate的资料还是很全的,而且像开发手册之类的也已经在汉化版本了,便也不用看E文看的头晕了。
本文介绍了一个简单的Spring与Hibernate整合示例,展示了如何利用这两种框架完成数据库操作。具体包括搭建开发环境、创建实体类及映射文件、配置Spring与Hibernate等步骤。
1978

被折叠的 条评论
为什么被折叠?



