Spring+Hibernate+MySql實例(註解)
在上一篇教程中,我們創建一個簡單的Java項目結構,並演示如何使用Hibernate在Spring框架來在 MySQL數據庫進行數據處理工作(插入,選擇,更新和刪除)。在本教程中,將學習如何使用Spring做同樣的事情,只不過這一次我們使用 Hibernate 的註解方式。
最終項目結構
最終的項目文件結構看起來應該就像下面的圖所示:
1.創建表
在MySQL數據庫中創建一張「stock」表。 SQL語句如下:
CREATE TABLE `yiibai`.`stock` (
`STOCK_ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`STOCK_CODE` varchar(10) NOT NULL,
`STOCK_NAME` varchar(20) NOT NULL,
PRIMARY KEY (`STOCK_ID`) USING BTREE,
UNIQUE KEY `UNI_STOCK_NAME` (`STOCK_NAME`),
UNIQUE KEY `UNI_STOCK_ID` (`STOCK_CODE`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
2. Model & BO & DAO
模型中,業務對象(BO)和數據訪問對象(DAO)模式是有助於清楚地識別層,以避免弄亂項目結構。
Stock Model (Annotation)
Stock模型註解類來存儲庫存數據。
package com.yiibai.stock.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
@Entity
@Table(name = "stock", catalog = "yiibai", uniqueConstraints = {
@UniqueConstraint(columnNames = "STOCK_NAME"),
@UniqueConstraint(columnNames = "STOCK_CODE") })
public class Stock implements java.io.Serializable {
private Integer stockId;
private String stockCode;
private String stockName;
public Stock() {
}
public Stock(String stockCode, String stockName) {
this.stockCode = stockCode;
this.stockName = stockName;
}
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "STOCK\_ID", unique = true, nullable = false)
public Integer getStockId() {
return this.stockId;
}
public void setStockId(Integer stockId) {
this.stockId = stockId;
}
@Column(name = "STOCK\_CODE", unique = true, nullable = false, length = 10)
public String getStockCode() {
return this.stockCode;
}
public void setStockCode(String stockCode) {
this.stockCode = stockCode;
}
@Column(name = "STOCK\_NAME", unique = true, nullable = false, length = 20)
public String getStockName() {
return this.stockName;
}
public void setStockName(String stockName) {
this.stockName = stockName;
}
@Override
public String toString() {
return "Stock \[stockCode=" + stockCode + ", stockId=" + stockId
+ ", stockName=" + stockName + "\]";
}
}
Stock Business Object (BO))
Stock 業務對象(BO)接口和實現,它是用來存儲項目的業務功能,真正的數據庫操作(CRUD)的工作不參與這一個類,而是用一個DAO(StockDao)類來做到這一點。
package com.yiibai.stock.bo;
import com.yiibai.stock.model.Stock;
public interface StockBo {
void save(Stock stock);
void update(Stock stock);
void delete(Stock stock);
Stock findByStockCode(String stockCode);
}
使這個類中的 Spring IoC容器的 bean「stockBo」自動裝配庫存DAO類。
package com.yiibai.stock.bo.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yiibai.stock.bo.StockBo;
import com.yiibai.stock.dao.StockDao;
import com.yiibai.stock.model.Stock;
@Service("stockBo")
public class StockBoImpl implements StockBo{
@Autowired
StockDao stockDao;
public void setStockDao(StockDao stockDao) {
this.stockDao = stockDao;
}
public void save(Stock stock){
stockDao.save(stock);
}
public void update(Stock stock){
stockDao.update(stock);
}
public void delete(Stock stock){
stockDao.delete(stock);
}
public Stock findByStockCode(String stockCode){
return stockDao.findByStockCode(stockCode);
}
}
Stock Data Access Object
Stock DAO接口和實現。在上一個教程中,DAO類是直接擴展「HibernateDaoSupport「。但註釋方式不可能做到這一點,因爲沒有辦法從DAO類會話到工廠bean自動裝配。解決方法是創建一個自定義類(CustomHibernateDaoSupport),並擴展了「HibernateDaoSupport」和自動裝配會話工廠,DAO類擴展了這個類。
package com.yiibai.stock.dao;
import com.yiibai.stock.model.Stock;
public interface StockDao {
void save(Stock stock);
void update(Stock stock);
void delete(Stock stock);
Stock findByStockCode(String stockCode);
}
package com.yiibai.util;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public abstract class CustomHibernateDaoSupport extends HibernateDaoSupport
{
@Autowired
public void anyMethodName(SessionFactory sessionFactory)
{
setSessionFactory(sessionFactory);
}
}
package com.yiibai.stock.dao.impl;
import java.util.List;
import org.springframework.stereotype.Repository;
import com.yiibai.stock.dao.StockDao;
import com.yiibai.stock.model.Stock;
import com.yiibai.util.CustomHibernateDaoSupport;
@Repository("stockDao")
public class StockDaoImpl extends CustomHibernateDaoSupport implements StockDao{
public void save(Stock stock){
getHibernateTemplate().save(stock);
}
public void update(Stock stock){
getHibernateTemplate().update(stock);
}
public void delete(Stock stock){
getHibernateTemplate().delete(stock);
}
public Stock findByStockCode(String stockCode){
List list = getHibernateTemplate().find(
"from Stock where stockCode=?",stockCode
);
return (Stock)list.get(0);
}
}
5.資源配置
建立一個目錄resources在「project_name/main/java/',它將用於存儲Spring,Hibernate等配置文件。
Spring Configuration
數據庫關聯….
創建一個屬性文件(database.properties)來存放數據庫的詳細信息,把它放到「resources/properties」文件夾中。 一個很好的做法是將數據庫信息和Spring bean配置在不同的文件。
database.properties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/yiibai
jdbc.username=root
jdbc.password=password
創建一個「dataSource」 bean配置文件(DataSource.xml)存放數據庫信息,並從database.properties導入的屬性,把它放到「resources/database」文件夾中。
DataSource.xml
Hibernate related….
創建一個會話工廠bean的配置文件(Hibernate.xml),把它放到「resources/database」文件夾中。在註釋必須使用AnnotationSessionFactoryBean 來代替 LocalSessionFactoryBean,並註明您的註解模型類在「annotatedClasses」屬性,而不是'mappingResources'屬性。
Hibernate.xml
<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>
</props>
</property>
<property name="annotatedClasses">
<list>
<value>com.yiibai.stock.model.Stock</value>
</list>
</property>
</bean>
導入所有的 Spring bean 配置文件合併爲一個文件(BeanLocations.xml),把它放到「resources/config」文件夾。
BeanLocations.xml
導入Spring數據庫配置並使用 Spring自動掃描功能。
<!-- Database Configuration -->
<import resource="../database/DataSource.xml"/>
<import resource="../database/Hibernate.xml"/>
<!-- Auto scan the components -->
<context:component-scan
base-package="com.yiibai.stock" />
6. 運行它
把所有的文件和配置整合,運行它。
package com.yiibai.common;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.yiibai.stock.bo.StockBo;
import com.yiibai.stock.model.Stock;
public class App
{
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");
}
}
輸出結果:
Hibernate: insert into yiibai.stock (STOCK_CODE, STOCK_NAME) values (?, ?)
Hibernate: select stock0_.STOCK_ID as STOCK1_0_, stock0_.STOCK_CODE as STOCK2_0_, stock0_.STOCK_NAME as STOCK3_0_ from yiibai.stock stock0_ where stock0_.STOCK_CODE=?
Stock [stockCode=7667, stockId=3, stockName=HAIO]
Hibernate: update yiibai.stock set STOCK_CODE=?, STOCK_NAME=? where STOCK_ID=?
Hibernate: delete from yiibai.stock where STOCK_ID=?
Done
總結
所有的Spring,Hibernate相關類和配置文件都進行註解,它只是保留在XML文件中的數據庫的詳細信息。就個人而言,我不使用太多的註釋功能,因爲在某種程度上可能需要一些解決方法,像上面的「CustomHibernateDaoSupport'擴展'HibernateDaoSupport」。 在Spring和Hibernate的XML文件的成熟是一個更優的選擇。