Spring+Hibernate+MySql實例(註解)

在上一篇教程中,我們創建一個簡單的Java項目結構,並演示如何使用Hibernate在Spring框架來在 MySQL數據庫進行數據處理工作(插入,選擇,更新和刪除)。在本教程中,將學習如何使用Spring做同樣的事情,只不過這一次我們使用 Hibernate 的註解方式。

最終項目結構


最終的項目文件結構看起來應該就像下面的圖所示:
Spring+Hibernate+MySql實例(註解)

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



properties/database.properties






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文件的成熟是一個更優的選擇。

代碼下載  -  http://pan.baidu.com/s/1bewLiu