笔记59 Spring+Hibernate整合(二)

时间:2023-03-09 18:00:05
笔记59 Spring+Hibernate整合(二)

一、项目结构

笔记59 Spring+Hibernate整合(二)

二、创建表

数据库中只有一张表,stock,三个字段:stock_id、stock_code和stock_name。

 CREATE TABLE `stock` (
`STOCK_ID` int(10) NOT NULL AUTO_INCREMENT,
`STOCK_CODE` varchar(10) NOT NULL DEFAULT '',
`STOCK_NAME` varchar(20) NOT NULL DEFAULT '',
PRIMARY KEY (`STOCK_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

三、Model——BO——DAO

模型中,业务对象(BO)和数据访问对象(DAO)模式是有助于清楚地识别层,以避免弄乱项目结构。

1.Stock (Model)

Stock模型类用于数据库存储数据。

Stock.java

 package stock.model;

 import java.io.Serializable;

 public class Stock implements Serializable {

     /**
*
*/
private static final long serialVersionUID = 1L;
private Long stockId;
private String stockCode;
private String stockName; public Long getStockId() {
return stockId;
} public void setStockId(Long stockId) {
this.stockId = stockId;
} public String getStockCode() {
return stockCode;
} public void setStockCode(String stockCode) {
this.stockCode = stockCode;
} public String getStockName() {
return stockName;
} public void setStockName(String stockName) {
this.stockName = stockName;
} public String toString() {
return "Stock [stockId=" + stockId + ",stockCode=" + stockCode + ",stockName=" + stockName + "]";
}
}

2.Stock Business Object (BO)

  Stock 业务对象(BO)接口和实现,它是用来存储项目的业务功能,真正的数据库操作(CRUD)的工作不应该参与这一个类,而是有一个DAO(StockDao)类来完成对数据库的抽插。

StockBo.java

 package stock.bo;

 import stock.model.Stock;

 public interface StockBo {

     void save(Stock stock);

     void update(Stock stock);

     void delete(Stock stock);

     Stock findByStockCode(String stockCode);
}

StockBoImpl.java

 package stock.bo;

 import stock.dao.StockDao;
import stock.model.Stock; public class StockBoImpl implements StockBo { private StockDao stockDao; public StockDao getStockDao() {
return stockDao;
} public void setStockDao(StockDao stockDao) {
this.stockDao = stockDao;
} @Override
public void save(Stock stock) {
// TODO Auto-generated method stub
stockDao.save(stock);
} @Override
public void update(Stock stock) {
// TODO Auto-generated method stub
stockDao.update(stock);
} @Override
public void delete(Stock stock) {
// TODO Auto-generated method stub
stockDao.delete(stock);
} @Override
public Stock findByStockCode(String stockCode) {
// TODO Auto-generated method stub
return stockDao.findByStockCode(stockCode);
} }

3.Stock (Data Access Object——DAO)

  Stock DAO接口和实现,DAO实现类扩展了 Spring 的“HibernateDaoSupport”,以使Spring框架支持Hibernate。通过getHibernateTemplate()执行 Hibernate 功能。

StockDao.java

 package stock.dao;

 import stock.model.Stock;

 public interface StockDao {

     void save(Stock stock);

     void update(Stock stock);

     void delete(Stock stock);

     Stock findByStockCode(String stockCode);
}

StockDaoImpl.java

 package stock.dao;

 import java.util.List;

 import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

 import stock.model.Stock;

 public class StockDaoImpl extends HibernateDaoSupport implements StockDao {

     @Override
public void save(Stock stock) {
// TODO Auto-generated method stub
getHibernateTemplate().save(stock);
} @Override
public void update(Stock stock) {
// TODO Auto-generated method stub
getHibernateTemplate().update(stock);
} @Override
public void delete(Stock stock) {
// TODO Auto-generated method stub
getHibernateTemplate().delete(stock);
} @Override
public Stock findByStockCode(String stockCode) {
// TODO Auto-generated method stub
@SuppressWarnings("unchecked")
List<Stock> stocks = getHibernateTemplate().find("from Stock where stockCode=?", stockCode);
return stocks.get(0);
} }

四、资源配置

为了方便管理,将各个部分的配置都剥离成单独的xml文件。

(一)Hibernate相关配置

1.创建Hibernate映射文件(Stock.hbm.xml)的Stock表,并放在包hibernate中。

Stock.hbm.xml

 <?xml version="1.0"?>

 <!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.pojo">
<class name="stock.model.Stock" table="stock">
<id name="stockId" type="java.lang.Long">
<column name="STOCK_ID" />
<generator class="identity" />
</id>
<property name="stockCode" type="string">
<column name="STOCK_CODE" length="10" not-null="true" unique="true" />
</property>
<property name="stockName" type="string">
<column name="STOCK_NAME" length="20" not-null="true" unique="true" />
</property>
</class> </hibernate-mapping>

2.配置数据源DataSource

在配置过程中需要一个资源文件,用来存放数据库的详细信息,位于properties包中。

database.properties

 jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/stock?characterEncoding=UTF-8
jdbc.username=root
jdbc.password=123456

DataSource.xml(database包中)

 <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"> <bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>properties/database.properties</value>
</property>
</bean> <bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean> </beans>

3.配置Hibernate的sessionFactory

Hibernate.xml(database包中)

 <?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"> <!-- Hibernate session factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource">
<ref bean="dataSource" />
</property> <property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hbm2ddl.auto">update</prop>
</props>
</property> <property name="mappingResources">
<list>
<value>hibernate/Stock.hbm.xml</value>
</list>
</property> </bean>
</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,将所有的配置文件引入。

 <?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"> <!-- Database Configuration -->
<import resource="classpath:database/DataSource.xml"/>
<import resource="classpath:database/Hibernate.xml"/> <!-- Beans Declaration -->
<import resource="classpath:spring/beans/Stock.xml"/> </beans>

五、测试

 package stock.test;

 import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import stock.bo.StockBo;
import stock.model.Stock; public class Test {
public static void main(String[] args) {
ApplicationContext appContext = new ClassPathXmlApplicationContext("spring/config/BeanLocations.xml"); StockBo stockBo = (StockBo) appContext.getBean("stockBo"); /** insert **/
Stock stock = new Stock();
stock.setStockCode("7668");
stock.setStockName("HAIO");
stockBo.save(stock); /** select **/
Stock stock2 = stockBo.findByStockCode("7668");
System.out.println(stock2); /** update **/
stock2.setStockName("HAIO-1");
stockBo.update(stock2); // /** delete **/
// stockBo.delete(stock2); System.out.println("Done");
}
}

六、总结

1.结合思想:通过DAO继承HibernateDaoSupport来实现spring和hibernate的整合。

2.业务层(service)或业务对象(BO)不应该直接对数据库进行抽插,尽量将所有的有关数据库的操作放在DAO层里面。

七、采用注解

1.在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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"> <context:component-scan base-package="stock">
</context:component-scan>
</beans>

2.修改StockBoImpl.java,增加注解。

首先标识此类是一个bean,使用@Component注解,然后自动装载所需的DAO bean。

 package stock.bo;

 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import stock.dao.StockDao;
import stock.model.Stock; @Component
public class StockBoImpl implements StockBo { @Autowired
private StockDao stockDao; @Override
public void save(Stock stock) {
// TODO Auto-generated method stub
stockDao.save(stock);
} @Override
public void update(Stock stock) {
// TODO Auto-generated method stub
stockDao.update(stock);
} @Override
public void delete(Stock stock) {
// TODO Auto-generated method stub
stockDao.delete(stock);
} @Override
public Stock findByStockCode(String stockCode) {
// TODO Auto-generated method stub
return stockDao.findByStockCode(stockCode);
} }

2.修改StockDaoImpl.java,增加注解。

spring不会为继承HibernateDaoSupport的对象自动装配sessionFacotry的,不能简单的使用如下语句实现注入:

     @Autowired
private SessionFactory sessionFactory;

这样会报错,如下图所示:

笔记59 Spring+Hibernate整合(二)

所以必须调用父类的setSessionFactory方法设置sessionfactory。

 package stock.dao;

 import java.util.List;

 import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Component; import stock.model.Stock; @Component
public class StockDaoImpl extends HibernateDaoSupport implements StockDao { @Autowired
public StockDaoImpl(SessionFactory sessionfactory) {
super.setSessionFactory(sessionfactory);
} @Override
public void save(Stock stock) {
// TODO Auto-generated method stub
getHibernateTemplate().save(stock);
} @Override
public void update(Stock stock) {
// TODO Auto-generated method stub
getHibernateTemplate().update(stock);
} @Override
public void delete(Stock stock) {
// TODO Auto-generated method stub
getHibernateTemplate().delete(stock);
} @Override
public Stock findByStockCode(String stockCode) {
// TODO Auto-generated method stub
@SuppressWarnings("unchecked")
List<Stock> stocks = getHibernateTemplate().find("from Stock where stockCode=?", stockCode);
return stocks.get(0);
} }

3.修改Test里面获取bean的方法。

 StockBo stockBo = (StockBo) appContext.getBean(StockBo.class);