笔记59 Spring+Hibernate整合(二)
一、项目结构
二、创建表
数据库中只有一张表,stock,三个字段:stock_id、stock_code和stock_name。
1 CREATE TABLE `stock` ( 2 `STOCK_ID` int(10) NOT NULL AUTO_INCREMENT, 3 `STOCK_CODE` varchar(10) NOT NULL DEFAULT '', 4 `STOCK_NAME` varchar(20) NOT NULL DEFAULT '', 5 PRIMARY KEY (`STOCK_ID`) 6 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
三、Model——BO——DAO
模型中,业务对象(BO)和数据访问对象(DAO)模式是有助于清楚地识别层,以避免弄乱项目结构。
1.Stock (Model)
Stock模型类用于数据库存储数据。
Stock.java
1 package stock.model; 2 3 import java.io.Serializable; 4 5 public class Stock implements Serializable { 6 7 /** 8 * 9 */ 10 private static final long serialVersionUID = 1L; 11 private Long stockId; 12 private String stockCode; 13 private String stockName; 14 15 public Long getStockId() { 16 return stockId; 17 } 18 19 public void setStockId(Long stockId) { 20 this.stockId = stockId; 21 } 22 23 public String getStockCode() { 24 return stockCode; 25 } 26 27 public void setStockCode(String stockCode) { 28 this.stockCode = stockCode; 29 } 30 31 public String getStockName() { 32 return stockName; 33 } 34 35 public void setStockName(String stockName) { 36 this.stockName = stockName; 37 } 38 39 public String toString() { 40 return "Stock [stockId=" + stockId + ",stockCode=" + stockCode + ",stockName=" + stockName + "]"; 41 } 42 }
2.Stock Business Object (BO)
Stock 业务对象(BO)接口和实现,它是用来存储项目的业务功能,真正的数据库操作(CRUD)的工作不应该参与这一个类,而是有一个DAO(StockDao)类来完成对数据库的抽插。
StockBo.java
1 package stock.bo; 2 3 import stock.model.Stock; 4 5 public interface StockBo { 6 7 void save(Stock stock); 8 9 void update(Stock stock); 10 11 void delete(Stock stock); 12 13 Stock findByStockCode(String stockCode); 14 }
StockBoImpl.java
1 package stock.bo; 2 3 import stock.dao.StockDao; 4 import stock.model.Stock; 5 6 public class StockBoImpl implements StockBo { 7 8 private StockDao stockDao; 9 10 public StockDao getStockDao() { 11 return stockDao; 12 } 13 14 public void setStockDao(StockDao stockDao) { 15 this.stockDao = stockDao; 16 } 17 18 @Override 19 public void save(Stock stock) { 20 // TODO Auto-generated method stub 21 stockDao.save(stock); 22 } 23 24 @Override 25 public void update(Stock stock) { 26 // TODO Auto-generated method stub 27 stockDao.update(stock); 28 } 29 30 @Override 31 public void delete(Stock stock) { 32 // TODO Auto-generated method stub 33 stockDao.delete(stock); 34 } 35 36 @Override 37 public Stock findByStockCode(String stockCode) { 38 // TODO Auto-generated method stub 39 return stockDao.findByStockCode(stockCode); 40 } 41 42 }
3.Stock (Data Access Object——DAO)
Stock DAO接口和实现,DAO实现类扩展了 Spring 的“HibernateDaoSupport”,以使Spring框架支持Hibernate。通过getHibernateTemplate()执行 Hibernate 功能。
StockDao.java
1 package stock.dao; 2 3 import stock.model.Stock; 4 5 public interface StockDao { 6 7 void save(Stock stock); 8 9 void update(Stock stock); 10 11 void delete(Stock stock); 12 13 Stock findByStockCode(String stockCode); 14 }
StockDaoImpl.java
1 package stock.dao; 2 3 import java.util.List; 4 5 import org.springframework.orm.hibernate3.support.HibernateDaoSupport; 6 7 import stock.model.Stock; 8 9 public class StockDaoImpl extends HibernateDaoSupport implements StockDao { 10 11 @Override 12 public void save(Stock stock) { 13 // TODO Auto-generated method stub 14 getHibernateTemplate().save(stock); 15 } 16 17 @Override 18 public void update(Stock stock) { 19 // TODO Auto-generated method stub 20 getHibernateTemplate().update(stock); 21 } 22 23 @Override 24 public void delete(Stock stock) { 25 // TODO Auto-generated method stub 26 getHibernateTemplate().delete(stock); 27 } 28 29 @Override 30 public Stock findByStockCode(String stockCode) { 31 // TODO Auto-generated method stub 32 @SuppressWarnings("unchecked") 33 List<Stock> stocks = getHibernateTemplate().find("from Stock where stockCode=?", stockCode); 34 return stocks.get(0); 35 } 36 37 }
四、资源配置
为了方便管理,将各个部分的配置都剥离成单独的xml文件。
(一)Hibernate相关配置
1.创建Hibernate映射文件(Stock.hbm.xml)的Stock表,并放在包hibernate中。
Stock.hbm.xml
1 <?xml version="1.0"?> 2 3 <!DOCTYPE hibernate-mapping PUBLIC 4 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 5 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 6 <hibernate-mapping package="com.pojo"> 7 <class name="stock.model.Stock" table="stock"> 8 <id name="stockId" type="java.lang.Long"> 9 <column name="STOCK_ID" /> 10 <generator class="identity" /> 11 </id> 12 <property name="stockCode" type="string"> 13 <column name="STOCK_CODE" length="10" not-null="true" unique="true" /> 14 </property> 15 <property name="stockName" type="string"> 16 <column name="STOCK_NAME" length="20" not-null="true" unique="true" /> 17 </property> 18 </class> 19 20 </hibernate-mapping>
2.配置数据源DataSource
在配置过程中需要一个资源文件,用来存放数据库的详细信息,位于properties包中。
database.properties
1 jdbc.driverClassName=com.mysql.jdbc.Driver 2 jdbc.url=jdbc:mysql://localhost:3306/stock?characterEncoding=UTF-8 3 jdbc.username=root 4 jdbc.password=123456
DataSource.xml(database包中)
1 <beans xmlns="http://www.springframework.org/schema/beans" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://www.springframework.org/schema/beans 4 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> 5 6 <bean 7 class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 8 <property name="location"> 9 <value>properties/database.properties</value> 10 </property> 11 </bean> 12 13 <bean id="dataSource" 14 class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 15 <property name="driverClassName" value="${jdbc.driverClassName}" /> 16 <property name="url" value="${jdbc.url}" /> 17 <property name="username" value="${jdbc.username}" /> 18 <property name="password" value="${jdbc.password}" /> 19 </bean> 20 21 </beans>
3.配置Hibernate的sessionFactory
Hibernate.xml(database包中)
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> 6 7 <!-- Hibernate session factory --> 8 <bean id="sessionFactory" 9 class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 10 11 <property name="dataSource"> 12 <ref bean="dataSource" /> 13 </property> 14 15 <property name="hibernateProperties"> 16 <props> 17 <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> 18 <prop key="hibernate.show_sql">true</prop> 19 <prop key="hbm2ddl.auto">update</prop> 20 </props> 21 </property> 22 23 <property name="mappingResources"> 24 <list> 25 <value>hibernate/Stock.hbm.xml</value> 26 </list> 27 </property> 28 29 </bean> 30 </beans>
(二)Spring相关配置
1.相关bean的注入
创建一个bean配置文件(Stock.xml)的BO和DAO类,把它放入 “spring/beans” 文件夹中。依赖的 DAO(stockDao)bean 注入到 bo(stockBo)bean; SessionFactory 的 bean 成stockDao。
Stock.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 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-2.5.xsd"> <!-- Stock business object --> <bean id="stockBo" class="stock.bo.StockBoImpl"> <property name="stockDao" ref="stockDao" /> </bean> <!-- Stock Data Access Object --> <bean id="stockDao" class="stock.dao.StockDaoImpl"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> </beans>
2.整合
在“spring/config”文件夹中创建配置文件BeanLocations.xml,将所有的配置文件引入。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> 6 7 <!-- Database Configuration --> 8 <import resource="classpath:database/DataSource.xml"/> 9 <import resource="classpath:database/Hibernate.xml"/> 10 11 <!-- Beans Declaration --> 12 <import resource="classpath:spring/beans/Stock.xml"/> 13 14 </beans>
五、测试
1 package stock.test; 2 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.ClassPathXmlApplicationContext; 5 6 import stock.bo.StockBo; 7 import stock.model.Stock; 8 9 public class Test { 10 public static void main(String[] args) { 11 ApplicationContext appContext = new ClassPathXmlApplicationContext("spring/config/BeanLocations.xml"); 12 13 StockBo stockBo = (StockBo) appContext.getBean("stockBo"); 14 15 /** insert **/ 16 Stock stock = new Stock(); 17 stock.setStockCode("7668"); 18 stock.setStockName("HAIO"); 19 stockBo.save(stock); 20 21 /** select **/ 22 Stock stock2 = stockBo.findByStockCode("7668"); 23 System.out.println(stock2); 24 25 /** update **/ 26 stock2.setStockName("HAIO-1"); 27 stockBo.update(stock2); 28 29 // /** delete **/ 30 // stockBo.delete(stock2); 31 32 System.out.println("Done"); 33 } 34 }
六、总结
1.结合思想:通过DAO继承HibernateDaoSupport来实现spring和hibernate的整合。
2.业务层(service)或业务对象(BO)不应该直接对数据库进行抽插,尽量将所有的有关数据库的操作放在DAO层里面。
七、采用注解
1.在Stock.xml中进行修改,采用自动扫描包。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:tx="http://www.springframework.org/schema/tx" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 7 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd 8 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"> 9 10 <context:component-scan base-package="stock"> 11 </context:component-scan> 12 </beans>
2.修改StockBoImpl.java,增加注解。
首先标识此类是一个bean,使用@Component注解,然后自动装载所需的DAO bean。
1 package stock.bo; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.stereotype.Component; 5 6 import stock.dao.StockDao; 7 import stock.model.Stock; 8 9 @Component 10 public class StockBoImpl implements StockBo { 11 12 @Autowired 13 private StockDao stockDao; 14 15 @Override 16 public void save(Stock stock) { 17 // TODO Auto-generated method stub 18 stockDao.save(stock); 19 } 20 21 @Override 22 public void update(Stock stock) { 23 // TODO Auto-generated method stub 24 stockDao.update(stock); 25 } 26 27 @Override 28 public void delete(Stock stock) { 29 // TODO Auto-generated method stub 30 stockDao.delete(stock); 31 } 32 33 @Override 34 public Stock findByStockCode(String stockCode) { 35 // TODO Auto-generated method stub 36 return stockDao.findByStockCode(stockCode); 37 } 38 39 }
2.修改StockDaoImpl.java,增加注解。
spring不会为继承HibernateDaoSupport的对象自动装配sessionFacotry的,不能简单的使用如下语句实现注入:
1 @Autowired 2 private SessionFactory sessionFactory;
这样会报错,如下图所示:
所以必须调用父类的setSessionFactory方法设置sessionfactory。
1 package stock.dao; 2 3 import java.util.List; 4 5 import org.hibernate.SessionFactory; 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.orm.hibernate3.support.HibernateDaoSupport; 8 import org.springframework.stereotype.Component; 9 10 import stock.model.Stock; 11 12 @Component 13 public class StockDaoImpl extends HibernateDaoSupport implements StockDao { 14 15 @Autowired 16 public StockDaoImpl(SessionFactory sessionfactory) { 17 super.setSessionFactory(sessionfactory); 18 } 19 20 @Override 21 public void save(Stock stock) { 22 // TODO Auto-generated method stub 23 getHibernateTemplate().save(stock); 24 } 25 26 @Override 27 public void update(Stock stock) { 28 // TODO Auto-generated method stub 29 getHibernateTemplate().update(stock); 30 } 31 32 @Override 33 public void delete(Stock stock) { 34 // TODO Auto-generated method stub 35 getHibernateTemplate().delete(stock); 36 } 37 38 @Override 39 public Stock findByStockCode(String stockCode) { 40 // TODO Auto-generated method stub 41 @SuppressWarnings("unchecked") 42 List<Stock> stocks = getHibernateTemplate().find("from Stock where stockCode=?", stockCode); 43 return stocks.get(0); 44 } 45 46 }
3.修改Test里面获取bean的方法。
1 StockBo stockBo = (StockBo) appContext.getBean(StockBo.class);