SSM超市订单管理项目
项目演示和介绍
是不是苦于学完东西找不到地方输出,找不到一个好的项目练手?那么你算是找对地方了,我将带给你一个非常适合ssm入门实战项目,使用maven搭建,让你熟练掌握SSM整合开发!
- 技术栈:Spring+SpringMVC+Mybatis+Ajax+原生分页实现·····不多逼逼,先上效果图:
- 项目已实现功能:用户登录,用户角色分类,用户列表查询,密码修改、ajax异步请求,用户增删改,分页及条件查询!
功能不多也不少,非常适合入门实战,前端静态资源完整,数据库也完整,文章末尾有获取方式!接下来挑一些功能代码讲解
一、项目结构及依赖导入
1、结构图
都能看懂,很友好
2、pom.xml
<dependencies>
<!-- mybatis依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
<!-- 数据库连接-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.3</version>
</dependency>
<!--spring AOP的包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>javax.servlet.jsp.jstl-api</artifactId>
<version>1.2.2</version>
</dependency>
<!-- standard标签库-->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
二、SSM整合,脚手架搭建
spring层----spring-mapper.xml
<?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
https://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!-- 配置初始化大小,最大,最小-->
<property name="initialSize" value="${jdbc.init}"></property>
<property name="minIdle" value="${jdbc.minIdle}"></property>
<property name="maxActive" value="${jdbc.maxActive}"></property>
<!-- 配置获取连接等待超时时间-->
<property name="maxWait" value="60000"></property>
<!-- 配置间隔多久时间才能进行一次检测,检测需要关闭的空闲连接,单位是毫秒-->
<property name="timeBetweenEvictionRunsMillis" value="60000"></property>
<!-- 配置一个连接池中最小生存时间,单位是毫秒-->
<property name="minEvictableIdleTimeMillis" value="300000"></property>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
</bean>
<!-- 配置扫描Dao接口包,动态实现Dao接口注入到spring容器中-->
<bean id="MapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- dao接口所在的包,如果有多个包逗号或分号分隔-->
<!-- <property name="basePackage" value="com.a.dao,com.b.dao"></property>-->
<property name="basePackage" value="com.song.mapper"></property>
<!-- 注入 sqlsessionfactory 如果工厂只有一个sqlsessionfactory的bean此配置可以省略-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
</beans>
spring层----spring-mvc.xml
<?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:mvc="http://www.springframework.org/schema/mvc"
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
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd ">
<!-- 注解扫描-->
<context:component-scan base-package="com.song.controller" >
</context:component-scan>
<!-- 静态资源默认的servlet配置-->
<!-- 静态资源访问 实际字需要这一句,上一句我们一般都加上-->
<mvc:default-servlet-handler/>
<!-- 注解驱动-->
<mvc:annotation-driven>
<!-- 安装Fastjson转换器-->
<mvc:message-converters register-defaults="false">
<bean id="fastJsonHttpMessageConverter"
class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<!-- 加入支持的媒体类型:返回contentType -->
<property name="supportedMediaTypes">
<list>
<!-- 这里顺序不能反,一定先写text/html,不然ie下会出现下载提示 -->
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="jsp/**"/>
<bean id="UserInterceptor" class="com.song.filter.UserInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
<!-- 视图解析器
作用 :1.捕获后端控制器的返回值 如果返回的是hello
2.解析:在返回值前后拼接 "/hello.jsp"
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀-->
<property name="prefix" value=""></property>
<!-- 后缀-->
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
spring----spring-service.xml
<?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">
<!-- 扫描service下的包 也就是扫描相关的bean-->
<context:component-scan base-package="com.song.service"/>
<!-- 将我们的所有业务类,注入到spring,可以通过配置或者注解实现-->
<bean id="UserServiceImpl" class="com.song.service.UserServiceImpl">
<property name="userMapper" ref="userMapper"></property>
</bean>
<bean id="RoleServiceImpl" class="com.song.service.RoleServiceImpl">
<property name="roleMapper" ref="roleMapper"></property>
</bean>
<!-- 引入一个事务管理器,其中依赖DataSource,借以获取连接,进而控制事务逻辑-->
<bean id="tx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据源-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- aop事务支持-->
</beans>
mybatis整合----mybatis-config.xml
<?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.song.pojo"/>
</typeAliases>
<!-- mapper注册-->
<mappers>
<mapper class="com.song.mapper.UserMapper"/>
<mapper class="com.song.mapper.RoleMapper"/>
</mappers>
</configuration>
数据库相关----jdbc.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/smbms?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=123456
jdbc.init=1
jdbc.minIdle=1
jdbc.maxActive=10
总配置-----aplicationcontext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="spring-mapper.xml"></import>
<import resource="spring-service.xml"></import>
<import resource="spring-mvc.xml"></import>
</beans>
到这里脚手架就搭建好了,接下来的开发就是最简单的部分了
三、实体类POJO
User,用户
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id; //id
private String userCode; //用户编码
private String userName; //用户名称
private String userPassword; //用户密码
private Integer gender; //性别
private Date birthday; //出生日期
private String phone; //电话
private String address; //地址
private Integer userRole; //用户角色
private Integer createdBy; //创建者
private Integer modifyBy; //更新者
private Date creationDate; //创建时间
private Date modifyDate; //更新时间
private Integer age; //年龄
private String userRoleName; //用户角色名称
}
Role,角色
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Role {
private Integer id; //id
private String userCode; //角色编码
private String roleName; //角色名称
private Integer createdBy; //创建者
private Date creationDate; //创建时间
private Integer modifyBy; //更新者
private Date modifyDate; //更新时间
}
四、用户登录及验证
代码优先从底层写起,这样行云流水,一气呵成!
1、UserMapper接口:一个方法,查询用户是否存在
//登录
User getNameAndPassword(@Param("username") String userName,@Param("password") String password);
2、写了mapper就应该有一个对应的mapper.xml用来写对应的sql语句,
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.song.mapper.UserMapper">
<select id="getNameAndPassword" resultType="user">
select * from smbms.smbms_user where userCode=#{username} and userPassword=#{password}
</select>
</mapper>
3、然后再到service层
UserService接口
//登录
User getUserByNameAndPwd(@Param("username") String username, @Param("password") String password);
UserServiceImpl
//拿到登录用户
public User getUserByNameAndPwd(String username, String password) {
return userMapper.getNameAndPassword(username,password);
}
4、姐下来就是Controller层了
UserController
@Controller
@RequestMapping("jsp")
public class UserController {
@Autowired
@Qualifier("UserServiceImpl")
private UserService userService;//注入bean,自动装配
//登录
@RequestMapping(value = "login",produces = "text/html;charset=UTF-8;")
public String login(String username,String password,HttpSession session) {
System.out.println("进入登录方法");
User userByNameAndPwd = userService.getUserByNameAndPwd(username,password);
if (userByNameAndPwd == null){
return "login";
}else{
session.setAttribute("user",userByNameAndPwd);
return "frame";
}
}
}
实现完毕,
五、重难点:用户管理(包含查询用户列表,动态SQL,分页)
mapper和mapper.xml
//查询数据
List<User> getUserList(@Param("username") String queryname,@Param("userrole") int queryUserRole,@Param("current") int currentPageNo,@Param("pagesize") int pageSize);
//查询用户总数
int getCount(@Param("username") String queryname,@Param("userrole") int queryUserRole);
- 动态Sql(重点)
<select id="getUserList" resultType="user">
select u.*,r.roleName as userRoleName from smbms.smbms_user u,smbms.smbms_role r where u.userRole = r.id
<if test="username!=null and username!=''">
and u.userName like "%"#{username}"%"
</if>
<if test="userrole > 0">
and u.userRole = #{userrole}
</if>
order by u.creationDate DESC limit #{current},#{pagesize}
</select>
<select id="getCount" resultType="int">
select count(1) as count from smbms_user u, smbms_role r where u.userRole = r.id
<if test="username!=null and username!='' ">
and u.userName like "%"#{username}"%"
</if>
<if test="userrole > 0">
and u.userRole = #{userrole}
</if>
</select>
service层.
//返回用户列表
public List<User> getUserList(String queryname,int queryUserRole,int currentPageNo,int pageSize) {
int current=(currentPageNo-1)*pageSize;//计算第几页
return userMapper.getUserList(queryname,queryUserRole,current,pageSize);
}
//得到用户总数
public int getCount(String queryname, int queryUserRole) {
//int current=(currentPageNo-1)*pageSize;
//System.out.println("current==="+current);
return userMapper.getCount(queryname, queryUserRole);
}
controller层
//查询用户
@RequestMapping("query")
public String userList(String queryname,@Param("queryUserRole") String queryUserRole1,String pageIndex, Model mv){
Page page = new Page();
int currentPageNo =1;
int queryUserRole;
page.setCurrentPageNo(currentPageNo);
if ( pageIndex!= null) {
System.out.println("pageIndex---->"+pageIndex);
page.setCurrentPageNo(Integer.parseInt(pageIndex));
}
currentPageNo= page.getCurrentPageNo();
int pageSize = page.getPageSize();
System.out.println("queryUserRole1=="+queryUserRole1);
if (queryUserRole1 != null) {
queryUserRole = Integer.parseInt(queryUserRole1);
}else {
queryUserRole=0;
}
List<User> userList = userService.getUserList(queryname, queryUserRole, currentPageNo, pageSize);
int totalCount = userService.getCount(queryname, queryUserRole);
page.setTotalCount(totalCount);
int totalCount1 = page.getTotalCount();
int totalPageCount = page.getTotalPageCount();
List<Role> roleList = roleService.getRoleList();
mv.addAttribute("queryUserName",queryname);
mv.addAttribute("roleList",roleList);
mv.addAttribute("totalCount",totalCount1);
mv.addAttribute("totalPageCount",totalPageCount);
mv.addAttribute("currentPageNo",currentPageNo);
mv.addAttribute("userList",userList);
return "userlist";
}
因为涉及到分页需要一个分页的类来帮助我们实现分页,
package com.song.pojo;
public class Page {
//当前页码-来自于用户输入
private int currentPageNo;
//总数量(表)
private int totalCount = 0;
//页面容量
private int pageSize = 5;
//总页数-totalCount/pageSize(+1)
private int totalPageCount = 1;
public int getCurrentPageNo() {
return currentPageNo;
}
public void setCurrentPageNo(int currentPageNo) {
if(currentPageNo > 0){
this.currentPageNo = currentPageNo;
}
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
if(totalCount > 0){
this.totalCount = totalCount;
//设置总页数
this.setTotalPageCountByRs();
}
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
if(pageSize > 0){
this.pageSize = pageSize;
}
}
public int getTotalPageCount() {
return totalPageCount;
}
public void setTotalPageCount(int totalPageCount) {
this.totalPageCount = totalPageCount;
}
public void setTotalPageCountByRs(){
if(this.totalCount % this.pageSize == 0){
this.totalPageCount = this.totalCount / this.pageSize;
}else if(this.totalCount % this.pageSize > 0){
this.totalPageCount = this.totalCount / this.pageSize + 1;
}else{
this.totalPageCount = 0;
}
}
}
- 整个项目难点就在这儿,如果把这块啃下来了,其他的也就是小菜一碟罢了,所以,其他功能我就不展示了,
结尾:前端静态资源和数据库获取
项目我只做完了一半,另一半也是增改查没什麽难点了所以就不打算做了,想练手的可以找我拿我写好的源码仿照着把订单模块完成,
需要的小伙伴可以留言我发给你,过段时间上传到gitee仓库!