スプリングMVC+Spring+Hibernate+PostgreSQLフレームの集積とマルチテナント(一)
72328 ワード
スプリングMVC+Spring+Hibernate+PostgreSQLフレームの集積とマルチテナント
本論では、Mavenでspring MVC+Spring+Hibernateのwebフレームを構築し、postgreSQLをデータベースとし、データソースはdbcpを採用する.建てられた考えは以下の通りです. 1.Mavenプロジェクトを作成し、pom.xmlファイル を作成する..Spring構成 を導入する. 3.ヒベルナ構成 4.マルチテナント実現 .データベース設計 .サービスentityエンティティ を生成する..dao層 を作成する. 9.service層 を作成する. 10.テストspringとhibernate統合 11.Spring MVC を導入する..配置web.xml容器 .制御層controler を作成する..視聴層 を作成する. 15.サーバ試験の配置 1.Mavenプロジェクトを作成し、pom.xmlファイルを作成する
pomファイルの内容は以下の通りです.
設定ファイルを作成し、設定ファイルをsrc/main/resourceリソースディレクトリの下に置く(以下同じ).プロジェクトに必要な配置情報config.properties
Hbernateの構成は主にデータソースdbcpを配置し、Session Factoryを配置し、事務管理器を配置し、そのspring-hibernate.xmlファイルは以下の通りである.
第3ステップでは、マルチテナントを配置し、2つのタイプのTenantIdResolaverとSchemaBasedMulti TenantConnection Providerに関連する:
TenantIdResolaverの種類は以下の通りです.
PostgreSQLでdatabaseを作成し、exampledbと呼ばれます.schemaを創建して、myschemaといいます.mychemaでテーブルを作成し、ステートメントを作成します.
8.1 Daoインターフェース
Dao層とService層は必ず面相インターフェースプログラミングの思想を採用しています.だから、まず一般的なDaoインターフェース、GenericDao.javaを定義します.
9.1 serviceインターフェースを作成する
私たちはSrc/test/javaでテストクラスを作成できます.上記の配置をテストします.もしテストが成功すれば、基本的に成功しました.
本論では、Mavenでspring MVC+Spring+Hibernateのwebフレームを構築し、postgreSQLをデータベースとし、データソースはdbcpを採用する.建てられた考えは以下の通りです.
pomファイルの内容は以下の通りです.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>cn.ac.bccgroupId>
<artifactId>maqueartifactId>
<packaging>warpackaging>
<version>0.0.1-SNAPSHOTversion>
<name>maque Maven Webappname>
<url>http://maven.apache.orgurl>
<repositories>
<repository>
<id>mavenid>
<name>Maven Repository Switchboardname>
<layout>defaultlayout>
<url>http://repo1.maven.org/maven2url>
<snapshots>
<enabled>falseenabled>
snapshots>
repository>
<repository>
<id>alibaba-opensourceid>
<name>alibaba-opensourcename>
<url>http://code.alibabatech.com/mvn/releases/url>
<layout>defaultlayout>
repository>
<repository>
<id>alibaba-opensource-snapshotid>
<name>alibaba-opensource-snapshotname>
<url>http://code.alibabatech.com/mvn/snapshots/url>
<layout>defaultlayout>
repository>
repositories>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<spring.version>4.2.1.RELEASEspring.version>
properties>
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.11version>
<scope>testscope>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>servlet-apiartifactId>
<version>3.0-alpha-1version>
<scope>providedscope>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>jstlartifactId>
<version>1.2version>
dependency>
<dependency>
<groupId>javax.servlet.jspgroupId>
<artifactId>jsp-apiartifactId>
<version>2.2.1-b03version>
<scope>providedscope>
dependency>
<dependency>
<groupId>commons-fileuploadgroupId>
<artifactId>commons-fileuploadartifactId>
<version>1.2.2version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>1.1.26version>
dependency>
<dependency>
<groupId>org.codehaus.jacksongroupId>
<artifactId>jackson-mapper-aslartifactId>
<version>1.9.11version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
<version>2.7.4version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.7.4version>
dependency>
<dependency>
<groupId>org.aspectjgroupId>
<artifactId>aspectjweaverartifactId>
<version>1.7.1version>
dependency>
<dependency>
<groupId>org.hibernategroupId>
<artifactId>hibernate-coreartifactId>
<version>4.2.5.Finalversion>
dependency>
<dependency>
<groupId>org.hibernategroupId>
<artifactId>hibernate-entitymanagerartifactId>
<version>4.2.5.Finalversion>
dependency>
<dependency>
<groupId>org.hibernategroupId>
<artifactId>hibernate-ehcacheartifactId>
<version>4.2.5.Finalversion>
dependency>
<dependency>
<groupId>org.hibernate.javax.persistencegroupId>
<artifactId>hibernate-jpa-2.0-apiartifactId>
<version>1.0.1.Finalversion>
dependency>
<dependency>
<groupId>postgresqlgroupId>
<artifactId>postgresqlartifactId>
<version>9.1-901-1.jdbc4version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-beansartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-expressionartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-ormartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>commons-dbcpgroupId>
<artifactId>commons-dbcpartifactId>
<version>1.4version>
dependency>
dependencies>
<build>
<finalName>maquefinalName>
<plugins>
<plugin>
<artifactId>maven-war-pluginartifactId>
plugin>
<plugin>
<artifactId>maven-compiler-pluginartifactId>
<configuration>
<source>1.8source>
<target>1.8target>
configuration>
plugin>
plugins>
build>
project>
2.Spring配置の導入設定ファイルを作成し、設定ファイルをsrc/main/resourceリソースディレクトリの下に置く(以下同じ).プロジェクトに必要な配置情報config.properties
#PostgreSQL
jdbc.driver=org.postgresql.Driver
jdbc.url=jdbc:postgresql://localhost:5432/exampledb
jdbc.username=postgres
jdbc.password=123abc
validationQuery=SELECT 1
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.hbm2ddl.auto=update
hibernate.show_sql=true
hibernate.format_sql=true
sessionInfoName=sessionInfo
2.1 Spring配置
<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" xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
">
<context:property-placeholder location="classpath:config.properties" />
<context:component-scan base-package="cn.ac.bcc.maque.dao,cn.ac.bcc.maque.service" />
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor">bean>
beans>
2.2ログファイルのプロファイルLog 4 jを導入するlog4j.rootLogger=INFO,A1,R
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.Target=System.out
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=[%c]%m%n
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=sshf.log
log4j.appender.R.MaxFileSize=10MB
log4j.appender.R.Threshold=ALL
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH\:mm\:ss,SSS}][%c]%m%n
3.Hibernate配置Hbernateの構成は主にデータソースdbcpを配置し、Session Factoryを配置し、事務管理器を配置し、そのspring-hibernate.xmlファイルは以下の通りである.
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="username" value="${jdbc.username}">property>
<property name="password" value="${jdbc.password}">property>
<property name="url" value="${jdbc.url}">property>
<property name="driverClassName" value="${jdbc.driver}" >property>
bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<map>
<entry key="hibernate.dialect" value="${hibernate.dialect}">entry>
<entry key="hibernate.show_sql" value="${hibernate.show_sql}">entry>
<entry key="hibernate.format_sql" value="${hibernate.format_sql}">entry>
<entry key="hibernate.current_session_context_class" value="org.springframework.orm.hibernate4.SpringSessionContext">entry>
<entry key="hibernate.multiTenancy" value="SCHEMA">entry>
<entry key="hibernate.tenant_identifier_resolver" value="cn.ac.bcc.maque.dao.impl.TenantIdResolver">entry>
<entry key="hibernate.multi_tenant_connection_provider" value="cn.ac.bcc.maque.dao.impl.SchemaBasedMultiTenantConnectionProvider">entry>
map>
property>
<property name="packagesToScan">
<list>
<value>cn.ac.bcc.maque.modelvalue>
list>
property>
bean>
<bean name="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory">property>
bean>
<tx:annotation-driven transaction-manager="transactionManager" />
beans>
4.マルチテナント実現第3ステップでは、マルチテナントを配置し、2つのタイプのTenantIdResolaverとSchemaBasedMulti TenantConnection Providerに関連する:
TenantIdResolaverの種類は以下の通りです.
package cn.ac.bcc.maque.dao.impl;
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
import cn.ac.bcc.maque.model.Login;
public class TenantIdResolver implements CurrentTenantIdentifierResolver {
@Override
public String resolveCurrentTenantIdentifier() {
return Login.getTenantId();
}
@Override
public boolean validateExistingCurrentSessions() {
return true;
}
}
SchemaBasedMulti TenantConnection Providerの種類は以下の通りです.package cn.ac.bcc.maque.dao.impl;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;
import org.apache.commons.dbcp.BasicDataSource;
import org.hibernate.HibernateException;
import org.hibernate.service.jdbc.connections.internal.DatasourceConnectionProviderImpl;
import org.hibernate.service.jdbc.connections.spi.MultiTenantConnectionProvider;
import org.hibernate.service.spi.Configurable;
import org.hibernate.service.spi.Stoppable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository("schemaBasedMultiTenantConnectionProvider")
public class SchemaBasedMultiTenantConnectionProvider implements MultiTenantConnectionProvider,Stoppable,Configurable {
/**
*
*/
private static final long serialVersionUID = -5379376698684861045L;
private final DatasourceConnectionProviderImpl connectionProvider = new DatasourceConnectionProviderImpl();
public void configure(Map configurationValues) {
this.connectionProvider.configure(configurationValues);
}
public Connection getAnyConnection() throws SQLException {
return connectionProvider.getConnection();
}
public void releaseAnyConnection(Connection connection) throws SQLException {
connectionProvider.closeConnection(connection);
}
public Connection getConnection(String tenantIdentifier) throws SQLException {
final Connection connection = getAnyConnection();
try {
// connection.createStatement().execute("USE " + tenantIdentifier);
connection.createStatement().execute("set schema '" + tenantIdentifier + "'");
} catch (SQLException e) {
throw new HibernateException("Could not alter JDBC connection to specified schema [" + tenantIdentifier + "]", e);
}
return connection;
}
public void releaseConnection(String tenantIdentifier, Connection connection) throws SQLException {
try {
connection.createStatement().execute("USE test");
} catch (SQLException e) {
throw new HibernateException("Could not alter JDBC connection to specified schema [" + tenantIdentifier + "]", e);
}
connectionProvider.closeConnection(connection);
}
public boolean supportsAggressiveRelease() {
return this.connectionProvider.supportsAggressiveRelease();
}
public void stop() {
this.connectionProvider.stop();
}
public boolean isUnwrappableAs(Class unwrapType) {
return this.connectionProvider.isUnwrappableAs(unwrapType);
}
public T unwrap(Class unwrapType) {
return this.connectionProvider.unwrap(unwrapType);
}
}
5.データベース設計PostgreSQLでdatabaseを作成し、exampledbと呼ばれます.schemaを創建して、myschemaといいます.mychemaでテーブルを作成し、ステートメントを作成します.
create database exampledb;
create schema myschema;
set schema 'myschema';
create table user_info(id varchar(200),name varchar(50),signup_date
date);
6.業務entityエンティティを生成するpackage cn.ac.bcc.maque.model;
// Generated 2016-5-11 17:35:53 by Hibernate Tools 4.3.1.Final
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* User generated by hbm2java
*/
@Entity
@Table(name="user_info")
public class User implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = -5656136547913487597L;
@Id
@Column(name="id")
private String id;
@Column(name="name")
private String name;
@Column(name="signup_date")
private Date signupDate;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Date getSignupDate() {
return this.signupDate;
}
public void setSignupDate(Date signupDate) {
this.signupDate = signupDate;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public boolean equals(Object other) {
if ((this == other))
return true;
if ((other == null))
return false;
if (!(other instanceof User))
return false;
User castOther = (User) other;
return ((this.getName() == castOther.getName()) || (this.getName() != null && castOther.getName() != null
&& this.getName().equals(castOther.getName())))
&& ((this.getSignupDate() == castOther.getSignupDate())
|| (this.getSignupDate() != null && castOther.getSignupDate() != null
&& this.getSignupDate().equals(castOther.getSignupDate())));
}
public int hashCode() {
int result = 17;
result = 37 * result + (getName() == null ? 0 : this.getName().hashCode());
result = 37 * result + (getSignupDate() == null ? 0 : this.getSignupDate().hashCode());
return result;
}
}
8.ダオ層を作成する8.1 Daoインターフェース
Dao層とService層は必ず面相インターフェースプログラミングの思想を採用しています.だから、まず一般的なDaoインターフェース、GenericDao.javaを定義します.
package cn.ac.bcc.maque.dao;
import java.io.Serializable;
import java.util.List;
public interface GenericDao <T, PK extends Serializable>{
T load(PK id);
T get(PK id);
List findAll();
void persist(T entity);
PK save(T entity);
void saveOrUpdate(T entity);
void delete(PK id);
void flush();
}
具体的なUserDao.javaインターフェースを再定義します.package cn.ac.bcc.maque.dao;
import cn.ac.bcc.maque.model.User;
public interface UserDao extends GenericDao<User,String>{
}
8.2 Dao層実現package cn.ac.bcc.maque.dao.impl;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import cn.ac.bcc.maque.dao.UserDao;
import cn.ac.bcc.maque.model.User;
@Repository("userDao")
@Transactional
public class UserDaoImpl implements UserDao {
@Autowired
private SessionFactory sessionFactory;
private Session currentSession(){
Session session = sessionFactory.getCurrentSession();
return session;
}
@Override
public User load(String id) {
// TODO Auto-generated method stub
return null;
}
@Override
public User get(String id) {
return (User) currentSession().get(User.class,id);
}
@SuppressWarnings("unchecked")
@Override
public List findAll() {
List users = currentSession().createQuery("from User user").list();
return users;
}
@Override
public void persist(User entity) {
// TODO Auto-generated method stub
}
@Override
public String save(User entity) {
return (String) currentSession().save(entity);
}
@Override
public void saveOrUpdate(User entity) {
// TODO Auto-generated method stub
}
@Override
public void delete(String id) {
currentSession().delete(currentSession().get(User.class, id));
}
@Override
public void flush() {
// TODO Auto-generated method stub
}
}
9.service層を作成する9.1 serviceインターフェースを作成する
package cn.ac.bcc.maque.service;
import java.util.List;
import cn.ac.bcc.maque.model.User;
public interface UserService {
User load(String id);
User get(String id);
List<User> findAll();
void persist(User entity);
String save(User entity);
void saveOrUpdate(User entity);
void delete(String id);
void flush();
}
9.2 service層実現類package cn.ac.bcc.maque.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.ac.bcc.maque.dao.UserDao;
import cn.ac.bcc.maque.model.User;
import cn.ac.bcc.maque.service.UserService;
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
public User load(String id) {
// TODO Auto-generated method stub
return null;
}
@Override
public User get(String id) {
return userDao.get(id);
}
@Override
public List findAll() {
return userDao.findAll();
}
@Override
public void persist(User entity) {
// TODO Auto-generated method stub
}
@Override
public String save(User entity) {
return userDao.save(entity);
}
@Override
public void saveOrUpdate(User entity) {
// TODO Auto-generated method stub
}
@Override
public void delete(String id) {
userDao.delete(id);
}
@Override
public void flush() {
// TODO Auto-generated method stub
}
}
10.springとhibernateの整合をテストします.私たちはSrc/test/javaでテストクラスを作成できます.上記の配置をテストします.もしテストが成功すれば、基本的に成功しました.
package cn.ac.bcc.maque.service;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import org.apache.log4j.Logger;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.alibaba.fastjson.JSON;
import cn.ac.bcc.maque.model.Login;
import cn.ac.bcc.maque.model.User;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:spring.xml",
"classpath:spring-hibernate.xml"})
public class TestUserService {
private static final Logger LOGGER = Logger
.getLogger(TestUserService.class);
@Autowired
private UserService userService;
// @Test
// public void save(){
// User user = new User();
// user.setId(UUID.randomUUID().toString());
// user.setName("ada");
// user.setSignupDate(new Date());
// String id = userService.save(user);
// LOGGER.info(JSON.toJSON(id));
// }
//
// @Test
// public void findAll(){
// List users = userService.findAll();
// for(User u:users){
// LOGGER.info(u.getId()+"\t"+u.getName()+"\t"+u.getSignupDate());
// }
// }
@Test
public void saveByTenantId(){
Login.setTenantId("myschema");
User user = new User();
user.setId(UUID.randomUUID().toString());
user.setName("ada");
user.setSignupDate(new Date());
String id = userService.save(user);
LOGGER.info(JSON.toJSON(id));
}
}
未完了...-11.Spring MVC-12.プロファイルweb.xml容器-13.制御層controlller-14を作成します.视レイヤー-15を作成します.配置サーバテスト