目录
完成一个前后端分离的Vue+SSM小项目
一.预备步骤
Step1:创建表
Step2:创建maven项目,添加web框架,继承tomcat。
Step3:修改pom.xml文件
<?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>org.example</groupId> <artifactId>Pro1</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!-- JSTL依赖--> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- 添加Jackson依赖--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.8</version> </dependency> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.2.0</version> </dependency> <!-- 单元测试--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.3.19</version> </dependency> <!-- springMVC依赖--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.19</version> </dependency> <!-- servlet依赖--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <!-- mybatis--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.7</version> </dependency> <!--mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.27</version> </dependency> <!-- 日志信息--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.12</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.19</version> </dependency> <!-- spring-context 核心ioc--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.19</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.3.19</version> </dependency> <!-- spring-aspects--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.3.19</version> </dependency> <!-- aop--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.3.19</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>5.3.19</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.3.19</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> <version>5.3.19</version> </dependency> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.1</version> </dependency> <!-- 阿里公司数据库连接池--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.12</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> </dependency> </dependencies> <!-- 插件配置 --> <build> <plugins> <!-- 指定编译的JDK的版本和项目部署到客户端环境中的JDK的版本和编码。 可以在插件中配置也可以在<properties>标签中配置--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>16</source> <target>16</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> <!--识别所有的配置文件--> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build> </project>
Step4:添加jdbc.properties属性文件
jdbc.driverClassName=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/ssmuser jdbc.username=root jdbc.password=niit
Step5:添加SqlMapConfig.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> <!-- 设置日志输出语句,显示响应操作的sql语名--> <settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> <plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin> </plugins> </configuration>
Step6:添加数据访问层的核心配置文件(也是spring核心配置文件之一)applicationContext-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:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p" 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-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tool"> <!-- 读取属性文件--> <context:property-placeholder location="classpath:mybatis/jdbc.properties"></context:property-placeholder> <!-- 配置数据源--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}"></property> <property name="url" value="${jdbc.url}"></property> <property name="username" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </bean> <!-- 配置sqlSessionFactoryBean--> <bean class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 配置数据源--> <property name="dataSource" ref="dataSource"></property> <!-- 配置SqlMapConfig.xml核心配置文件--> <property name="configLocation" value="classpath:mybatis/sqlMapConfig.xml"></property> <!-- 注册实体类--> <property name="typeAliasesPackage" value="pojo"></property> </bean> <!-- 注册mapper.xml文件--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="mapper"></property> </bean> </beans>
1.注意要加classPath,表示在编译后的类路径下去找。但凡指定路径去读取文件都要加classpath。
2. 配置数据源,引用上方的数据源,mybatis核心配置文件也要配置,因为spring无法接管所有的mybatis功能配置,注册实体类,实体类就是数据库数据的映射。
3.思考applicationContext-mapper中各个标签存在的必要性
mapper层首先要访问数据库,所以要配置访问数据库的有关信息-即属性文件和数据源的作用
sqlSessionFactoryBean就是提供与数据库的对话对象
配置mapper,具体的mapper通过sqlSession来访问具体的数据
4.mapper -> sqlSession -> 数据库信息(数据源-》来自属性文件)
Step7:添加业务逻辑层的核心配置文件(也是spring核心配置文件之一)applicationContext-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:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/aop" 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.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/tool http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> <!-- 添加包扫描--> <context:component-scan base-package="service.impl"></context:component-scan> <!-- 添加事务管理器--> <!-- 配置事务切面--> <!-- 配置切入点和绑定--> </beans>
Step8:添加springmvc配置文件
<?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:p="http://www.springframework.org/schema/p" 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-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 添加包扫描--> <context:component-scan base-package="controller"></context:component-scan> <!-- 视图解析器,如果是Ajax请求则不需要--> <!-- 添加注解驱动--> <mvc:annotation-driven> <mvc:path-matching suffix-pattern="true" /> </mvc:annotation-driven> </beans>
Step9:配置web.xml配置文件
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 添加中文编码过滤器--> <filter> <filter-name>encode</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> <init-param> <param-name>forceRequestEncoding</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>forceResponseEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encode</filter-name> <!-- 拦截所有请求--> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 注册SpringMVC框架--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 读取SpringMVC核心配置文件--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc/springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <!-- DispatcherServlet拦截的请求,只接收*.action的请求--> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 注册Spring框架,目的是启动spring容器--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/applicationContext-*.xml</param-value> </context-param> <!-- org.springframework.web.context.ContextLoaderListener--> </web-app>
Step10:数据库可视化
这个按钮可以实现编写sql语句
二.后端功能
1. pojo层
public class User { private String userId; private String cardType; private String cardNo; private String userName; private String userSex; private String userAge; private String userRole; }
2.mapper层
(1)创建UserMapper接口
public interface UserMapper { //方法要根据页面中要查询的内容来写 List<User> selectUser (@Param("userName") String userName, @Param("userSex") String userSex, @Param("startRow") int startRow); //添加用户 int createUser(User user); //根据id删除用户 int deleteUserById(String userId); //获取页面总页数(根据查询结果的不同) int getRowCount(@Param("userName") String userName,@Param("userSex") String userSex); }
(2)创建UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="mapper.UserMapper"> <!-- 处理属性名和字段名不同的问题--> <resultMap id="usermap" type="user"> <id property="userId" column="user_id"></id> <result property="cardType" column="card_type"></result> <result property="cardNo" column="card_no"></result> <result property="cardName" column="card_name"></result> <result property="userSex" column="user_sex"></result> <result property="userAge" column="user_age"></result> <result property="userRole" column="user_role"></result> </resultMap> <!-- 定义全部列名--> <sql id="allColumns"> user_id,card_type,card_no,user_name,user_sex,user_age,user_role </sql> <!-- List<User> selectUser (@Param("userName") String userName, @Param("userSex") String userSex, int startRow);--> <select id="selectUser" resultMap="usermap"> select <include refid="allColumns"></include> from user <where> <if test="userName != null and userName != ''"> and user_name like concat('%',#{userName},'%') </if> <if test="userSex != null and userSex != ''"> and user_sex = #{userSex} </if> </where> limit #{startRow},5 </select> <!-- //int createUser(User user);--> <insert id="createUser" parameterType="user"> insert into user values (#{userId},#{cardType},#{cardNo},#{userName},#{userSex},#{userAge},#{userRole}) </insert> <!-- int deleteUserById(String userId);--> <delete id="deleteUserById"> delete from user where user_id = #{userid} </delete> <!-- int getRowCount(@Param("userName") String userName,@Param("userSex") String userSex);--> <select id="getRowCount" resultType="int"> select count(*) from user <where> <if test="userName != null and userName != ''"> and user_name like concat ('%',#{userName},'%') </if> <if test="userSex != null and userSex != ''"> and user_sex = #{userSex} </if> </where> </select> </mapper>
limit (当前页码-1)*每页条数,每页条数
传进来的是需要显示的页数,也就是当前页码,但是limit不支持运算,所以要将当前页码-1 *每页条数,所以要在业务层或界面层处理。
3.service层
(1)业务接口
public interface UserService { List<User> selectUserPage(String userName,String userSex,int startCount); int createUser(User user); int deleteUserById(String userId); int getRowCount(String userName,String userSex); }
(2)业务实现
@Service public class UserServiceImpl implements UserService { @Autowired UserMapper userMapper; @Override public List<User> selectUserPage(String userName, String userSex, int startCount) { return userMapper.selectUser(userName,userSex,startCount); } @Override public int createUser(User user) { return userMapper.createUser(user); } @Override public int deleteUserById(String userId) { return userMapper.deleteUserById(userId); } @Override public int getRowCount(String userName, String userSex) { return userMapper.getRowCount(userName,userSex); } }
4.controller层
@Controller public class UserController { @Autowired UserService userService; public static final int PAGE_SIZE = 5; @RequestMapping("/selectUserPage") @ResponseBody public List<User> selectUserPage(String userName,String userSex,Integer page){ int startRow = 0; if(page != null){ startRow = (page-1)*PAGE_SIZE; } return userService.selectUserPage(userName,userSex,startRow); } @RequestMapping("/deleteUserById") @ResponseBody public int deleteUserById(String userId){ return userService.deleteUserById(userId); } @RequestMapping("/createUser") @ResponseBody public int createUser(User user){ String userId = System.currentTimeMillis()+""; user.setUserId(userId); return userService.createUser(user); } @RequestMapping("/getRowCount") @ResponseBody public int getCount(String userName,String userSex){ return userService.getRowCount(userName,userSex); } }
1.@ResponseBody表示是以Ajax请求方式返回
如果这个类的每个方法都是Ajax请求方式返回,那么可以在类名上添加注解@RestController来代替所有的@ResponseBody
2.在类上的RequestMapping是虚拟路径,就像包名一样。
三.后端功能测试
最好每实现一层就测,但是业务逻辑层很简单,所以可以实现了mapper层和service层再测。
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:spring/applicationContext-mapper.xml","classpath:spring/applicationContext-service.xml"}) public class MyTest { @Autowired UserService userService; @Test public void testSelect(){ List<User> list = userService.selectUserPage(null,null,0); list.forEach(user -> System.out.println(user)); } @Test public void testCreate(){ int num = userService.createUser(new User("123","身份证","456","大西瓜","男","8","幼儿园小学生")); System.out.println(num); } @Test public void testDelete(){ int num = userService.deleteUserById("123"); System.out.println(num); } @Test public void testGet(){ int num = userService.getRowCount(null,"男"); System.out.println(num); } }
四.前端功能
Vue实现,非SSM整合重点,不予叙述。
五.出现的bug
1.出现找不到org.springframework.web.context.ContextLoaderListener的问题。
在项目结构中找到你的项目,点击置于Output Root,检查WEB-INF下是否有lib,出现bug的原因就是因为没有lib。
2.依赖的问题
按照展示的pom.xml来就没问题,但具体是因为哪个导致的错误暂不清楚。
3.配置文件的命名空间的问题
按照展示的applicationContext-mapper.xml和applicationContext-service.xml来,具体因为哪个导致的错误暂不清楚。
特别注意
<mvc:annotation-driven> <mvc:path-matching suffix-pattern="true" /> </mvc:annotation-driven>
这个标签有重名的命名空间,要用mvc为结尾的命名空间。