CRM客户管理系统

CRM客户管理系统

数据库

主键字段

在数据库设计中,如果有一组字段能够唯一确定一条记录,则可以把他们设计成表的主键,推荐使用一个字段做主键,而且推荐使用没有业务含义的字段做主键。

设置主键有两种方式

  1. 数据库自增,但是这个数据库自增,数据库会开辟出一个线程专门管理数据库自增的信息,当我们有多个并发的进程需要进行插入操作时,数据库会上锁,只允许一个一个的进行,效率比较低下你真的懂自增主键(auto_increment)?_wind_huise的博客-CSDN博客_自增主键
  2. 使用uuid,uuid使jdk自带的字段,我们可以使用这个类生成32位的不重复的字段作为主键,而且速度快,并不会引起效率降低

外键字段

外键用来确定表与表之间的关系,表与表之间存在1对1,1对多等等关系,当然如果外键不能为空,则使用内连接,如果外键可以为空,使用外连接。但是如果两种都可以使用,建议使用内连接,速度比较快

日期和事件的字段

data:年月日,time:时分秒 datatime:年月日时分秒

而由于sql中与Java之间的日期转换比较麻烦,所以在数据库中我们使用string类型进行存储

char(10):yyyy–MM–dd

char(19):yyyy–MM–dd HH:mm:ss

搭建开发环境

添加依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
<?xml version="1.0" encoding="UTF-8"?>

<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.moonshuo.crm</groupId>
<artifactId>crm</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>

<name>crm Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>https://www.example.com</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!-- MySQL数据库连接驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
<!-- JDBC数据源连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.9</version>
</dependency>
<!-- MyBatis框架依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
<!-- Spring框架依赖的JAR配置 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.20</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.20</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.20</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.3.20</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.20</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.3.20</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.20</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.20</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>5.3.20</version>
</dependency>
<!-- Spring AOP支持-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.9.1</version>
</dependency>
<!-- MyBatis与Spring整合依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.7</version>
</dependency>
<!-- servlet及jstl标签库依赖的JAR配置 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<!-- 加载jackson插件依赖 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.13.3</version>
</dependency>
<!--poi依赖-->
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.2</version>
</dependency>
<!-- 文件上传 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<!-- Log4j2依赖的JAR配置 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.17.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.36</version>
<scope>compile</scope>
</dependency>
<!-- Spring5和Thymeleaf整合包 -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.15.RELEASE</version>
</dependency>

</dependencies>

<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
</build>

</project>

设置编码格式

image-20220605144827804

添加配置文件

mybatis配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--打印日志-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--指明对象的位置-->
<typeAliases>
<package name="com.zss.pojo"/>
</typeAliases>
<!--指明mapper文件位置-->
<mappers>
<package name="com.zss.mapper"/>
</mappers>
</configuration>

配置数据链接和事务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!--读取jdbc.properties配置文件的支持-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 配置数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="url" value="${jdbc.url}"/>
</bean>
<!-- 配置SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 必须注入属性dataSource -->
<property name="dataSource" ref="dataSource"/>
<!-- 如果mybatis没有特殊的配置(比如别名等),configLocation可以省去 ;否则,不能省略-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<!-- mapper注解扫描器配置,扫描@MapperScan注解,自动生成代码对象 -->
<bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--这个basePackage和mybatis-config中的mappers标签作用有什么区别-->
<property name="basePackage" value="com.moonshuo.crm.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>

<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置事务 -->
<aop:config>
<aop:pointcut expression="execution(* com.moonshuo.crm..service.*.*(..))" id="allMethodPointcut"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="allMethodPointcut"/>
</aop:config>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="save*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="edit*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="do*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="*" propagation="REQUIRED" read-only="true"/>
</tx:attributes>
</tx:advice>
</beans>

mvc配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- dispatcherServlet截获所有URL请求 -->
<mvc:default-servlet-handler/>
<!--thymeleaf视图解析器-->
<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="order" value="1"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
</property>
</bean>
</property>
</bean>



<!-- spring mvc 扫描包下的controller -->
<context:component-scan base-package="org.zuel.crm.web.controller"/>
<context:component-scan base-package="org.zuel.crm.settings.web.controller"/>
<context:component-scan base-package="org.zuel.crm.workbench.web.controller"/>

<!-- 配置注解驱动 -->
<mvc:annotation-driven/>

<!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/settings/**"/>
<mvc:mapping path="/workbench/**"/>
<!--登录页面和登录跳转验证要排除(排除拦截的优先级高于拦截)-->
<mvc:exclude-mapping path="/settings/qx/user/toLogin.do"/>
<mvc:exclude-mapping path="/settings/qx/user/login.do"/>
<!--拦截器类-->
<bean class="org.zuel.crm.settings.web.interceptor.LoginInterceptor" />
</mvc:interceptor>
</mvc:interceptors>

<!--
path:设置处理的请求地址
view-name:设置请求地址所对应的视图名称
-->
<!-- <mvc:view-controller path="/" view-name="index"></mvc:view-controller>-->

<!-- 虽然爆红,但是可以正常使用-->
<!-- <mvc:view-controller path="/" view-name="index"/>-->


<!-- 配置文件上传解析器 id:必须是multipartResolver-->
<!--<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="#{1024*1024*80}"/>
<property name="defaultEncoding" value="utf-8"/>
</bean>-->
</beans>

总配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 加载系统配置文件
<context:property-placeholder location="classpath:*.properties" />-->
<!-- 扫描注解 -->
<context:component-scan base-package="com.moonshuo.crm.service" />
<!-- 导入数据相关配置 -->
<import resource="applicationContext-datasource.xml" />
</beans>

配置web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="dataservice" version="3.0">
<display-name>dataservice application</display-name>
<!-- spring监听器加载applicationContext.xml配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- spring字符过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Spring mvc分发servlet -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- 欢迎页,默认进入index controller -->
<welcome-file-list>
<welcome-file>/</welcome-file>
</welcome-file-list>
<!--<error-page>
<error-code>404</error-code>
<location>/settings/error/to404Page.do</location>
</error-page>-->
</web-app>

配置maven的编译选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
</build>

注意放置文件的时候,web根目录下面数据都是不安全的,所以一般放到wen-inf下面,是受到保护的,而图片则放置到根目录下面。

测试

配置服务器,查看是否搭建成功

编码实现

image-20220605161143174

setting表示系统管理功能,而workbench表示业务管理功能

系统管理功能

首页

分析需求:

image-20220605163220625

编码实现:

设置mvc扫描这个包

登录功能实现

image-20220608152802924

我们这里的respondbody返回的对象,但是还需要携带相应的状态码等等,所以我们使用新建立一个对象,可以包含状态码和user对象等等

逆向工程创建类

1
2
3
4
5
6
7
8
9
10
11
12
13
<build>
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
</plugins>
</build>

加入插件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<!--上面爆红可以不用管-->
<generatorConfiguration>
<!--这个需要配置一个jar包的位置,一般在maven长裤里面就直接找到了-->
<classPathEntry location="D:\Maven\maven-repository\mysql\mysql-connector-java\8.0.29\mysql-connector-java-8.0.29.jar"/>
<!--
targetRuntime: 执行生成的逆向工程的版本
MyBatis3Simple: 生成基本的CRUD(清新简洁版 增删改)
MyBatis3: 生成带条件的CRUD(奢华尊享版 )
-->
<context id="DB2Tables" targetRuntime="MyBatis3Simple">
<commentGenerator>
<!-- 是否去除自动生成的注释 -->
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!-- 数据库的连接信息 -->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/crm"
userId="root"
password="200101">
</jdbcConnection>
<!-- javaBean的生成策略-->
<javaModelGenerator targetPackage="com.moonshuo.crm.pojo" targetProject=".\src\main\java">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" /><!--去掉空格-->
</javaModelGenerator>
<!-- SQL映射文件的生成策略 -->
<sqlMapGenerator targetPackage="com.moonshuo.crm.mapper"
targetProject=".\src\main\resources">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- Mapper接口的生成策略 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.moonshuo.crm.mapper" targetProject=".\src\main\java">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!-- 逆向分析的表 -->
<!-- tableName设置为*号,可以对应所有表,此时不写domainObjectName -->
<!-- domainObjectName属性指定生成出来的实体类的类名 -->
<table tableName="tbl_user" domainObjectName="User"/>
</context>
</generatorConfiguration>

配置文件

功能优化

标志码

image-20220705164207995

这些0与1代表成功与否的标识码,0代表失败,而1代表成功,但是将来如果我们又因为业务要求需要开发许多的标志信息,那么这些的修改就比较冗余,所以我们将这些标志封装成一个常量类

1
2
3
4
5
public class Contants {
//保存标志位
public static final String RETURN_OBJECT_CODE_SUCCESS="1";
public static final String RETURN_OBJECT_CODE_FAIL="0";
}

image-20220705165922915

session名称问题

image-20220705175853289

这个sessionUser在这里其实已经写死了,但是如果我们需要进行更改,并且多个地方进行更改的时候,就会变得麻烦,所以我们使用和上述同样的方法,定义一个常量

image-20220705180129689