目录
1、需求
2、项目准备
pom.xml
SQL
jdbc.properties
log4j.properties
applicationContext.xml
spring-mvc.xml
web.xml
3、工作流程
4、难点
项目已经上传到gitee:https://gitee.com/xzl-it/my-projects
SpringMVC项目练习:数据后台管理系统
结合MVC和三重架构,使用Spring和SpringMVC实现前后端交互的web应用。
项目页面实现如下:
Spring环境搭建步骤
① 创建工程 (Project&Module)
② 导入静态页面 (这部分后面再细讲)
③ 导入需要坐标 (pom.xml)
④ 创建包结构 (controller、service、dao、domain、utils)
⑤ 执行对应的sql语句
⑥ 创建POJO类 (User.java和Role.java)
⑦ 创建配置文件 (applicationContext.xml、spring-mvc.xml、jdbc.properties、log4j.properties)
总体环境搭建完成后,目录结构如下:
下面是项目需要的配置文件:
4.0.0
org.example
projectForSpringMVC
1.0-SNAPSHOT
war
11
11
org.apache.tomcat.maven
tomcat7-maven-plugin
2.2
8080
UTF-8
mysql
mysql-connector-java
5.1.32
c3p0
c3p0
0.9.1.2
com.alibaba
druid
1.1.10
junit
junit
4.12
test
org.springframework
spring-context
5.0.5.RELEASE
org.springframework
spring-test
5.0.5.RELEASE
org.springframework
spring-web
5.0.5.RELEASE
org.springframework
spring-webmvc
5.0.5.RELEASE
javax.servlet
javax.servlet-api
3.0.1
provided
javax.servlet.jsp
javax.servlet.jsp-api
2.2.1
provided
com.fasterxml.jackson.core
jackson-core
2.9.0
com.fasterxml.jackson.core
jackson-databind
2.9.0
com.fasterxml.jackson.core
jackson-annotations
2.9.0
commons-fileupload
commons-fileupload
1.3.1
commons-io
commons-io
2.3
commons-logging
commons-logging
1.2
org.slf4j
slf4j-log4j12
1.7.7
log4j
log4j
1.2.17
org.springframework
spring-jdbc
5.0.5.RELEASE
org.springframework
spring-tx
5.0.5.RELEASE
jstl
jstl
1.2
/* 创建数据库 'SpringMVC' */
CREATE DATABASE IF NOT EXISTS `SpringMVC` DEFAULT CHARACTER SET utf8;
/* 使用数据库 'SpringMVC' */
USE `SpringMVC`;
/* 创建表 'sys_role' */
DROP TABLE IF EXISTS `sys_role`;
CREATE TABLE `sys_role` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`roleName` varchar(50) DEFAULT NULL,
`roleDescription` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
/* 插入数据到表 'sys_role' */
INSERT INTO `sys_role`(`id`,`roleName`,`roleDesc`)
VALUES (1,'院长','负责全面工作'),
(2,'研究员','课程研发工作'),
(3,'讲师','授课工作'),
(4,'助教','协助解决学生的问题');
/* 创建表 'sys_user' */
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(50) DEFAULT NULL,
`email` varchar(50) DEFAULT NULL,
`password` varchar(80) DEFAULT NULL,
`phoneNum` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
/* 插入数据到表 'sys_user' */
INSERT INTO `sys_user`(`id`,`username`,`email`,`password`,`phoneNum`)
VALUES (1,'zhangsan','[email protected]','123','13888888888'),
(2,'lisi','[email protected]','123','13999999999'),
(3,'wangwu','[email protected]','123','18599999999');
/* 创建表 'sys_user_role' */
DROP TABLE IF EXISTS `sys_user_role`;
CREATE TABLE `sys_user_role` (
`userId` bigint(20) NOT NULL,
`roleId` bigint(20) NOT NULL,
PRIMARY KEY (`userId`,`roleId`),
KEY `roleId` (`roleId`),
CONSTRAINT `sys_user_role_ibfk_1` FOREIGN KEY (`userId`) REFERENCES `sys_user` (`id`),
CONSTRAINT `sys_user_role_ibfk_2` FOREIGN KEY (`roleId`) REFERENCES `sys_role` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/* 插入数据到表 'sys_user_role' */
INSERT INTO `sys_user_role`(`userId`,`roleId`)
VALUES (1,1),
(1,2),
(2,2),
(2,3);
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/springmvc
jdbc.username=root
jdbc.password=xzlXZGK680
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c:/mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### set log levels - for more verbose logging change 'info' to 'debug' ###
log4j.rootLogger=info, stdout
CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
CharacterEncodingFilter
/*
contextConfigLocation
classpath:applicationContext.xml
org.springframework.web.context.ContextLoaderListener
DispatcherServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:spring-mvc.xml
2
DispatcherServlet
/
这里以一个请求动作进行举例:
前端对后端服务器的请求,被前端控制器全部拦截,交由对应的控制器;
控制器调用业务逻辑层代码,封装模型和视图;
业务逻辑层调用数据访问层代码,封装需要的数据进行返回;
最后返回到控制器进行全部封装完成,相应到对应的视图资源进行返回前端。
总体过程如图:
这个过程主要是多表查询,要分清楚主键约束,即删表的时候要先删用户表,再删关系表。
还有一个就是存储过程中,用户的id是由MySQL自动生成的,存储过程获取不到,这里使用PreparedStatementCreator。
在UserDaoImpl.java中:
@Override
public Long save(final User user) {
// 创建PreparedStatementCreator,用于构建PreparedStatement
PreparedStatementCreator creator = new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
// 使用原始jdbc完成PreparedStatement的组建
PreparedStatement preparedStatement = connection.prepareStatement("insert into sys_user values(?,?,?,?,?)", PreparedStatement.RETURN_GENERATED_KEYS);
preparedStatement.setObject(1, null); // 设置第一个占位符为NULL,通常用于表示主键自动生成
preparedStatement.setString(2, user.getUsername()); // 设置第二个占位符为用户的用户名
preparedStatement.setString(3, user.getEmail()); // 设置第三个占位符为用户的电子邮件地址
preparedStatement.setString(4, user.getPassword()); // 设置第四个占位符为用户的密码
preparedStatement.setString(5, user.getPhoneNum()); // 设置第五个占位符为用户的电话号码
return preparedStatement;
}
};
// 创建keyHolder,用于获取自动生成的主键
GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
// 使用jdbcTemplate执行SQL插入,并将生成的主键保存到keyHolder中
jdbcTemplate.update(creator, keyHolder);
// 获得生成的主键
long userId = keyHolder.getKey().longValue();
// 返回当前保存用户的id,该id是数据库自动生成的
return userId;
}