<file_sep>## OOAD Project

- 14302010038 王翀
-  14302010049 蒲实

1. 架构
- PJ实现了数据层和业务层，主要使用到Spring和Hibernate
- 数据层使用Hibernate封装，实现在`src\common`和`src\model`中
    - 其中`model`实现了数据库的ORM映射
    - `common`封装了基本的数据库操作，对外提供操作的接口
- 业务层实现在`src\service`中，对于每个用例提供了操作的接口，最后的测试也是在这里提供的接口上进行测试
    - 业务层对数据库的操作完全通过数据层提供的接口实现

---

2. 数据层 `src\common`
    - ORM `src\model` 
        - `Company`：企业
        - `RiskCheckTemplateItem`：检查条目，为某一具体的检查条目
        - `RiskCheckTemplate`：检查模版，包括了一个检查项的集合
        - `RiskCheckPlan`：检查计划，包括了对应了检查模版
        - `RiskCheck`：检查任务，一次检查包括了对应的企业、计划，并包含了具体的检查条目
        - `RiskCheckItem`：企业可见的某一具体的检查条目，企业可以对其录入进度
        - 其中`eunums`有`Company`和`RiskCheck`的`state`的枚举，以及相应的数据库转换器类
    - 数据库操作`src\common`
        - `src\common\IPersistenceManager`提供对数据库所有操作的接口
        - `src\common\PMHibernateImpl`为上述接口的实现
    - 数据库 Mysql
        - host : 192.168.127.12:3306
        - username: kadoufall
        - password: <PASSWORD>
        - table : ooad1
        
---

3. 业务逻辑层 `src\service`
    - `ICompanyService` ： 封装了企业的相关操作
    - `IRiskCheckTemplateItemService` ： 封装了具体的检查条目的添加和搜索
    - `IRiskCheckTemplateService` ： 封装了检查模版的添加、编辑、搜索和添加具体的检查条目
    - `IRiskCheckPlanService` ： 封装了检查计划的添加、编辑、搜索和删除
    - `IRiskCheckService` ： 封装了分配一次任务的操作
    
---

4. JUnit单元测试  `src-test`
    - 测试的内容标注在注释中

---

5. 项目配置 `src-config`
    - 配置数据源、`Hibernate`以及数据层和业务层的位置

---

PS ： PJ的数据库持久化参考了张天戈老师的demo
<file_sep>package service;

import model.RiskCheckTemplateItem;

import java.util.List;

public interface IRiskCheckTemplateItemService {
    RiskCheckTemplateItem add(String name, String content);
    List<RiskCheckTemplateItem> search(String input);
}
<file_sep>package model;

import common.BaseModelObject;
import common.IPersistenceManager;

import javax.persistence.*;
import java.util.Set;

@Entity
@Table(name = "riskchecktemplate")
public class RiskCheckTemplate extends BaseModelObject {

    private String name;
    private String summary;
    private Set<RiskCheckTemplateItem> riskCheckTemplateItems;


    public static RiskCheckTemplate create(IPersistenceManager pm, String name, String summary, Set<RiskCheckTemplateItem> riskCheckTemplateItems) {
        RiskCheckTemplate re = new RiskCheckTemplate();
        re.setName(name);
        re.setSummary(summary);
        re.setRiskCheckTemplateItems(riskCheckTemplateItems);

        pm.save(re);
        return re;
    }

    @Column(name = "name", nullable = false, length = 45)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Column(name = "summary", nullable = false, length = 100)
    public String getSummary() {
        return summary;
    }

    public void setSummary(String summary) {
        this.summary = summary;
    }

    @Access(AccessType.PROPERTY)
    @ManyToMany(cascade = {
                    CascadeType.DETACH,
                    CascadeType.MERGE,
                    CascadeType.REFRESH,
                    CascadeType.PERSIST
                }, fetch = FetchType.LAZY)
    public Set<RiskCheckTemplateItem> getRiskCheckTemplateItems() {
        return riskCheckTemplateItems;
    }

    public void setRiskCheckTemplateItems(Set<RiskCheckTemplateItem> riskCheckTemplateItems) {
        this.riskCheckTemplateItems = riskCheckTemplateItems;
    }

}
<file_sep>package service;

import model.Company;
import model.RiskCheckItem;
import model.enums.CompanyState;

import java.util.Set;

public interface ICompanyService {
    void finishOneCheckRiskItem(RiskCheckItem riskCheckItem, String result);

    Company add(String code, String name, CompanyState state, String organizationalCode,
                String industryGenera, String industry, String businessCategory, String contact, String contactNumber);

    void delete(Company company);

    Company edit(Company company, String code, String name, CompanyState state, String organizationalCode,
                 String industryGenera, String industry, String businessCategory, String contact, String contactNumber);

    Set<RiskCheckItem> getAllRiskCheckItem(Company company);

}
<file_sep>package model;

import common.BaseModelObject;
import common.IPersistenceManager;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;

@Entity
@Table(name = "riskchecktemplateitem")
public class RiskCheckTemplateItem extends BaseModelObject {
    private String name;
    private String content;

    public static RiskCheckTemplateItem create(IPersistenceManager pm, String name, String content) {
        RiskCheckTemplateItem re = new RiskCheckTemplateItem();
        re.setName(name);
        re.setContent(content);

        pm.save(re);
        return re;
    }


    @Column(name = "name", nullable = false, length = 100)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Column(name = "content", nullable = false, length = 100)
    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}
<file_sep>import common.BasePersistenceTest;
import common.IPersistenceManager;
import model.*;
import model.enums.CompanyState;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import service.IRiskCheckService;

import java.util.HashSet;

import static org.junit.Assert.*;

/**
 * Created by asus on 2017/6/20.
 */
public class RiskCheckServiceTest extends BasePersistenceTest {
    @Autowired
    IRiskCheckService service;

    @Autowired
    IPersistenceManager pm;

    @Before
    public void setUp() throws Exception {
    }

    @After
    public void tearDown() throws Exception {
        pm.deleteAll(Company.class);
        pm.deleteAll(RiskCheck.class);
        pm.deleteAll(RiskCheckPlan.class);
        pm.deleteAll(RiskCheckTemplate.class);
        pm.deleteAll(RiskCheckTemplateItem.class);

    }

    // 测试将一个plan发放给一个company，与其他测试中的add类似
    @Test
    public void add() throws Exception {
        Company company = Company.create(pm, "", "", CompanyState.NORMAL, "", "", "", "", "", "" );
        RiskCheckTemplate template = RiskCheckTemplate.create(pm, "template","", new HashSet<RiskCheckTemplateItem>());
        RiskCheckPlan plan = RiskCheckPlan.create(pm, "plan", template);
        RiskCheck task = service.add(company, plan, "2017-06-30");

        RiskCheck result = pm.get(RiskCheck.class, task.getId());
        assertNotNull(result);


    }


}<file_sep>/*
 * Copyright 2006 Centenum Software Solutions, Inc. All rights reserved.
 * CENTENUM PROPRIETARY/CONFIDENTIAL. 
 */
package common;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.orm.hibernate4.support.HibernateDaoSupport;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.List;

/**
 * A hibernate/Spring framework implementation for IObjectFactory
 * 
 * @author <NAME>
 * 
 */
@Transactional
public class PMHibernateImpl extends HibernateDaoSupport implements IPersistenceManager, BeanFactoryAware {

	public static IPersistenceManager getInstance() {
		ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
				new String[] { "HibernateApplicationContext.xml" });
		return (IPersistenceManager) ((BeanFactory) appContext)
				.getBean("objectFactory");
	}

	BeanFactory beanFactory;

	private Class getImplClass(Class clazz) {
		if (clazz.isInterface()) {
			return beanFactory.getBean(getBeanID(clazz)).getClass();
		} else {
			return clazz;
		}
	}

	private String getBeanID(Class clazz) {
		int pos = clazz.getName().lastIndexOf('.') + 1;
		return clazz.getName().substring(pos);
	}

	@Override
	public IModelObject create(Class clazz) {
		IModelObject bean = (IModelObject) beanFactory
				.getBean(getBeanID(clazz));
		return bean;
	}

	@Override
	public IModelObject get(Class clazz, Serializable id) {
		IModelObject bean = (IModelObject) getHibernateTemplate().get(
				getImplClass(clazz), id);
		return bean;
	}

	@Override
	public IModelObject load(IModelObject e) {
		getHibernateTemplate().load(e, e.getId());
		return e;
	}

	@Override
	public void delete(IModelObject obj) {
		getHibernateTemplate().delete(obj);
	}

	@Override
	public IModelObject save(IModelObject obj) {
		getHibernateTemplate().saveOrUpdate(obj);
		return obj;
	}

	@Override
	public IModelObject create(IModelObject obj) {
		getHibernateTemplate().saveOrUpdate(obj);
		return obj;
	}

	@Override
	public <T extends IModelObject> List<T> findByProperty(Class<T> clazz, String propertyName, String value) {
		System.out.println("from " + clazz.getName() +" clazz where clazz."+propertyName+" like '% :"+propertyName+"%'");
		return (List<T>)getHibernateTemplate().find("from " + clazz.getName() +" clazz where clazz."+propertyName+" like '%"+value+"%'");
	}

	@Override
	public <T extends IModelObject> List<T> findByFussyValue(Class<T> clazz, String value) {
		Field[] fields = clazz.getDeclaredFields();
		StringBuffer hql = new StringBuffer();
		hql.append("from " + clazz.getName() +" clazz where ");
		//String sql = "from " + clazz.getName() +" clazz where ";clazz."+propertyName+" like '%"+value+"%'"


		if(fields[0].getType().getSimpleName().equals("String"))
			hql.append("clazz."+fields[0].getName()+" like '%"+value+"%'");
		for (int i = 1; i<fields.length; i++) {

			if(fields[i].getType().getSimpleName().equals("String"))
				hql.append(" or clazz."+fields[i].getName()+" like '%"+value+"%'");
		}
		return (List<T>)getHibernateTemplate().find(hql.toString());


	}



	@Override
	public <T extends IModelObject> List<T> all(Class<T> clazz) {
		return (List<T>)getHibernateTemplate().find("from " + clazz.getName());
	}



	@Override
	public boolean exist(IModelObject value) {
		throw new RuntimeException("not supported");
	}

	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		this.beanFactory = beanFactory;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * edu.fudan.framework.persistence.IObjectFactory#deleteAll(java.lang.Class)
	 */
	@Override
	public void deleteAll(Class clazz) {
		getHibernateTemplate().deleteAll(all(clazz));
	}

	@Override
	public Criteria createCriteria(Class clazz) {
		return getHibernateSession().createCriteria(clazz);
	}

	@Override
	public void save(IModelObject model, Serializable id) {
		// getSession().persist(model, id);
	}

	@Override
	public Session getHibernateSession() {
		return currentSession();
	}

	@Override
	public void logicDelete(IModelObject modelObject) {
		save(modelObject);
	}

	@Override
	public Query createQuery(String hql) {
		return getHibernateSession().createQuery(hql);
	}
}
<file_sep>package service;

import model.RiskCheckTemplate;
import model.RiskCheckTemplateItem;

import java.util.List;
import java.util.Set;

public interface IRiskCheckTemplateService {
    RiskCheckTemplate add(String name, String summary, Set<RiskCheckTemplateItem> riskCheckTemplateItems);

    RiskCheckTemplate edit(RiskCheckTemplate riskCheckTemplate, String name, String summary, Set<RiskCheckTemplateItem> riskCheckTemplateItems);

    RiskCheckTemplate addRiskCheckTemplateItem(RiskCheckTemplate riskCheckTemplate, RiskCheckTemplateItem riskCheckTemplateItem);

    List<RiskCheckTemplate> search(String input);
}
