iT邦幫忙

DAY 8
1

無痛學習SpringMVC與Spring Security系列 第 8

[Model]Spring Hibernate/JPA EnitityManagerFacotry Java Config設定

要實現CRUD,首先需要完成DAO這塊coding,之後再搭配表單與Controller來進行相關操作,資料庫選擇MySQL,ORM部分選用Hibernate/JPA(Java Persistence API),今天要分享Hibernate/JPA Java Config Class如何撰寫,首先加入相關的Dependency(Springframework ORM及Hibernate)於pom.xml

...
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-orm</artifactId>
	<version>${spring.version}</version>
</dependency>
<dependency>
	<groupId>org.hibernate</groupId>
	<artifactId>hibernate-entitymanager</artifactId>
	<version>${hibernate.version}</version>
</dependency>
<dependency>
	<groupId>org.hibernate</groupId>
	<artifactId>hibernate-core</artifactId>
	<version>${hibernate.version}</version>
</dependency>
<dependency>
	<groupId>org.hibernate.javax.persistence</groupId>
	<artifactId>hibernate-jpa-2.1-api</artifactId>
	<version>1.0.0.Final</version>
</dependency>
....

<properties>
 	<hibernate.version>4.3.6.Final</hibernate.version>
        <spring.version>4.0.7.RELEASE</spring.version>
        ...
</properties>

接著新增一 POJO並使用JPA Annotation,有人習慣將Annotation放在getter的地方,有人放在屬性(field)的地方,看個人習慣。

@Entity
//預設Table name即為class name, 如果要指定table name,則需加入@Table(name="tablename")
public class DCN implements Serializable{
	
	private static final long serialVersionUID = 3716247587694820755L;
	public DCN(){
		
	}
	
	@Id //@Id代表這個屬性是primary key
	@GeneratedValue(generator="uuid")//新增一筆資料時產生key的方法,或稱為generator 
	@GenericGenerator(name="uuid", strategy="uuid")//指定uuid演算法產生primary key 
	private String prikey;
	@Column //@Column代表屬性要persist到資料庫,預設資料庫欄位名稱就是該變數
	private String category;
	private Integer serialNumber;
	@Column(name="no") //也可以另外指定資料庫實際欄位名稱
	private String no;
	private Integer rev;
	@Column
	private String issueDate;
	@Column
	private String completedDate;
	@Transient //代表此屬性不persist到資料庫
	private MultipartFile uploadFile;

	//getter以及setter省略
}

接著refactor之前的ServiceConfig為PersistenceConfig,裡面已經有Datasource,記得把database的url、username及password寫入jdbc.properties檔,在Spring專案要導入JPA,我們需要org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean來設定Entity Manager Factory(對應到Hibernate的Session Factory)相關參數,如指定Hibernate為實作JPA的Provider,同時我們也需要org.springframework.transaction.PlatformTransactionManager來管理Transaction,相關Bean Code如下

package tw.blogger.springtech.springmvc.config;

import javax.persistence.EntityManagerFactory;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.hibernate4.HibernateExceptionTranslator;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.jolbox.bonecp.BoneCPDataSource;


@PropertySource(value="classpath:jdbc.properties")
@EnableTransactionManagement
@Configuration
public class PersistenceConfig {
	
	@Autowired
	Environment env; //Environment物件存放Profile以及Property Source
	
	@Bean
	public BoneCPDataSource dataSource(){
		BoneCPDataSource datasource = new BoneCPDataSource();
		/*以下就設定一些dataSource的參數,url, username及password key/value pair
		 * 另外存在jdbc.properties檔裡,再用eng.getProperty("key")取得value,
		 */
        datasource.setDriverClass("com.mysql.jdbc.Driver");
        datasource.setJdbcUrl(env.getProperty("jdbc.url"));
        datasource.setUsername(env.getProperty("jdbc.username"));
        datasource.setPassword(env.getProperty("jdbc.password"));
        datasource.setIdleConnectionTestPeriodInMinutes(60);
        datasource.setIdleMaxAgeInMinutes(420);
        datasource.setMaxConnectionsPerPartition(30);
        datasource.setMinConnectionsPerPartition(10);
        datasource.setPartitionCount(3);
        datasource.setAcquireIncrement(5);
        datasource.setStatementsCacheSize(100);
       
 
        return datasource;
	}
	
	@Bean
	public JdbcTemplate jdbcTemplate(){
		return new JdbcTemplate(dataSource()); //Dependency Injection只需要呼叫方法即可
	}
	
	@Bean
	public LocalContainerEntityManagerFactoryBean entityManagerFactory(){
		LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
		//new 一個entity factory
		HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();//new一個實作JPA的vendor
		vendorAdapter.setGenerateDdl(true);
		vendorAdapter.setShowSql(true); //設定showSQL
		
		factory.setDataSource(dataSource()); //設定datasource
		factory.setJpaVendorAdapter(vendorAdapter); //設定Implement JPA vendor 
		factory.setPackagesToScan("tw.blogger.springtech.springmvc.model"); //設定Entity package位置
		
		factory.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver());
		return factory;
		
	}
	
	@Bean
	public PlatformTransactionManager transactionManager(){
		EntityManagerFactory factory = entityManagerFactory().getObject();
		return new JpaTransactionManager(factory);
//JpaTransactionManager需要注入EntityManagerFactory的Instance
	}
	
	@Bean
    public HibernateExceptionTranslator hibernateExceptionTranslator(){
        return new HibernateExceptionTranslator();
    }

}

今天先到這邊,明天再進行後續分享,這邊以後可能會稍微慢一點,JPA相關我也是邊看邊學(本來就夠慢了嗎!?)。


上一篇
[View]Sitemesh 3介紹與設定(含Spring Security簡易初始化)
下一篇
[Model]Spring MVC Repository及Service Annotation介紹
系列文
無痛學習SpringMVC與Spring Security31

尚未有邦友留言

立即登入留言