最近公司在作這樣的一個業務,由我來設計數據庫,其中有有一個需求,根據原型圖設計數據庫,這也是我第一次獨立設計數據庫,因涉及公司的機密,只能展現部分原型圖:前端
一、如圖是項目的原型圖,每一個項目都是一條記錄,於是,這能夠設計成獨立的項目表
算法
二、當點擊紅框中的「人員」,就會出現一個彈框,彈框如圖所示。spring
這是項目人員,天然關聯對應項目。不一樣的項目可能有不一樣的人員。於是,這能夠設計成一張項目人員表。表中的字段確定有「人員類型」,好比業務員,業務部經理等。外鍵天然是項目主鍵。一個項目可能會有多條記錄,好比說業務員一條記錄,業務部經理一條記錄等。因此,對於項目而言,這是一對多的關係,是什麼意思呢?一個項目在項目人員表有多條記錄;但對於項目人員來講,這是多對一的關係,多條項目人員的記錄對着一個項目。如圖所示:數據庫
生成數據表結構是有Java代碼生成的,於是,代碼以下:編程
/** * Created By zby on 15:00 2018/12/25 * 項目人員 */ @AllArgsConstructor @NoArgsConstructor @Data @Entity @Table(name = "zq_project_person") public class ProjectPerson extends BaseObj { /** * 人員類型 */ @Enumerated(EnumType.STRING) @Column(name = "person_type") private PersonTypeEnum personType; /** * 人員的ids,存儲人員的編號 */ @Column(name = "ids") private String ids; /** * 選擇時間 */ @Column(name = "op_time") private Date opTime; /** * 項目 */ @ManyToOne @JoinColumn(name = "project_id") private Project project; }
人員類型是枚舉,代碼以下:數組
/** * Created By zby on 9:43 2018/12/27 */ public enum PersonTypeEnum implements TitleEnum { PERSON_TYPE_SALESMAN("業務員"), PERSON_TYPE_SALESMAN_MANAGER("業務部經理"), PERSON_TYPE_DESIGNER("設計師"), PERSON_TYPE_DESIGNER_MANAGER("設計部經理"), PERSON_TYPE_PROJECT_SUPERVISION("工程監理"), PERSON_TYPE_ENGINEERING_MANAGER("工程部經理"); 。。。
經過以上的分析,咱們知道一對多和多對一的關係。這個「一」和「多」。究竟是什麼是 「一」,什麼又是「多」呢?在實際的項目中,咱們多問幾個爲何,成長也會特別的快。不要怕問,也許,人家可能沒時間回答你,或許,人家懼怕把你教會了。這樣,也要問,不問就永遠不知道。ide
「一」針對「一個點」來講,就像是spring中的aop(Aspect Oriented Programming)編程同樣。spring框自己就是以算法驅動爲開發,但咱們在使用它時,通常是以業務驅動爲開發的。既然是業務處理,天然涉及到業務的諸多流程,好比,專門將JVM中的瞬時態的對象轉化爲數據庫的持久態的字段值、或將數據庫的持久態的字段值轉化爲瞬時態的Java對象的dao(data access object)層;專門處理數據庫事務相關的事務層(service層);專門處理接受前端數據和返回前端數據的控制層(controller層)。ui
咱們單單隻考慮其中的一個業務流程,即數據庫的事務層(service層)。這就是一個點,也就是aop須要考慮的一個點。aop的配置文件以下所示:spa
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd" default-lazy-init="true"> <!-- =================================================================== --> <!-- AOP: Configuration and Aspects @TODO:事務縮小範圍到 固定的 名字 --> <!-- 採用 ant風格的編寫方式, 一個 * 表示至少有0個字母,兩個 ** 表示至少有0個目錄 --> <!-- =================================================================== --> <aop:config> <aop:advisor id="managerTxOne" advice-ref="txAdvice" pointcut="execution(* *..service.*Service.*(..))" order="0"/> </aop:config> <tx:annotation-driven/> <!-- 開啓AOP監聽 只對當前配置文件有效 --> <aop:aspectj-autoproxy expose-proxy="true"/> <!-- 配置各個方法的權限,以get list search 開頭的都是隻讀權限 --> <tx:advice id="txAdvice"> <tx:attributes> <!--得到單個對象--> <tx:method name="get*" read-only="true"/> <!--列表對象--> <tx:method name="list*" read-only="true"/> <!--搜索分頁對象--> <tx:method name="search*" read-only="true"/> <tx:method name="*"/> </tx:attributes> </tx:advice> </beans>
咱們注意上面的<aop:config> 。。。</aop:config>這段代碼,其實就是配置的設置這個點。這個是處理全部以service結尾的。設計
於是,再說說咱們數據的庫的 「一」,這是針對一條記錄來講的,好比上文說到的項目表中有不少項目,咱們單單舉出來編號爲167的項目,那麼,這就是 「一」。「多」咱們針對的是當前數據表中涉及到外鍵字段的記錄的條數。好比在項目人員表中,外鍵名爲project_id的項目編號等於167的有不少條記錄。那麼,這就是「多」。
因此,一和多之間,並不是絕對的關係,只是相對來講。就像咱們初中學過的運動間的相對關係。什麼是靜止的,什麼是運動的?咱們坐在車箱裏,相對於窗外的行道樹,咱們是運動的。相對於車子,咱們就是靜止的。因此,也有句話,叫作日行不動八萬裏。萬物就是這樣,沒有絕對的關係。於是,在實際的項目中,咱們遇到了太多的一對多(多對一)的關係,好比:
咱們只有點擊選擇人員,纔將數據保存到數據庫中,可是,咱們仍是要將人員類型按照順序展現出來。於是,咱們須要考慮的是,判斷數據庫中是否存在某種人員類型,好比業務員類型,業務部經理類型。
在作項目以前,咱們須要考慮算法,不然,作出來的東西雖然沒錯,但不是業務所須要的。
經過上文的算法設計,咱們編寫實現方法:
@Override public Result<List<ProjectPerson>> listProjectPersons(Long projectId) { // 【1】步驟一 List<ProjectPerson> projectList = projectPersonDao.listProjectPersons(projectId); List<ProjectPerson> projectPersonList = new ArrayList<>(); Class<PersonTypeEnum> clz = PersonTypeEnum.class; // 【2】步驟二 for (PersonTypeEnum obj : clz.getEnumConstants()) { // 【3】步驟三 boolean objInProjectPerson = false; for (ProjectPerson projectPerson : projectList) { // 【4】步驟四 if (obj.equals(projectPerson.getPersonType())) { projectPerson.setSort(obj.ordinal()); objInProjectPerson = true; projectPersonList.add(projectPerson); break; } } // 【5】步驟五 if (!objInProjectPerson) { ProjectPerson projectPerson = new ProjectPerson(); projectPerson.setPersonType(obj); projectPerson.setSort(obj.ordinal()); projectPersonList.add(projectPerson); } } // 【6】步驟6 projectPersonList.sort(new Comparator<ProjectPerson>() { @Override public int compare(ProjectPerson firstProjectPerson, ProjectPerson secondProjectPerson) { return firstProjectPerson.getSort() - secondProjectPerson.getSort(); } }); return ResultUtil.buildSuccess(projectPersonList); }
咱們在開發過程當中和,要分明白什麼時候以業務驅動爲開發對象,什麼時候以算法驅動爲開發對象。這樣,作一個有條理的人,你就會得到更多的知識。