Maison >Java >javaDidacticiel >Système d'achat, de vente et de gestion des stocks pour les projets de fin d'études - à partir de la construction de base

Système d'achat, de vente et de gestion des stocks pour les projets de fin d'études - à partir de la construction de base

巴扎黑
巴扎黑original
2017-06-26 09:34:112395parcourir

Quatre années d'université et sur le point d'obtenir mon diplôme !

Ceci est mon dernier blog pendant mes études, pour résumer et partager mon projet de fin d'études. Le titre de la thèse que j'ai choisi est "Conception backend d'un système d'achat, de vente et de gestion des stocks d'équipements et d'instruments de réseau de gazoducs". Étant donné que je suis le seul à suivre la voie technique dans notre spécialisation, j'ai complété la conception et le développement de l'ensemble du système en. moi-même, ce qui a pris près d'un mois au total. Un mois plus tard, j'ai finalement obtenu d'excellents résultats.

Nous ne discuterons pas d'articles ici, ni n'écrirons des détails spécifiques de mise en œuvre. Nous parlerons principalement de la façon de construire votre propre cadre système et de la mise en œuvre du système étape par étape, et partagerons vos propres expériences. les autres, et les experts peuvent les traiter comme eux-mêmes. Il est temps de jeter des briques et du mortier ! !

A la fin du blog, tous les documents liés au développement du système seront joints, à l'exclusion du mémoire de fin d'études. Cet article inclut généralement le contenu du mémoire !

1. Affichage du système

1. Page de connexion

 

2. >

5. Gestion des utilisateurs

 

6.Ajout de produits

7.

 

8. Gestion des fournisseurs

 

9. Gestion des bons de commande

 

10. Exportation des bons de commande

 

11. Vue des stocks

 

12.  

2. Analyse des exigences du système

Ce qui précède montre simplement la capture d'écran du test système terminé. Vous pouvez télécharger le package war et le déployer. à votre propre Tomcat Look, le texte commence ci-dessous.

Lors du développement d'un système (simple), la première chose que je veux faire est d'analyser la configuration système requise et de comprendre pourquoi vous souhaitez construire ce système, quels modules fonctionnels ce système possède et quelles fonctions chaque fonction met en œuvre.

Bien sûr, mon objectif principal ici est de terminer mon projet de fin d'études et de remettre mon mémoire de fin d'études. Mais je n’ai pas développé ce système simplement pour réaliser un projet de fin d’études. L'idée principale est de prendre comme exemple le développement de ce système d'achat, de vente et de gestion des stocks pour expliquer en détail l'ensemble du processus de développement d'un système depuis la confirmation des exigences, la sélection de la technologie, la conception de l'architecture, la mise en œuvre du système jusqu'au déploiement des tests. Utiliser pleinement les connaissances, la technologie et l’expérience acquises lors des stages pour mettre pleinement et mieux en œuvre un système. Construire un cadre système de base et former certaines spécifications, puis développer sur cette base peut économiser beaucoup de travail tel que la construction du cadre, l'ajout de dépendances, la configuration, etc.

Le travail principal et l'importance de ce développement sont les suivants :

① Apprendre à analyser les besoins des utilisateurs du point de vue de l'utilisateur, compléter l'analyse et la conception des besoins, etc.

 ② Maîtrise de l'utilisation de divers outils de développement et de conception connexes, ainsi que de logiciels open source.

 ③ Maîtrise de la technologie de développement Spring+SpringMVC+Hibernate+ExtJs.

 ④ Maîtrise de l'outil de gestion de versions Maven.

⑤ Du point de vue d'une entreprise, essayez de construire votre propre cadre de base sous-jacent.

 ⑥Établir un système complet d'achat, de vente et de gestion des stocks de conduites de gaz, effectuer des tests et analyser les résultats.

 ⑦ Déployez le système sur Internet pour implémenter de véritables applications Web.

1. Analyse du problème

Tout d'abord, pour analyser les besoins du système, la première chose que vous devez comprendre est ce qu'est le système d'achat, de vente et d'inventaire. est également appelé système de gestion de la chaîne d'approvisionnement. Le contenu le plus élémentaire est la gestion des achats, des stocks, des ventes et des retours. Le système d'achat, de vente et d'inventaire suit et gère les achats, l'entreposage et les ventes dans la production et l'exploitation de l'entreprise, depuis le bon de commande jusqu'aux marchandises mises dans l'entrepôt et aux marchandises vendues hors de l'entrepôt, chaque étape est suivie. et enregistré. Résoudre efficacement les problèmes commerciaux tels que la gestion de la distribution des entreprises. Alors, quelle est la différence entre le système d'achat, de vente et d'inventaire de conduites de gaz ? En fait, le système d'achat, de vente et d'inventaire a déjà la fonction d'achat, de vente et d'inventaire des produits généraux, et les conduites de gaz sont une marchandise. Partant de là, nous avons commencé à concevoir des modules fonctionnels du système.

2.Structure du module système

Le système est divisé en 6 modules principaux, à savoir la configuration de base, la gestion des achats, la gestion des ventes, la gestion des stocks, l'analyse statistique et le système. gestion. Les rôles définis par le système incluent l'administrateur, l'acheteur, le vendeur, l'administrateur d'inventaire, etc.

Structure du module système (conçue avec xmind) :

Initialement, le système met en place un super administrateur (admin) qui dispose de toutes les autorisations du système. Connectez-vous au système en tant qu'administrateur, définissez les rôles (administrateur système, acheteur, vendeur, administrateur d'inventaire) et attribuez les autorisations correspondantes. Entrez ensuite dans la gestion des utilisateurs et entrez les utilisateurs du système. Les administrateurs généraux se connectent au système et saisissent les données de base ; les acheteurs doivent saisir les fournisseurs, les bons de commande et les bons de retour ; les vendeurs doivent saisir les commandes clients et les bons de retour. Les administrateurs des stocks doivent effectuer un examen des achats et un examen des ventes dans la gestion des stocks. Si l'examen des achats est réussi, les marchandises seront mises dans l'entrepôt et si l'examen des ventes est réussi, les marchandises seront expédiées hors de l'entrepôt. l'entrepôt et l'inventaire seront réduits. Les administrateurs peuvent également consulter les statistiques mensuelles d'achat et les statistiques de ventes.

Processus global du système (conçu à l'aide de visio) :

, il est nécessaire d'entrer dans la phase de développement spécifique, de déterminer d'abord quelles technologies, outils de développement, etc. sont utilisés pour développer ce système.

Parlons brièvement de l'environnement de développement de ce système :

Plateforme de développement : windows 8.1

Version Java : jdk 1.8

Outil de gestion de projet : Maven

Outils de développement : Intellij IDEA

Base de données : MySql 5.1

Serveur : Tomcat 8.5

Framework de développement : Spring4 + SpringMVC + Hibernate5

Front-end Framework : ExtJs 4.2 + Jsp

Outils de modélisation : PowerDesigner, Visio

1.maven

Maven est un outil de build automatisé maintenu par Apache Software Foundation, se concentrant sur la construction de projets Serves et la gestion des dépendances pour la plate-forme Java. Il fournit un entrepôt central qui peut nous aider à télécharger automatiquement des composants et des bibliothèques open source tierces. Il vous suffit de vous appuyer sur un package jar dans votre projet de manière coordonnée, et Maven le téléchargera automatiquement depuis l'entrepôt central, et en même temps téléchargera d'autres packages jar dont dépend ce package jar, et vous pourrez télécharger la source code pour la lecture. Après avoir utilisé maven, une seule copie de chaque package jar lui-même est enregistrée dans l'entrepôt local, ce qui économise considérablement de l'espace de stockage, allège le projet et évite la confusion causée par un trop grand nombre de fichiers en double. Dans le même temps, Maven peut importer automatiquement tous les autres packages jar dont dépend pour nous le package jar actuel, sans participation manuelle, ce qui permet d'économiser beaucoup de temps et d'énergie. En utilisant maven, vous pouvez terminer automatiquement l'ensemble du processus de nettoyage, de compilation, de test, d'empaquetage et de déploiement avec une seule commande simple. Nos projets sont généralement divisés en environnements de développement et environnements de production. Différents environnements correspondent à différents fichiers de configuration. En utilisant maven, vous pouvez configurer deux environnements, spécifier l'environnement d'exécution, et vous pouvez remplacer les fichiers de configuration correspondants par Cela réduit les opérations manuelles. et d'éventuelles erreurs opérationnelles.

2.Intellij IDEA

IDEA est un environnement intégré pour le développement du langage Java, et Intellij est reconnu comme l'un des meilleurs outils de développement Java. IDEA est relativement puissant en matière d'invite automatique de code, de refactorisation, de débogage et d'intégration de divers outils de version (maven, svn, etc.). Je suis passé au développement d'idées pendant mon stage. J'ai déjà utilisé Eclipse par rapport à Eclipse, Idea présente plus d'avantages en termes de débogage et d'invites de code automatiques. Les projets ont une structure de répertoires plus conviviale, en particulier les projets multi-projets. Bien sûr, Eclipse est plus facile à utiliser qu'Idea. L'utilisation d'Idea peut augmenter votre vitesse de développement, mais seulement si vous devez mémoriser de nombreuses touches de raccourci. Utilisez la fonction de débogage d'Idea. Par exemple, il vous suffit d'appuyer sur la touche de raccourci Alt+F8 puis de saisir une expression pour l'évaluer rapidement ; pendant le débogage, Idea affichera la valeur de la variable dans différentes couleurs derrière la variable. connaître chaque étape du débogage, ce qui est très pratique. Bien utiliser IDEA peut améliorer considérablement notre vitesse de développement.

3.ExtJs

ExtJs peut être utilisé pour développer des applications clientes riches ajax. Il s'agit d'un framework ajax front-end écrit en javascript qui n'a rien à voir avec la technologie back-end. créer des interfaces utilisateur frontales et dispose de puissantes fonctions de traitement de données, ainsi que de statistiques graphiques, etc. Dans le même temps, ExtJs propose de nombreux thèmes personnalisés parmi lesquels choisir, ce qui en fait un bon choix pour développer des systèmes de gestion backend.

4. Conception de l'architecture sous-jacente

Avant de concevoir et de coder le système d'achat, de vente et d'inventaire, concevez d'abord votre propre cadre sous-jacent. Ce cadre sous-jacent peut être utilisé comme A. base pour le développement d'autres projets spécifiques, de sorte qu'il n'y ait pas besoin de faire beaucoup de travail répétitif à chaque fois qu'un projet est développé. Ce framework sous-jacent comprend principalement une spécification de développement et quelques classes d'outils communes. Plus important encore, il introduit divers frameworks par catégorie, tels que Spring, Hibernate et divers fichiers de configuration. Dans le même temps, si de nouvelles fonctions sont ajoutées au cours du développement futur, elles pourront être ajoutées à cette couche inférieure et continuellement améliorées.

1. Spécifications

Avant de procéder à la conception du framework, afin de fluidifier le processus de développement logiciel et d'améliorer la fiabilité, la lisibilité et la maintenabilité du code, la première chose à déterminer Ce sont les spécifications de développement. Eh bien, comme le dit le proverbe, il n’y a pas de règle sans règles, et il en va de même pour le développement de logiciels. Voici quelques règles simples à suivre.

1.1 Spécifications de base

La première chose à laquelle vous devez vous conformer sont quelques spécifications de base. De manière générale, les entreprises utilisent les noms de domaine comme base pour tous les noms, tels que les noms de fichiers, les noms de packages, etc. Par conséquent, j'ai demandé un nom de domaine [www.lyyzoo.com] comme nom de domaine personnel. Utilisez ensuite D:/lyyzoo-repo comme répertoire racine pour le développement, c'est-à-dire l'entrepôt de code personnel. Tous les futurs projets seront construits dans ce répertoire. Tout développement de projet utilise Maven pour gérer les projets, la structure des répertoires est donc un répertoire de spécification Maven standard.

Structure de répertoire convenue par Maven :

1.2 Spécifications du code

① Nommage

Toutes les exigences de nommage Voir la signification de le nom, essayez de vous assurer que la signification de la variable est connue via le nom de la variable et essayez d'ajouter des commentaires là où des commentaires sont nécessaires.

  > Les noms de packages sont tous en minuscules, sous la forme d'un nom de domaine + module, tel que : com.lyyzoo.service

  > lettre, chacun met en majuscule la première lettre d'un mot.

  > Le nom de la méthode adopte la nomenclature Camel, commençant par une lettre minuscule, et la première lettre de chaque mot est minuscule ; les getters et setters sont automatiquement générés à l'aide de Lombok, ajoutez simplement l'annotation @Data.

  > Les noms de variables adoptent la méthode de dénomination Camel, commençant par une lettre minuscule, et la première lettre de chaque mot est en majuscule. Les noms de variables ne doivent pas être trop longs et peuvent être sous forme d'abréviations, mais la signification du nom doit être claire.

  > Les noms de constantes sont tous en majuscules et chaque mot est séparé par "_".

 ②Layering

  Le projet est divisé en modules fonctionnels. Différents projets construisent différents projets et utilisent des dépendances maven pour la gestion. Les couches de base du package incluent le contrôleur (couche de contrôle), le service (couche métier), le dao (couche d'accès aux données) et l'entité (couche de modèle).

2. Conception de l'architecture

2.1 Structure du module

La couche inférieure de l'ensemble du projet se concentre sur certaines choses communes et de base, qui sont intégrées ensemble pour une réutilisation future. Tout d’abord, créez un projet maven nommé lyyzoo, lyyzoo servira de répertoire racine sous-jacent. Il y a deux sous-modules principaux sous lyyzoo, à savoir lyyzoo-base et lyyzoo-starter est un module de base et est utilisé pour certains programmes Java et JavaEE simples. lyyzoo-starter est lié à JavaEE et dépendra de lyyzoo-. base, et introduit également des frameworks tiers tels que Spring et Hibernate. Ajoutez ensuite des sous-modules spécifiques dans chaque module. Quel module doit être utilisé dans le développement futur, ajoutez simplement ce module dans les dépendances.

Le diagramme de structure du module sous-jacent :

Voici la relation entre chaque POM :

① lyyzoo > 🎜 >

 

 ② lyyzoo-base > pom.xml

 

 ③ lyyzoo-starter >

 

 2.2 Gestion des dépendances

Une fois la structure construite, vous devez effectuer un travail détaillé de configuration des dépendances. lyyzoo est la classe parent de tous les modules, vous devez donc le faire. ajoutez-le à lyyzoo Propriétés communes, gestion des dépendances, plug-ins maven, etc.

Tout d'abord, indiquez tous les numéros de version et placez-les dans , de sorte que si vous devez passer à une autre version, vous puissiez simplement modifier le numéro de version pour atteindre l'objectif. Certaines propriétés sont répertoriées comme suit : notamment la version sous-jacente, la version Java, Spring, la version Hibernate, etc.

 1 <properties> 2   <!-- Global --> 3   <lyyzoo.version>1.0-SNAPSHOT</lyyzoo.version> 4   <java.version>1.8</java.version> 5   <maven.compiler.source>${java.version}</maven.compiler.source> 6   <maven.compiler.target>${java.version}</maven.compiler.target> 7   <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 8   <!-- lombok --> 9   <lombok.version>1.16.14</lombok.version>10   <!-- log -->11   <slf4j.version>1.7.7</slf4j.version>12   <logback.version>1.1.3</logback.version>13   <!-- jdbc -->14   <mysql.version>5.1.38</mysql.version>15   <!--  -->16   <c3p0.version>0.9.5.2</c3p0.version>17   <!-- test -->18   <junit.version>4.12</junit.version>19   <!-- servlet -->20   <servlet.version>3.1.0</servlet.version>21   <!-- spring -->22   <spring.version>4.2.6.RELEASE</spring.version>23   <aspectjrt.version>1.7.3</aspectjrt.version>24   <aspectjweaver.version>1.7.3</aspectjweaver.version>25   <!-- hibernate -->26   <hibernate.version>5.0.1.Final</hibernate.version>27   <hibernate.jpa.version>1.0.0.Final</hibernate.jpa.version>28 </properties>
Afficher le code

Ensuite, introduisez la gestion des dépendances et introduisez d'autres projets dans lyyzoo. tous les packages jar tiers sont ajoutés à , afin que tous les packages jar puissent être facilement gérés. Certains des packages jar introduits sont répertoriés ci-dessous. Pour les autres, veuillez vous référer au code source.

 ① Tout d'abord, vous devez introduire d'autres modules sous lyyzoo, tels que lyyzoo-base-core, lyyzoo-starter-base et d'autres modules.

 1 <!-- lyyzoo --> 2 <dependency> 3   <groupId>com.lyyzoo</groupId> 4   <artifactId>lyyzoo-base-core</artifactId> 5   <version>${lyyzoo.version}</version> 6 </dependency> 7 <dependency> 8   <groupId>com.lyyzoo</groupId> 9   <artifactId>lyyzoo-base-data</artifactId>10   <version>${lyyzoo.version}</version>11 </dependency>12 <dependency>13   <groupId>com.lyyzoo</groupId>14   <artifactId>lyyzoo-starter-base</artifactId>15   <version>${lyyzoo.version}</version>16 </dependency>17 <dependency>18   <groupId>com.lyyzoo</groupId>19   <artifactId>lyyzoo-starter-jpa</artifactId>20   <version>${lyyzoo.version}</version>21 </dependency>
Afficher le code

 ② Lié à JDBC, le package jar associé est c3p0, utilisé pour la connexion à la base de données Pool ; package de pilotes MySQL ; dbutils, qui encapsule simplement JDBC et est simple et pratique à utiliser.

 1 <!-- jdbc --> 2 <dependency> 3   <groupId>com.mchange</groupId> 4   <artifactId>c3p0</artifactId> 5   <version>${c3p0.version}</version> 6 </dependency> 7 <dependency> 8   <groupId>mysql</groupId> 9   <artifactId>mysql-connector-java</artifactId>10   <version>${mysql.version}</version>11 </dependency>12 <dependency>13   <groupId>commons-dbutils</groupId>14   <artifactId>commons-dbutils</artifactId>15   <version>1.5</version>16 </dependency>
Afficher le code

 ③ Journal lié :

 1 <!-- log --> 2 <dependency> 3   <groupId>org.slf4j</groupId> 4   <artifactId>slf4j-api</artifactId> 5   <version>${slf4j.version}</version> 6 </dependency> 7 <dependency> 8   <groupId>ch.qos.logback</groupId> 9   <artifactId>logback-classic</artifactId>10   <version>${logback.version}</version>11 </dependency>12 <!-- slf4j -->13 <dependency>14   <groupId>org.slf4j</groupId>15   <artifactId>log4j-over-slf4j</artifactId>16   <version>${slf4j.version}</version>17 </dependency>
Afficher le code

 ④ Lié au printemps, y compris spring aop, spring mvc, etc.

 1 <!-- springframework --> 2 <dependency> 3   <groupId>org.springframework</groupId> 4   <artifactId>spring-aop</artifactId> 5   <version>${spring.version}</version> 6 </dependency> 7 <dependency> 8   <groupId>org.springframework</groupId> 9   <artifactId>spring-aspects</artifactId>10   <version>${spring.version}</version>11 </dependency>12 <dependency>13   <groupId>org.springframework</groupId>14   <artifactId>spring-beans</artifactId>15   <version>${spring.version}</version>16 </dependency>17 <dependency>18   <groupId>org.springframework</groupId>19   <artifactId>spring-context</artifactId>20   <version>${spring.version}</version>21 </dependency>22 <dependency>23   <groupId>org.springframework</groupId>24   <artifactId>spring-context-support</artifactId>25   <version>${spring.version}</version>26 </dependency>27 <dependency>28   <groupId>org.springframework</groupId>29   <artifactId>spring-core</artifactId>30   <version>${spring.version}</version>31 </dependency>32 <dependency>33   <groupId>org.springframework</groupId>34   <artifactId>spring-jdbc</artifactId>35   <version>${spring.version}</version>36 </dependency>37 <dependency>38   <groupId>org.springframework</groupId>39   <artifactId>spring-jms</artifactId>40   <version>${spring.version}</version>41 </dependency>42 <dependency>43   <groupId>org.springframework</groupId>44   <artifactId>spring-orm</artifactId>45   <version>${spring.version}</version>46 </dependency>47 <dependency>48   <groupId>org.springframework</groupId>49   <artifactId>spring-tx</artifactId>50   <version>${spring.version}</version>51 </dependency>52 <dependency>53   <groupId>org.springframework</groupId>54   <artifactId>spring-web</artifactId>55   <version>${spring.version}</version>56 </dependency>57 <dependency>58   <groupId>org.springframework</groupId>59   <artifactId>spring-webmvc</artifactId>60   <version>${spring.version}</version>61 </dependency>
Afficher le code

 ⑤ lié à la mise en veille prolongée :

 1 <dependency> 2   <groupId>org.hibernate</groupId> 3   <artifactId>hibernate-c3p0</artifactId> 4   <version>${hibernate.version}</version> 5 </dependency> 6 <dependency> 7   <groupId>org.hibernate.common</groupId> 8   <artifactId>hibernate-commons-annotations</artifactId> 9   <version>${hibernate.version}</version>10 </dependency>11 <dependency>12   <groupId>org.hibernate</groupId>13   <artifactId>hibernate-core</artifactId>14   <version>${hibernate.version}</version>15 </dependency>16 <dependency>17   <groupId>org.hibernate</groupId>18   <artifactId>hibernate-entitymanager</artifactId>19   <version>${hibernate.version}</version>20 </dependency>
Afficher le code

 

  所有的依赖添加好后,就需要为各个子模块添加具体的依赖了,根据每个子模块的功能,添加相关的依赖,而不是将所有的依赖一次性加入。这样我们就可以根据自己开发的项目的需要,添加模块依赖,而不是一次性加入所有jar包,避免冗余,增大项目的体积。下面以lyyzoo-base-data和lyyzoo-starter-jpa为例说明。

  lyyzoo-base-data模块是基础数据相关,主要与数据库打交道,那么就需要引入mysql驱动、数据库连接池c3p0等,pom.xml如下:

 1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 "> 3     <modelVersion>4.0.0</modelVersion> 4     <parent> 5         <groupId>com.lyyzoo</groupId> 6         <artifactId>lyyzoo-base</artifactId> 7         <version>1.0-SNAPSHOT</version> 8     </parent> 9     <artifactId>lyyzoo-base-data</artifactId>10     <name>${project.artifactId}</name>11     <packaging>jar</packaging>12 13     <dependencies>14         <!-- dbutils -->15         <dependency>16             <groupId>commons-dbutils</groupId>17             <artifactId>commons-dbutils</artifactId>18         </dependency>19         <!-- jdbc -->20         <dependency>21             <groupId>mysql</groupId>22             <artifactId>mysql-connector-java</artifactId>23         </dependency>24         <dependency>25             <groupId>com.mchange</groupId>26             <artifactId>c3p0</artifactId>27         </dependency>28     <!-- test -->29         <dependency>30             <groupId>com.lyyzoo</groupId>31             <artifactId>lyyzoo-base-test</artifactId>32             <scope>test</scope>33         </dependency>34     </dependencies>35 </project>
View Code

  lyyzoo-starter-jpa是Java持久化相关,所以主要引入hibernate相关的依赖,同时,starter-jpa会依赖base-data及starter-base,pom.xml如下:

 1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 "> 3     <modelVersion>4.0.0</modelVersion> 4     <parent> 5         <groupId>com.lyyzoo</groupId> 6         <artifactId>lyyzoo-starter</artifactId> 7         <version>1.0-SNAPSHOT</version> 8     </parent> 9     <artifactId>lyyzoo-starter-jpa</artifactId>10     <name>${project.artifactId}</name>11     <packaging>jar</packaging>12 13     <dependencies>14         <dependency>15             <groupId>com.lyyzoo</groupId>16             <artifactId>lyyzoo-base-data</artifactId>17         </dependency>18         <dependency>19             <groupId>com.lyyzoo</groupId>20             <artifactId>lyyzoo-starter-base</artifactId>21         </dependency>22         <dependency>23             <groupId>org.hibernate</groupId>24             <artifactId>hibernate-c3p0</artifactId>25         </dependency>26         <dependency>27             <groupId>org.hibernate.common</groupId>28             <artifactId>hibernate-commons-annotations</artifactId>29         </dependency>30         <dependency>31             <groupId>org.hibernate</groupId>32             <artifactId>hibernate-core</artifactId>33         </dependency>34         <dependency>35             <groupId>org.hibernate</groupId>36             <artifactId>hibernate-ehcache</artifactId>37         </dependency>38         <dependency>39             <groupId>org.hibernate.javax.persistence</groupId>40             <artifactId>hibernate-jpa-2.1-api</artifactId>41         </dependency>42         <dependency>43             <groupId>org.hibernate</groupId>44             <artifactId>hibernate-validator</artifactId>45         </dependency>46         <dependency>47             <groupId>com.lyyzoo</groupId>48             <artifactId>lyyzoo-starter-test</artifactId>49             <scope>test</scope>50         </dependency>51     </dependencies>52 </project>
View Code

  2.3类结构

  有了前面的基础之后,接下来进行重点的类结构设计。底层需要做的最重要的工作就是将一些通用的类抽象出来,以便于以后重用,从而提高开发效率。例如返回结果和分页类的封装、通用的工具类、JDBC相关的操作等。

  说明一下,整个底层很大一部分是从之前实习的公司(这个就不说了)直接拿过来的,有些则更改了。相信我拿取的这部分代码并不会涉及机密问题,不用于商业用途,仅仅只是学习,应该没多大问题。

  (1) lyyzoo-base-core

  lyyzoo-base-core 目录结构:

  

  lyyzoo-base-core是基础核心,封装了返回结果和加入了一些常用的工具类。

  com.lyyzoo.bean包下封装了BaseBean和Result,BaseBean是Bean类的一个基础类,实现了序列化,重写了toString()方法,如下:

 1 package com.lyyzoo.bean; 2  3 import org.apache.commons.lang3.builder.ToStringBuilder; 4 import org.apache.commons.lang3.builder.ToStringStyle; 5  6 import java.io.Serializable; 7  8 /** 9  * BaseBean 实现序列化 <p>10  *11  * @author bojiangzhou12  * @date 2017-03-2713  */14 public abstract class BaseBean implements Serializable {15 16     /**17      * ToStringBuilder – 用于辅助实现Object.toString()方法<p>18      */19     public String toString() {20         return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);21     }22 23 }
View Code

  Result则封装了返回的结果,这里主要与ExtJs相对应,ExtJs进行ajax请求时,返回success=true,会进入success()方法;返回success=false,会进入failure()方法。同时,封装了返回消息、标识、错误信息等,便于前端拿到相应数据。

 1 package com.lyyzoo.bean; 2  3 import lombok.Data; 4  5 import java.util.Map; 6  7 /** 8  * 封装返回结果<p> 9  *10  * @author bojiangzhou11  * @date 2017-03-2712  */13 @Data14 public class Result extends BaseBean {15     private static final long serialVersionUID = 1L;16 17     /**18      * 成功标志19      */20     public boolean success;21     /**22      * 返回标示23      */24     public Integer code;25     /**26      * 相关消息27      */28     public String msg;29     /**30      * 相关数据31      */32     public Object data;33     /**34      * 错误详细35      */36     public Map<String, Object> errors;37 38     public Result() {39 40     }41 42     public Result(boolean success) {43         this.success = success;44     }45 46     public Result(boolean success, Integer code, Object data, String msg) {47         this(success);48         this.code = code;49         this.data = data;50         this.msg = msg;51     }52 53     public Result(Integer code, Map<String, Object> errors, String msg) {54         this.success = false;55         this.code = code;56         this.errors = errors;57         this.msg = msg;58     }59 60     public boolean isSuccess() {61         return this.success;62     }63 64     public boolean hasErrors() {65         if (this.errors != null && this.errors.size() > 0) {66             return true;67         }68         return false;69     }70 }
View Code

  其它的主要是一些工具类,例如Arrays继承了org.apache.commons.lang3.ArrayUtils,使得Arrays具有了丰富的操作集合的工具。再如Dates,Dates里封装了大量的对日期操作的方法,比如格式化日期、获取某个日期当天的开始时间和结束时间等。

  (2) lyyzoo-starter-base

  lyyzoo-starter-base 目录结构:

  

  lyyzoo-starter-base是web应用程序的一个基础,主要封装了基础实体类以及spring-base和日志的配置。实体的顶层是AbstractEntity,AbstractEntity继承BaseBean。AbstractEntity重写了equals和hashCode方法,主要做的处理是,如果两个实体的id相同也算这两个对象为同一个对象。代码如下:

 1 package com.lyyzoo.data.entity; 2  3 import com.lyyzoo.bean.BaseBean; 4  5 import java.io.Serializable; 6  7 /** 8  * 抽象实体类 重写equals和hashCode方法 9  *10  * @author bojiangzhou11  * @date 2017-03-2812  */13 @SuppressWarnings("serial")14 public abstract class AbstractEntity<ID extends Serializable> extends BaseBean implements Serializable {15 16     public abstract ID getId();17 18     @Override19     public boolean equals(Object obj) {20 21         if (null == obj) {22             return false;23         }24         if (this == obj) {25             return true;26         }27         if (!getClass().equals(obj.getClass())) {28             return false;29         }30 31         AbstractEntity<?> that = (AbstractEntity<?>) obj;32 33         return null == this.getId() ? false : this.getId().equals(that.getId());34     }35 36     @Override37     public int hashCode() {38         int hashCode = 17;39 40         hashCode += null == getId() ? 0 : getId().hashCode() * 31;41 42         return hashCode;43     }44 45 }
View Code

  BaseEntity则继承AbstractEntity,BaseEntity作为其它实体的父类存在,BaseEntity定义了主键ID的生成策略。代码如下:

 1 package com.lyyzoo.data.entity; 2  3 import lombok.Data; 4  5 import javax.persistence.GeneratedValue; 6 import javax.persistence.GenerationType; 7 import javax.persistence.Id; 8 import javax.persistence.MappedSuperclass; 9 10 /**11  * 统一定义id的entity基类.12  * <p/>13  * 抽象实体基类,提供统一的ID,和相关的基本功能14  * <p/>15  */16 @Data17 @MappedSuperclass18 @SuppressWarnings("serial")19 public abstract class BaseEntity extends AbstractEntity<Long> {20 21     /**22      * id 字段23      */24     @Id25     protected Long id;26 27     @Id28     @GeneratedValue(strategy = GenerationType.IDENTITY)29     public Long getId() {30         return this.id;31     }32 33     public void setId(Long id) {34         this.id = id;35     }36 }
View Code

  spring-base.xml是基础配置,主要配置了扫描系统的配置文件、注解等。

 1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3        xmlns="http://www.springframework.org/schema/beans" 4        xmlns:beans="http://www.springframework.org/schema/beans" 5        xmlns:context="http://www.springframework.org/schema/context" 6        xmlns:aop="http://www.springframework.org/schema/aop" 7        xmlns:tx="http://www.springframework.org/schema/tx" 8        xmlns:util="http://www.springframework.org/schema/util" 9        xmlns:mvc="http://www.springframework.org/schema/mvc"10        xmlns:jee="http://www.springframework.org/schema/jee"11        xmlns:jdbc="http://www.springframework.org/schema/jdbc"12        xmlns:tool="http://www.springframework.org/schema/tool"13        xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"14        xsi:schemaLocation="15      http://www.springframework.org/schema/beans/spring-beans.xsd16      http://www.springframework.org/schema/context/spring-context.xsd17      http://www.springframework.org/schema/aop/spring-aop.xsd18      http://www.springframework.org/schema/tx/spring-tx.xsd19      http://www.springframework.org/schema/util/spring-util.xsd20      http://www.springframework.org/schema/mvc/spring-mvc.xsd21      http://www.springframework.org/schema/jee/spring-jee.xsd22      http://www.springframework.org/schema/jdbc/spring-jdbc.xsd23      http://www.springframework.org/schema/tool/spring-tool.xsd24      http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd"25 >26 27     <description>Spring Base Config</description>28 29     <!-- 加载config.properties -->30     <context:property-placeholder location="classpath*:/config/*.properties" file-encoding="UTF-8" />31 32     <!-- 使用annotation 自动注册bean, 并保证@Required、@Autowired的属性被注入 -->33     <context:component-scan base-package="com.lyyzoo">34         <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>35         <context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>36     </context:component-scan>37 38     <!-- 支持上传文件 -->39     <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>40 41 </beans>
View Code
  (3) lyyzoo-starter-jpa

  lyyzoo-starter-jpa 目录结构:

  

  lyyzoo-starter-jpa集成了持久化相关的操作,配置等。

  首先需要做持久化相关的配置(spring-base-jpa.xml),如数据源、SessionFactory、事务管理等。数据源使用c3p0,数据源相关配置如数据库驱动、地址等写到到配置文件中。配置Hibernate SessionFactory的同时,增加了JdbcTemplate。事务管理器使用Hibernate的事务管理。总的配置如下:

  1 <?xml version="1.0" encoding="UTF-8"?>  2 <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  3     xmlns="http://www.springframework.org/schema/beans"  4     xmlns:beans="http://www.springframework.org/schema/beans"  5     xmlns:tx="http://www.springframework.org/schema/tx"  6     xmlns:aop="http://www.springframework.org/schema/aop"  7     xmlns:context="http://www.springframework.org/schema/context"  8     xmlns:mvc="http://www.springframework.org/schema/mvc"  9     xmlns:util="http://www.springframework.org/schema/util" 10     xmlns:jee="http://www.springframework.org/schema/jee" 11     xmlns:jdbc="http://www.springframework.org/schema/jdbc" 12     xmlns:tool="http://www.springframework.org/schema/tool" 13     xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr" 14     xsi:schemaLocation=" 15      http://www.springframework.org/schema/beans/spring-beans.xsd 16      http://www.springframework.org/schema/context/spring-context.xsd 17      http://www.springframework.org/schema/aop/spring-aop.xsd 18      http://www.springframework.org/schema/tx/spring-tx.xsd 19      http://www.springframework.org/schema/util/spring-util.xsd 20      http://www.springframework.org/schema/mvc/spring-mvc.xsd 21      http://www.springframework.org/schema/jee/spring-jee.xsd 22      http://www.springframework.org/schema/jdbc/spring-jdbc.xsd 23      http://www.springframework.org/schema/tool/spring-tool.xsd 24      http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd" 25     > 26  27     <description>Spring Jpa</description> 28  29     <!-- 使用C3P0 --> 30     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 31         <property name="driverClass" value="${jdbc.driver}"/> 32         <property name="jdbcUrl" value="${jdbc.url}"/> 33         <property name="user" value="${jdbc.username}"/> 34         <property name="password" value="${jdbc.password}"/> 35  36         <!-- default: 3 --> 37         <!-- 初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。--> 38         <property name="initialPoolSize" value="${c3p0.initialPoolSize:5}"/> 39  40         <!-- default: 3 --> 41         <!-- 连接池保留最小连接数--> 42         <property name="minPoolSize" value="${c3p0.minPoolSize:5}"/> 43  44         <!-- default: 15 --> 45         <!-- 连接池保留最大连接数。--> 46         <property name="maxPoolSize" value="${c3p0.maxPoolSize:15}"/> 47  48         <!-- default: 0(秒) = 永不丢弃--> 49         <!-- 最大空闲时间,600 秒内未使用则连接被丢弃。--> 50         <property name="maxIdleTime" value="${c3p0.maxIdleTime:600}"/> 51     </bean> 52  53     <!-- sessionFactory --> 54     <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> 55         <property name="dataSource" ref="dataSource" /> 56         <property name="hibernateProperties" > 57             <props> 58                 <prop key="dialect">${hibernate.dialect}</prop> 59                 <prop key="show_sql">${hibernate.show.sql}</prop> 60                 <prop key="hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop> 61             </props> 62         </property> 63         <!-- 扫描hibernate注解实体 --> 64         <property name="packagesToScan"> 65             <list> 66                 <value>com.lyyzoo.*.entity</value> 67             </list> 68         </property> 69     </bean> 70  71     <!-- jdbcTemplate --> 72     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> 73         <property name="dataSource" ref="dataSource"/> 74     </bean> 75     <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate"> 76         <constructor-arg ref="dataSource"/> 77     </bean> 78     <bean id="jdbcTemplateSupport" class="com.lyyzoo.data.jdbc.JdbcTemplateSupport"> 79         <property name="dataSource" ref="dataSource"/> 80         <property name="namedParameterJdbcTemplate" ref="namedParameterJdbcTemplate"/> 81     </bean> 82  83     <!-- 事务管理器 --> 84     <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> 85         <property name="sessionFactory" ref="sessionFactory" /> 86     </bean> 87  88     <!-- 事务通知属性 --> 89     <tx:advice id="transactionManagerAdvice" transaction-manager="transactionManager"> 90         <tx:attributes> 91             <tx:method name="get*"        read-only="true"         /> 92             <tx:method name="load*"        read-only="true"        /> 93             <tx:method name="find*"        read-only="true"        /> 94             <tx:method name="list*"        read-only="true"        /> 95             <tx:method name="page*"        read-only="true"        /> 96             <tx:method name="query*"    read-only="true"        /> 97             <tx:method name="*"            propagation="REQUIRED"    /> 98         </tx:attributes> 99     </tx:advice>100 101     <!-- AOP 事务 -->102     <aop:config proxy-target-class="true">103         <aop:pointcut id="serviceMethod" expression="execution(* com.lyyzoo..*Service.*(..))"/>104         <aop:advisor pointcut-ref="serviceMethod" advice-ref="transactionManagerAdvice"/>105     </aop:config>106 107     <!-- 扫描注解 -->108     <context:component-scan base-package="com.lyyzoo" />109 110 </beans>
View Code

  然后在com.lyyzoo.data.domain包下,Page封装了分页相关的属性,如当前页数据、页码、每页大小、总页数等。com.lyyzoo.data.util包下,Sqls封装了操作sql语句的工具,比如根据传入的查询语句,返回查询总数的sql语句。在com.lyyzoo.data.jdbc包下,JdbcTemplateSupport封装了比较复杂的查询,比如根据传入的参数、分页条件等,自动查询数据、总数并封装到Page里返回。com.lyyzoo.data.dao包下,SimpleDao封装了基于Hibernate SessionFactory的简单的增删改查操作,如save(),get()等方法。dao包下,BaseDao继承SimpleDao,并代理了JdbcTemplateSupport,使得BaseDao具有SimpleDao和JdbcTemplateSupport的功能,BaseDao则作为其它dao的一个父类存在。最后,在com.lyyzoo.service包下,BaseService代理了BaseDao,进行了进一步的封装,BaseService是其它service类的父类,其它service就可以直接调用save、get、page等内置方法。

  (4) lyyzoo-starter-web

  lyyzoo-starter-web自然跟web相关,在com.lyyzoo.web包下,BaseController作为controller类的父类,主要封装了返回结果集等信息。还有web相关配置,如视图解析器等内容:

 1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3     xmlns="http://www.springframework.org/schema/beans" 4     xmlns:beans="http://www.springframework.org/schema/beans" 5     xmlns:tx="http://www.springframework.org/schema/tx" 6     xmlns:aop="http://www.springframework.org/schema/aop" 7     xmlns:context="http://www.springframework.org/schema/context" 8     xmlns:mvc="http://www.springframework.org/schema/mvc" 9     xmlns:task="http://www.springframework.org/schema/task"10     xmlns:util="http://www.springframework.org/schema/util"11     xmlns:jee="http://www.springframework.org/schema/jee"12     xmlns:jdbc="http://www.springframework.org/schema/jdbc"13     xmlns:tool="http://www.springframework.org/schema/tool"14     xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"15     xsi:schemaLocation="16      http://www.springframework.org/schema/beans/spring-beans.xsd17      http://www.springframework.org/schema/context/spring-context.xsd18      http://www.springframework.org/schema/aop/spring-aop.xsd19      http://www.springframework.org/schema/tx/spring-tx.xsd20      http://www.springframework.org/schema/util/spring-util.xsd21      http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd22      http://www.springframework.org/schema/task/spring-task-3.2.xsd23      http://www.springframework.org/schema/jee/spring-jee.xsd24      http://www.springframework.org/schema/jdbc/spring-jdbc.xsd25      http://www.springframework.org/schema/tool/spring-tool.xsd26      http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd"27     >28 29     <description>Spring Web</description>30     31     <!-- 加载config.properties -->32     <context:property-placeholder location="classpath*:/config/*.properties" file-encoding="UTF-8" />33             34     <!-- 扫描Controller以及ControllerAdvice -->35     <context:component-scan base-package="com.lyyzoo" use-default-filters="false">36         <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>37         <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>38     </context:component-scan>39 40     <!-- 静态资源映射 -->41     <mvc:resources location="/static/" mapping="/static/**"/>42 43     <!-- 容器默认的DefaultServletHandler处理 所有静态内容与无RequestMapping处理的URL-->    44     <mvc:default-servlet-handler />45 46     <!-- 支持@Controller注解 -->47     <mvc:annotation-driven />48 49     <!-- 视图解析器 -->50     <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">51         <property name="prefix" value="/WEB-INF/view"/>52         <property name="suffix" value=".jsp"/>53     </bean>54     55 </beans>
View Code
  (5) 类结构图

  类结构图参考《底层类结构.vsd》

  

  

 五、数据库与实体设计

  在开始开发一个系统之前,首先需要做的就是根据需求分析设计系统的实体对象以及对应的数据库表结构,这是开发的基础。

  根据前面的需求分析设计的功能模块,实体对象可以分为5个模块,分别是系统模块(system)、基础模块(base)、采购模块(purchase)、销售模块(sale)、库存模块(stock)。下面是实体清单:

  

  有了清单之后,利用PowerDesigner进行数据库物理模型设计。由于拥有对数据库的完全控制权,所以不对表设置约束,所有的约束在程序代码中进行控制。下面列出各个实体的属性即对应的表,具体可参考《数据库物理模型.pdm》。物理模型设计完成后,创建名为gpss的数据库,然后创建各个表。

  数据库模型:

  

 

 

六、系统功能实现

1.创建工程

  需求分析做完了,技术没问题,底层架构也设计好了,数据库设计好了,前面的所有准备工作做完了,下面就要进行燃气管进销存系统的编码实现了。首先要做的工作就是创建工程,项目名拟为gpss,即燃气管进销存(Gas Purchase Sale Stock)的缩写,工程名则为lyyzoo-gpss。

  在IDEA中创建lyyzoo-gpss的maven工程,继承lyyzoo。同时,在lyyzoo-gpss下创建两个子模块,分别为lyyzoo-gpss-base和lyyzoo-gpss-web,base模块包含了系统的dao、entity、service等层次,主要为java文件;web则包含了controller层、jsp、js等web相关资源文件。

  lyyzoo-gpss目录结构:

  

  lyyzoo-gpss > pom.xml:

 1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 "> 3   <modelVersion>4.0.0</modelVersion> 4   <parent> 5     <groupId>com.lyyzoo</groupId> 6     <artifactId>lyyzoo</artifactId> 7     <version>1.0-SNAPSHOT</version> 8   </parent> 9   <groupId>com.lyyzoo.gpss</groupId>10   <artifactId>lyyzoo-gpss</artifactId>11   <name>lyyzoo :: gpss</name>12   <packaging>pom</packaging>13 14   <modules>15     <module>lyyzoo-gpss-base</module>16     <module>lyyzoo-gpss-web</module>17   </modules>18 19   <profiles>20     <!-- 开发环境 -->21     <profile>22       <id>dev</id>23       <activation>24         <property>25           <name>env</name>26           <value>dev</value>27         </property>28       </activation>29     </profile>30     <!-- 线上环境 -->31     <profile>32       <id>online</id>33       <activation>34         <property>35           <name>env</name>36           <value>online</value>37         </property>38       </activation>39     </profile>40   </profiles>41   <build>42     <plugins>43       <plugin>44         <groupId>com.juvenxu.portable-config-maven-plugin</groupId>45         <artifactId>portable-config-maven-plugin</artifactId>46         <version>1.1.5</version>47         <executions>48           <execution>49             <goals>50               <goal>replace-package</goal>51             </goals>52           </execution>53         </executions>54         <configuration>55           <portableConfig>src/main/resources/portable/config-${env}.xml</portableConfig>56         </configuration>57       </plugin>58     </plugins>59   </build>60 61 </project>
View Code

  lyyzoo-gpss-base主要是dao层、service层、model层的集成,所以需要依赖于底层lyyzoo-starter-jpa、lyyzoo-starter-web。

  lyyzoo-gpss-base > pom.xml:

 1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 "> 3     <modelVersion>4.0.0</modelVersion> 4     <parent> 5         <groupId>com.lyyzoo.gpss</groupId> 6         <artifactId>lyyzoo-gpss</artifactId> 7         <version>1.0-SNAPSHOT</version> 8     </parent> 9     <artifactId>lyyzoo-gpss-base</artifactId>10     <name>lyyzoo :: gpss :: base</name>11     <packaging>jar</packaging>12 13     <dependencies>14         <dependency>15             <groupId>com.lyyzoo</groupId>16             <artifactId>lyyzoo-starter-jpa</artifactId>17         </dependency>18         <dependency>19             <groupId>com.lyyzoo</groupId>20             <artifactId>lyyzoo-starter-web</artifactId>21         </dependency>22     </dependencies>23 24 </project>
View Code

  lyyzoo-gpss-web是web相关,是controller层所在。依赖于lyyzoo-gpss-base、lyyzoo-starter-base等。

  lyyzoo-gpss-web > pom.xml:

 1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 "> 3     <modelVersion>4.0.0</modelVersion> 4     <parent> 5         <groupId>com.lyyzoo.gpss</groupId> 6         <artifactId>lyyzoo-gpss</artifactId> 7         <version>1.0-SNAPSHOT</version> 8     </parent> 9     <artifactId>lyyzoo-gpss-web</artifactId>10     <name>lyyzoo :: gpss :: web</name>11     <packaging>war</packaging>12 13     <dependencies>14         <dependency>15             <groupId>com.lyyzoo.gpss</groupId>16             <artifactId>lyyzoo-gpss-base</artifactId>17             <version>${project.version}</version>18         </dependency>19         <dependency>20             <groupId>com.lyyzoo</groupId>21             <artifactId>lyyzoo-starter-base</artifactId>22         </dependency>23         <dependency>24             <groupId>com.lyyzoo</groupId>25             <artifactId>lyyzoo-starter-jpa</artifactId>26         </dependency>27         <dependency>28             <groupId>com.lyyzoo</groupId>29             <artifactId>lyyzoo-starter-web</artifactId>30         </dependency>31         <dependency>32             <groupId>com.lyyzoo</groupId>33             <artifactId>lyyzoo-starter-test</artifactId>34         </dependency>35 36 37     </dependencies>38 39 40     <build>41         <finalName>gpss</finalName>42         <outputDirectory>src/main/webapp/WEB-INF/classes</outputDirectory>43     </build>44 45 </project>
View Code

2.系统配置

  工程建好后,首要要做的就是系统的配置工作了,如web.xml,这应该算是web项目的起点了。进入lyyzoo-gpss-web/src/main/webapp/WEB-INF/web.xml,进行web的配置,主要的一些配置有加载系统的配置文件、Spring、字符过滤器、SpringMVC等配置。

  一些基础的配置如下:

 1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns="http://java.sun.com/xml/ns/javaee" 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 5     " 6          version="3.0"> 7  8   <display-name>lyyzoo :: gpss</display-name> 9 10   <!-- 加载配置文件 -->11   <context-param>12     <param-name>contextConfigLocation</param-name>13     <param-value>classpath*:/spring/spring-base*.xml</param-value>14   </context-param>15 16   <!-- Spring -->17   <listener>18     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>19   </listener>20 21   <!-- 编码过滤器 -->22   <filter>23     <filter-name>encodingFilter</filter-name>24     <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>25     <init-param>26       <param-name>encoding</param-name>27       <param-value>UTF-8</param-value>28     </init-param>29     <init-param>30       <param-name>forceEncoding</param-name>31       <param-value>true</param-value>32     </init-param>33   </filter>34   <filter-mapping>35     <filter-name>encodingFilter</filter-name>36     <url-pattern>/*</url-pattern>37   </filter-mapping>38 39   <!-- 访问控制 -->40   <filter>41     <filter-name>VisitFilter</filter-name>42     <filter-class>com.lyyzoo.gpss.filter.VisitFilter</filter-class>43   </filter>44   <filter-mapping>45     <filter-name>VisitFilter</filter-name>46     <url-pattern>/admin/*</url-pattern>47   </filter-mapping>48 49   <!-- Spring MVC -->50   <servlet>51     <servlet-name>SpringMVC</servlet-name>52     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>53     <init-param>54       <param-name>contextConfigLocation</param-name>55       <param-value>classpath*:/spring/spring-web*.xml</param-value>56     </init-param>57     <load-on-startup>1</load-on-startup>58   </servlet>59   <servlet-mapping>60     <servlet-name>SpringMVC</servlet-name>61     <url-pattern>/</url-pattern>62   </servlet-mapping>63 64   <!-- 错误页面 -->65   <error-page>66     <error-code>404</error-code>67     <location>/error/404</location>68   </error-page>69   <error-page>70     <error-code>500</error-code>71     <location>/error/500</location>72   </error-page>73   <error-page>74     <exception-type>java.lang.Throwable</exception-type>75     <location>/error/500</location>76   </error-page>77 78   <!-- 首页 -->79   <welcome-file-list>80     <welcome-file>/</welcome-file>81   </welcome-file-list>82 83 </web-app>
View Code

  接着,配置系统将会用到的一些属性,如JDBC驱动、数据库用户名和密码等。在lyyzoo-gpss-web/src/main/resources/config下,创建config.properties配置文件,这个配置文件中的属性将会被底层spring配置的文件所引用。

  比如JDBC的属性:

 1 #################################### 2 #            DATABASE 3 #################################### 4 # local_db 5 jdbc.driver=net.sf.log4jdbc.DriverSpy 6 jdbc.url=jdbc:log4jdbc:mysql://localhost:3306/gpss?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false 7 jdbc.username=root 8 jdbc.password=root 9 10 # 初始化连接11 c3p0.initialPoolSize=512 # 连接池保留最小连接数13 c3p0.minPoolSize=514 # 连接池保留最大连接数15 c3p0.maxPoolSize=1516 # 最大空闲时间17 c3p0.maxIdleTime=60018 19 #hibernate20 hibernate.dialect=org.hibernate.dialect.MySQL5Dialect21 hibernate.show.sql=false22 hibernate.hbm2ddl.auto=update
View Code

  但是上面的配置只是本机的一个开发环境,如果我将项目发布到生产环境,那就至少需要重新修改数据库地址、用户名和密码。这样是比较麻烦的,所以,在lyyzoo-gpss-web/src/main/portable下创建两个xml文件,分别为开发环境和生产环境的:config-dev.xml和config-online.xml。

  config-online.xml:

 1 <?xml version="1.0" encoding="utf-8" ?> 2  3 <portable-config> 4     <config-file path="WEB-INF/classes/config/config.properties"> 5  6         <!-- JDBC --> 7         <replace key="jdbc.driver"><![CDATA[com.mysql.jdbc.Driver]]></replace> 8         <replace key="jdbc.url"><![CDATA[jdbc:mysql://192.168.1.91:30112/fff2f025c2b04?useUnicode=true&characterEncoding=utf-8]]></replace> 9         <replace key="jdbc.username">a6564a1169d94</replace>10         <replace key="jdbc.password">d3e6d1aea5e04</replace>11 12         <!-- hibernate -->13         <replace key="hibernate.show.sql">false</replace>14         <replace key="hibernate.hbm2ddl.auto">none</replace>15 16         <!-- debug -->17         <replace key="app.debug">false</replace>18         <replace key="app.env">online</replace>19         <replace key="logback.level">INFO</replace>20         <replace key="jdbc.resultsettable">ERROR</replace>21 22 23     </config-file>24 </portable-config>
View Code

  然后配置一个“不同环境打包”的maven插件——“portable-config-maven-plugin”,通过该插件,就可以在打包的时候加上需要打包的环境,例如指定online环境,在打包时就会将config-online.xml中的属性替换到config.properties里,这样一来就不必我们手动去替换了。配置好之后,我们在打包时可以使用命令[mvn clean package –Denv=online]打包线上环境的war包。

  maven环境配置,在lyyzoo-gpss > pom.xml中配置两个环境:

 1 <profiles> 2   <!-- 开发环境 --> 3   <profile> 4     <id>dev</id> 5     <activation> 6       <property> 7         <name>env</name> 8         <value>dev</value> 9       </property>10     </activation>11   </profile>12   <!-- 线上环境 -->13   <profile>14     <id>online</id>15     <activation>16       <property>17         <name>env</name>18         <value>online</value>19       </property>20     </activation>21   </profile>22 </profiles>
View Code

  不同环境打包插件(portable-config-maven-plugin)的配置:

 1 <build> 2   <plugins> 3     <plugin> 4       <groupId>com.juvenxu.portable-config-maven-plugin</groupId> 5       <artifactId>portable-config-maven-plugin</artifactId> 6       <version>1.1.5</version> 7       <executions> 8         <execution> 9           <goals>10             <goal>replace-package</goal>11           </goals>12         </execution>13       </executions>14       <configuration>15         <portableConfig>src/main/resources/portable/config-${env}.xml</portableConfig>16       </configuration>17     </plugin>18   </plugins>19 </build>
View Code

3.模块分层

  3.1 lyyzoo-gpss-base

  工程建好后,创建包的结构。按照一般的分层方式,分为dao层、entity层、service层,同时,每层下按模块划分为system、base、purchase、sale、stock。然后在entity下根据表设计创建实体类。

  lyyzoo-gpss-base 目录结构:

  

  3.2 lyyzoo-gpss-web

  然后是lyyzoo-gpss-web模块,该模块主要是controller层,以及静态资源文件、jsp文件等。com.lyyzoo.gpss.web作为controller层的包,同样,在web下按系统模块划分。

  lyyzoo-gpss-web 目录结构:

  

  3.3 静态资源文件

  lyyzoo-gpss-web/src/main/webapp/static作为静态文件的根目录,static/lib目录作为三方类库的根目录,如ExtJs、jQuery、其它的插件等。static/css是系统css文件的根目录;static/img是图片的根目录;static/js是系统js文件根目录,/js下同样按模块划分。

  静态资源文件目录结构:

  

  3.4 JSP文件

  jsp文件不能直接让用户访问,需要放到/WEB-INF下,与配置的spring视图解析器相对应,所有的jsp文件放到/WEB-INF/view目录下,view目录下按模块划分,index.jsp是系统的登录页面。/WEB-INF/layout/目录下,将jsp中需要引入的一些资源等做了整合,如ExtJs的文件、meta描述信息、taglib等,整合后,jsp中如果需要引入整合jsp即可,可减少很多重复的工作。

  taglib.jsp中引入了标签和设置了资源的路径:

 1 <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2  3 <%-- 引入标签 --%> 4 <%@taglib prefix="c" uri="" %> 5 <%@taglib prefix="fn" uri="" %> 6 <%@taglib prefix="fmt" uri="" %> 7 <%@taglib prefix="sf" uri="" %> 8  9 <%-- 资源路径 --%>10 <c:set var="CTX" value="${pageContext.request.contextPath}" />11 <c:set var="STATIC_CTX_URL" value="${CTX}/static" />12 <c:set var="LIB" value="${STATIC_CTX_URL}/lib" />13 <c:set var="JS" value="${STATIC_CTX_URL}/js"/>14 <c:set var="CSS" value="${STATIC_CTX_URL}/css"/>15 <c:set var="IMG" value="${STATIC_CTX_URL}/img"/>
View Code

  meta.jsp中主要设置了一些meta描述信息和ICO图标:

 1 <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 <%@ include file="/WEB-INF/layout/taglib.jsp" %> 3  4 <meta charset="utf-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=9,chrome=1"> 6  7 <meta name="description" content=""> 8 <meta name="author" content=""> 9 <meta name="renderer" content="webkit">10 <%-- 图标 --%>11 <link type="image/x-icon" href="${IMG}/favicon.ico" rel="icon">
View Code

  extjs-neptune.jsp则引入了ExtJs相关的css和js文件,以及jQuery等: 

 1 <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 <%@ include file="/WEB-INF/layout/taglib.jsp" %> 3  4 <link rel="stylesheet" type="text/css" href="${LIB}/ext/4.2.2/theme/ext-theme-neptune/ext-theme-neptune-all.css?1.1.11"/> 5 <link rel="stylesheet" type="text/css" href="${LIB}/ext/4.2.2/icons/icon.css?1.1.11"/> 6  7 <script type="text/javascript" src="${LIB}/ext/4.2.2/ext-all.js?1.1.11"></script> 8 <script type="text/javascript" src="${LIB}/ext/4.2.2/locale/ext-lang-zh_CN.js?1.1.11"></script> 9 <script type="text/javascript" src="${LIB}/jquery/2.1.1/jquery.js?1.1.11"></script>10 <script type="text/javascript" src="${JS}/Global.js?1.1.11"></script>11 12 <script type="text/javascript">13     window.CTX             = "${CTX}";14     window.STATIC_CTX_URL  = "${STATIC_CTX_URL}";15     window.LIB             = "${LIB}";16     window.JS              = "${JS}";17     window.CSS             = "${CSS}";18     window.IMG             = "${IMG}";19 </script>
View Code

  WEB-INF目录结构:

  

  3.4 登录实现举例

  首先创建一个BaseController,BaseController继承底层的BaseController,增加了HttpSession,以及获取当前登录用户的方法,这样其它的controller继承该BaseController后,就可以非常方便的获得当前session和登录用户了。

  BaseController代码如下:

 1 package com.lyyzoo.gpss.web; 2  3 import com.lyyzoo.gpss.entity.system.User; 4 import org.springframework.beans.factory.annotation.Autowired; 5  6 import javax.servlet.http.HttpSession; 7  8 /** 9  *10  * <p>11  *12  * @author bojiangzhou13  * @date 2017-04-0214  */15 public class BaseController extends com.lyyzoo.web.BaseController {16 17     @Autowired18     protected HttpSession session;19 20     public User getCurrentUser(){21         return (User) session.getAttribute("currentUser");22     }23 24     public Long getCurrentUserId(){25         return getCurrentUser().getId();26     }27 28     public String getCurrentUserAccount(){29         return getCurrentUser().getAccount();30     }31 32 }
View Code

  创建HomeController作为登录和主页的处理器。主要包含的方法有访问登录页面,访问登录后的主页,以及登录处理等。Controller需要加上@Controller标注该类为controller,使用@RequestMapping()支持访问rest形式的地址访问。HomeController中注入UserService,用于处理用户登录相关的业务。

  用户进入登录界面,jsp页面以的形式请求验证码,验证码使用工具类生成,以流的形式输出,生成的验证码保存到session中。用户输入登录账号、密码和验证码登录系统。首先前台会检测输入是否为空等,传到后台,从session中取出验证码判断验证码是否正确,不正确则刷新验证码并且需要用户重新输入验证码。验证码通过后,使用登录账号和密码查找数据库,如果有,则将该用户保存到session中,跳转到管理页面,登录成功。否则提示用户名或密码错误。

  HomeController代码如下:

  1 package com.lyyzoo.gpss.web;  2   3 import com.lyyzoo.gpss.entity.system.User;  4 import com.lyyzoo.gpss.service.system.UserService;  5 import com.lyyzoo.gpss.util.VCodeGenerator;  6 import com.lyyzoo.util.Cryptos;  7 import com.lyyzoo.util.Strings;  8 import org.springframework.beans.BeanUtils;  9 import org.springframework.beans.factory.annotation.Autowired; 10 import org.springframework.stereotype.Controller; 11 import org.springframework.web.bind.annotation.PathVariable; 12 import org.springframework.web.bind.annotation.RequestMapping; 13 import org.springframework.web.bind.annotation.RequestMethod; 14  15 import javax.imageio.ImageIO; 16 import javax.servlet.http.HttpServletResponse; 17 import javax.servlet.http.HttpSession; 18 import java.awt.image.BufferedImage; 19 import java.io.IOException; 20  21 /** 22  * <p> 23  * 24  * @author bojiangzhou 25  * @date 2017-03-29 26  */ 27 @Controller 28 @RequestMapping("") 29 public class HomeController extends BaseController { 30  31     @Autowired 32     private UserService userService; 33  34     /** 35      * 到首页/登录页面 36      */ 37     @RequestMapping(value = {"", "/", "/index", "/login"}) 38     public String index(){ 39         return "/index"; 40     } 41  42     /** 43      * 管理员主页 44      */ 45     @RequestMapping("/admin/home") 46     public String toHome(){ 47         return "/home/home"; 48     } 49  50     /** 51      * 登录 52      */ 53     @RequestMapping(value = "/login", method = RequestMethod.POST) 54     public String login(String account, String password, String vcode, HttpSession session){ 55         String redirect = REDIRECT("/login"); 56         //基本验证 57         if(Strings.isNullOrEmpty(account)){ 58             session.setAttribute("errorMsg", "账号必须填写!"); 59             return redirect; 60         } 61         if(Strings.isNullOrEmpty(password)){ 62             session.setAttribute("errorMsg", "密码必须填写!"); 63             return redirect; 64         } 65         if(Strings.isNullOrEmpty(vcode)){ 66             session.setAttribute("errorMsg", "验证码必须填写!"); 67             return redirect; 68         } 69         //验证码 70         String sessionVcode = (String) session.getAttribute("vcode"); 71         if(!vcode.equalsIgnoreCase(sessionVcode)){ 72             session.setAttribute("errorMsg", "验证码错误!"); 73             return redirect; 74         } 75         //验证用户名和密码 76         password = Cryptos.encryptMd5(password); 77         User loginUser = userService.login(account, password); 78         if(loginUser == null){ 79             session.setAttribute("errorMsg", "账号或密码错误!"); 80             return redirect; 81         } 82         if(loginUser.getIsLocked() == User.IsLocked.YES){ 83             session.setAttribute("errorMsg", "账号已锁定,不能登录!"); 84             return redirect; 85         } 86  87         //保存到session的时候清除密码 88         User currentUser = new User(); 89         BeanUtils.copyProperties(loginUser, currentUser); 90         currentUser.setPassword(null); 91  92         //登录成功 93         session.setAttribute("currentUser", currentUser); 94  95         return REDIRECT("/admin/home"); 96     } 97  98     /** 99      * 获取验证码100      */101     @RequestMapping("/vcode")102     public void getVCode(HttpSession session, HttpServletResponse response) throws IOException {103         //创建验证码生成器对象104         VCodeGenerator vcGenerator = new VCodeGenerator();105         //生成验证码106         String vcode = vcGenerator.generatorVCode();107         //将验证码保存在session域中,以便判断验证码是否正确108         session.setAttribute("vcode", vcode);109         //生成验证码图片110         BufferedImage vImg = vcGenerator.generatorRotateVCodeImage(vcode, true);111         //输出图像112         ImageIO.write(vImg, "gif", response.getOutputStream());113     }114 115     /**116      * 退出系统117      */118     @RequestMapping("/logoff")119     public String logoff(HttpSession session){120         session.invalidate();121         return REDIRECT("/");122     }123 124     @RequestMapping("/function")125     public String function(){126         return "/home/function";127     }128 129     @RequestMapping("/welcome")130     public String welcome(){131         return "/home/welcome";132     }133 134     /**135      * 错误页面136      * @param code137      * @return138      */139     @RequestMapping("/error/{code}")140     public String error(@PathVariable String code) {141         return "/error/" + code;142     }143 144 145 146 }
View Code

  UserService中根据用户名和密码获取用户:

 1 package com.lyyzoo.gpss.service.system; 2  3 @Service 4 public class UserService extends BaseService<User> { 5     @Autowired 6     private UserDao userDao; 7     /** 8      * 获取登录用户 9      */10     public User login(String account, String password){11         Map<String, Object> filter = new HashMap<>();12         filter.put("account", account);13         filter.put("password", password);14         filter.put("state", Applications.Flag.YES);15 16         User loginUser = get(filter);17         return loginUser;18     }19 }
View Code

7. Débogage et déploiement du système

1. Tests

Une fois le développement du système terminé, il doit d'abord être testé localement dans son ensemble, dès la connexion, chaque module, chaque fonction et chaque processus sont testés en détail.

Premier test si l'utilisateur n'est pas connecté, l'utilisateur ne peut pas accéder à la page de gestion Entrez l'adresse d'accès directement dans la barre d'adresse pour voir s'il accède à la page de connexion. Ensuite, testez au moins si le compte lié à chaque rôle est connecté normalement. Après la connexion, si le menu appartenant à chaque rôle s'affiche normalement.

Pour tester d'autres modules, utilisez le compte correspondant à chaque rôle pour vous connecter au système et tester les fonctions correspondantes. Par exemple, l'administrateur entre dans le système pour saisir des données de base, des informations sur les produits, des informations sur l'entrepôt, etc. L'administrateur des achats saisit les informations sur les fournisseurs, saisit les bons de commande et les soumet pour révision. L'administrateur des ventes saisit les informations client, saisit les commandes client et les soumet pour révision. Le gestionnaire des stocks examine le bon de commande, et si l'examen réussit, le stock augmentera ; si la commande client réussit l'examen, le stock diminuera. Vérifiez les informations d'inventaire et effectuez les opérations correspondantes pour voir si le montant de l'inventaire est correct. Les résultats des tests peuvent être consultés dans les captures d'écran des tests du système.

Les tests de tolérance aux pannes du système testent principalement le comportement du système dans des conditions anormales en saisissant des types de données incorrects et des valeurs hors plage. Le système fait un meilleur travail à cet égard. Si l'utilisateur saisit des données illégales, il lui rappellera immédiatement de saisir les données correctes. Premièrement, la légalité des données saisies par l'utilisateur et si elles doivent être saisies seront jugées dans le frontend. Une fois les données transmises au backend, il sera également jugé dans le code si les données sont correctes avant d'être enregistrées. à la base de données. Le Jdbc utilisé par le système peut également empêcher dans une certaine mesure l'injection SQL et d'autres problèmes. Si des exceptions imprévisibles se produisent dans le système, l'utilisateur sera invité avec une interface conviviale afin que les techniciens puissent maintenir le système en temps opportun.

D'une manière générale, l'ensemble du processus de test s'est déroulé sans problème. Il y a eu quelques problèmes mineurs, qui ont été résolus immédiatement. Toutes les fonctions ont été mises en œuvre et le système peut répondre à un processus de base d'achat, de vente et d'inventaire, et peut être étendu à l'avenir.

2. Déploiement

J'utilise Mopo Cloud pour déployer le projet. Mopo Cloud est facile à utiliser et gratuit dans une certaine limite. Il est plus adapté au déploiement et aux tests. Tout d'abord, créez une application Java nommée gpss sur Mobo Cloud, puis créez un service MySQL, liez-le à l'application Java et copiez la connexion à la base de données dans le fichier de configuration. Exportez la base de données GPS locale et importez-la dans l'application MySQL créée. Utilisez ensuite la commande mvn clean package –Denv=online dans IDEA pour empaqueter le package war pour l'environnement en ligne et publier le package war sur Mobo Cloud. Démarrez le projet, puis accédez et testez, tout est normal. Vous pouvez accéder au nom de domaine pour l'afficher. Le problème de compatibilité d'ext n'ayant pas été bien résolu, il est recommandé d'utiliser Google Chrome pour l'afficher. Plus tard, nous apprendrons comment déployer sur des cloud tels qu'Alibaba Cloud.

8. Résumé

En concevant et en complétant étape par étape ce système d'achat, de vente et d'inventaire de conduites de gaz, j'ai une meilleure compréhension de l'architecture, de la conception, du logiciel. framework, codage, et je suis plus compétent dans l'utilisation de divers outils et familier avec le processus de développement logiciel. Ce système est le produit des connaissances acquises au cours de quatre années d'études collégiales. Depuis l'obtention de la proposition de thèse, la compréhension de la proposition, la consultation des informations pertinentes, la réalisation d'une analyse de la demande, la conception de modules fonctionnels et la conception de bases de données, puis la combinaison de mon expérience de travail au cours du cours. stage et entreprise La conception architecturale construit sa propre couche inférieure. Le développement du système est réalisé sur cette base sous-jacente.

Après près d'un mois de projet de fin d'études, j'ai maîtrisé les connaissances pertinentes dans tous les aspects du développement logiciel, me suis familiarisé avec l'ensemble du processus et testé mon niveau de connaissances en quatre années d'université. De toute évidence, il existe encore de nombreuses lacunes. Par exemple, bien que le framework SSH soit utilisé dans ce système, il reste encore de nombreuses choses qui ne sont pas claires quant au principe de mise en œuvre du framework. Personnellement, je crois que lorsqu’on apprend, il faut savoir ce qui se passe et pourquoi. Surtout pour la technologie, il faut comprendre ses principes sous-jacents afin d’améliorer ses capacités. Ceux-ci seront progressivement améliorés dans les travaux futurs.

C'est fondamentalement la fin de l'écriture. C'est mon dernier blog depuis quatre ans à l'université. Désormais, j'étudierai au travail.

Je suis très heureux parce que je quitte l'école et que je peux aller travailler pour trouver de l'argent ; je suis très triste parce que je quitte l'école et le moment le plus confortable de ma vie est peut-être mon temps à l'université.

J'aime beaucoup mon école - l'Université du Sud-Ouest, située au pied de la montagne Jinyun, avec un bel environnement et de belles femmes, haha ​​!

9. Pièce jointe

Enfin, les documents liés au développement du système sont partagés : Système d'achat, de vente et d'inventaire d'équipements de réseau de gazoducs

L'annuaire des le package compressé est le suivant :

 

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn