SSM项目实战

avatar
作者
猴君
阅读量:0

项目实战一

这里实战的是我Javaweb项目实战(后端篇)的改写

Javaweb项目实战用到的技术是servlet+vue3

这里用到的是spring+springmvc+mybatis+vue3

项目结构

 步骤一:导入需要依赖

   <!--mybatis核心-->         <dependency>             <groupId>org.mybatis</groupId>             <artifactId>mybatis</artifactId>             <version>3.5.16</version>         </dependency> <!--德鲁伊连接池-->         <dependency>             <groupId>com.alibaba</groupId>             <artifactId>druid</artifactId>             <version>1.2.8</version>         </dependency>         <!--mysql驱动-->         <dependency>             <groupId>mysql</groupId>             <artifactId>mysql-connector-java</artifactId>             <version>8.0.32</version>         </dependency>        <!--简化实体类的getset-->         <dependency>             <groupId>org.projectlombok</groupId>             <artifactId>lombok</artifactId>             <version>1.18.32</version>         </dependency>       <!-- 方便使用JdbcTemplate事务也需要它-->         <dependency>             <groupId>org.springframework</groupId>             <artifactId>spring-jdbc</artifactId>             <version>6.0.6</version>         </dependency>          <!--spring context依赖-->         <!--当你引入Spring Context依赖之后,表示将Spring的基础依赖引入了-->         <dependency>             <groupId>org.springframework</groupId>             <artifactId>spring-context</artifactId>             <version>6.0.6</version>         </dependency>         <!--junit5测试-->         <dependency>             <groupId>org.junit.jupiter</groupId>             <artifactId>junit-jupiter-api</artifactId>             <version>5.10.2</version>         </dependency>      <!--spring test依赖快速使用ioc容器-->         <dependency>             <groupId>org.springframework</groupId>             <artifactId>spring-test</artifactId>             <version>6.0.6</version>             <scope>test</scope>         </dependency>          <!--spring aop依赖-->         <dependency>             <groupId>org.springframework</groupId>             <artifactId>spring-aspects</artifactId>             <version>6.0.6</version>         </dependency>          <!-- 声明式事务依赖-->         <dependency>             <groupId>org.springframework</groupId>             <artifactId>spring-tx</artifactId>             <version>6.0.6</version>         </dependency>       <!--springmvc依赖-->         <dependency>             <groupId>org.springframework</groupId>             <artifactId>spring-webmvc</artifactId>             <version>6.0.6</version>         </dependency>         <!--web项目需要servlet-->         <dependency>             <groupId>jakarta.platform</groupId>             <artifactId>jakarta.jakartaee-web-api</artifactId>             <version>9.1.0</version>             <scope>provided</scope>         </dependency>          <!--json-->         <dependency>             <groupId>com.fasterxml.jackson.core</groupId>             <artifactId>jackson-databind</artifactId>             <version>2.17.1</version>         </dependency>          <!-- jsp需要依赖! jstl-->         <dependency>             <groupId>jakarta.servlet.jsp.jstl</groupId>             <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>             <version>3.0.0</version>         </dependency>          <!--整和需要  加载ioc容器-->         <dependency>             <groupId>org.springframework</groupId>             <artifactId>spring-web</artifactId>             <version>6.0.6</version>         </dependency>          <!--整合需要  spring整合mybatis-->         <dependency>             <groupId>org.mybatis</groupId>             <artifactId>mybatis-spring</artifactId>             <version>3.0.3</version>         </dependency>          <!--日志-->         <dependency>             <groupId>ch.qos.logback</groupId>             <artifactId>logback-classic</artifactId>             <version>1.5.6</version>         </dependency>

步骤二:配置类

2.1 SpringConfig类

package org.example.config;  import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.TransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement;  import javax.sql.DataSource;  @Configuration @ComponentScan({"org.example.service"}) @EnableAspectJAutoProxy @EnableTransactionManagement public class SpringConfig {      //开始事务注解     @Bean     public TransactionManager transactionManager(DataSource dataSource){         DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();         dataSourceTransactionManager.setDataSource(dataSource);         return dataSourceTransactionManager;     } } 

2.2 JdbcConfig类

package org.example.config;  import com.alibaba.druid.pool.DruidDataSource; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource;  import javax.sql.DataSource;  @Configuration @PropertySource({"classpath:jdbc.properties"}) public class JdbcConfig {     @Value("${jdbc.driverClassName}")     private String driverClassName;     @Value("${jdbc.url}")     private  String url;      @Value("${jdbc.username}")     private String username;      @Value("${jdbc.password}")      private String password;      @Bean     public DataSource getDataSource(){         DruidDataSource dataSource = new DruidDataSource();         dataSource.setDriverClassName(driverClassName);         dataSource.setUrl(url);         dataSource.setUsername(username);         dataSource.setPassword(password);         return dataSource;     } } 

2.3 MybatisConfig类

package org.example.config;  import com.github.pagehelper.PageInterceptor; import jakarta.servlet.jsp.jstl.core.Config; import org.apache.ibatis.logging.slf4j.Slf4jImpl; import org.apache.ibatis.session.AutoMappingBehavior; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.mapper.MapperScannerConfigurer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;  import javax.sql.DataSource; import java.util.Properties;  @Configuration public class MybatisConfig {     @Bean     public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){         SqlSessionFactoryBean sqlSession= new SqlSessionFactoryBean();         sqlSession.setDataSource(dataSource);         org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();         configuration.setLogImpl(Slf4jImpl.class);  //日志         configuration.setMapUnderscoreToCamelCase(true); //驼峰映射         configuration.setAutoMappingBehavior(AutoMappingBehavior.FULL);//自动映射 数据库表和java对象         sqlSession.setConfiguration(configuration);         sqlSession.setTypeAliasesPackage("org.example.pojo");  //别名          //分页插件         PageInterceptor pageInterceptor = new PageInterceptor();         Properties properties = new Properties();         properties.setProperty("helperDialect","mysql");         pageInterceptor.setProperties(properties);         sqlSession.addPlugins(pageInterceptor);          return sqlSession;     }       @Bean     public MapperScannerConfigurer mapperScannerConfigurer(){         MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();         mapperScannerConfigurer.setBasePackage("org.example.mapper");         return mapperScannerConfigurer;     } } 

2.4 SpringMvcConfig类

package org.example.config;  import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;  import java.util.List;  @Configuration @ComponentScan({"org.example.controller"}) @EnableWebMvc public class SpringMvcConfig implements WebMvcConfigurer {      //全局异常处理       @Override     public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {       }      //静态资源     @Override     public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {          configurer.enable();     } } 

2.5 JavaConfig类

package org.example.config;  import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;  public class JavaConfig extends AbstractAnnotationConfigDispatcherServletInitializer {     @Override     protected Class<?>[] getRootConfigClasses() {         return new Class[]{JdbcConfig.class, SpringConfig.class, MybatisConfig.class};     }      @Override     protected Class<?>[] getServletConfigClasses() {         return new Class[]{SpringMvcConfig.class};     }      @Override     protected String[] getServletMappings() {         return new String[]{"/"};     } } 

步骤三:创建日志文件  logback.xml

<?xml version="1.0" encoding="UTF-8"?> <configuration debug="true">     <!-- 指定日志输出的位置,ConsoleAppender表示输出到控制台 -->     <appender name="STDOUT"               class="ch.qos.logback.core.ConsoleAppender">         <encoder>             <!-- 日志输出的格式 -->             <!-- 按照顺序分别是:时间、日志级别、线程名称、打印日志的类、日志主体内容、换行 -->             <pattern>[%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger] [%msg]%n</pattern>             <charset>UTF-8</charset>         </encoder>     </appender>      <!-- 设置全局日志级别。日志级别按顺序分别是:TRACE、DEBUG、INFO、WARN、ERROR -->     <!-- 指定任何一个日志级别都只打印当前级别和后面级别的日志。 -->     <root level="DEBUG">         <!-- 指定打印日志的appender,这里通过“STDOUT”引用了前面配置的appender -->         <appender-ref ref="STDOUT"/>     </root>      <!-- 根据特殊需求指定局部日志级别,可也是包名或全类名。 -->     <logger name="org.example.mapper" level="DEBUG"/>  </configuration>

步骤四 创建MD5类,全局统一json类

4.1MD5

package org.example.util;  import java.security.MessageDigest; import java.security.NoSuchAlgorithmException;  public class MD5Util {     public static String encrypt(String strSrc) {         try {             char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8',                     '9', 'a', 'b', 'c', 'd', 'e', 'f' };             byte[] bytes = strSrc.getBytes();  //使用平台的默认字符集将此 String 编码为 byte 序列,并 将结果存储到一个新的 byte 数组中。             MessageDigest md = MessageDigest.getInstance("MD5");             md.update(bytes);             bytes = md.digest();             int j = bytes.length;             char[] chars = new char[j * 2];             int k = 0;             for (int i = 0; i < bytes.length; i++) {                 byte b = bytes[i];                 chars[k++] = hexChars[b >>> 4 & 0xf];                 chars[k++] = hexChars[b & 0xf];             }             return new String(chars);         } catch (NoSuchAlgorithmException e) {             e.printStackTrace();             throw new RuntimeException("MD5加密出错");         }      }  } 

4.2json

package org.example.json;  //全局统一响应的JSON格式处理类 public class Result <T>{   //因为不确定返回消息是什么类型 ,所以这里声明了<T>     // 返回码     private Integer code;     // 返回消息     private String message;     // 返回数据     private T data;     public Result(){}     // 返回数据     protected static <T> Result<T> build(T data) {   //将data添加进去         Result<T> result = new Result<T>();         if (data != null)             result.setData(data);         return result;            //返回一个result对象     }     public static <T> Result<T> build(T body, Integer code, String message) { //         Result<T> result = build(body);  // 创建一个result对象,并添加data对象         result.setCode(code);         result.setMessage(message);         return result;     }     public static <T> Result<T> build(T body, ResultCodeEnum resultCodeEnum) {         Result<T> result = build(body);       //创建result对象并添加data数据         result.setCode(resultCodeEnum.getCode());  //给响应码添加枚举类中的数据         result.setMessage(resultCodeEnum.getMessage()); //给响应消息添加枚举类中的数据         return result;     }     /**      * 操作成功      * @param data  baseCategory1List      * @param <T>      * @return      */     public static<T> Result<T> ok(T data){          //返回一个result对象,这是一个操作成功的数据,如果操作成功就执行它         Result<T> result = build(data);    //创建result对象并添加data数据         return build(data, ResultCodeEnum.SUCCESS); //调用上面的方法,将枚举类中的ResultCodeEnum.SUCCESS赋值给响应码和响应消息并返回result     }     public Result<T> message(String msg){         this.setMessage(msg);         return this;     }     public Result<T> code(Integer code){         this.setCode(code);         return this;     }     public Integer getCode() {         return code;     }     public void setCode(Integer code) {         this.code = code;     }     public String getMessage() {         return message;     }     public void setMessage(String message) {         this.message = message;     }     public T getData() {         return data;     }     public void setData(T data) {         this.data = data;     } } 
package org.example.json;  public enum ResultCodeEnum {     SUCCESS(200,"success"),     USERNAEM_ERROR(501,"usernameError"),     PASSWORD_ERROR(503,"passwordError"),     NOTLOGIN(504,"notlogin"),     USERNAME_USED(505,"usernameUsed");        private Integer code;     private String message;     private ResultCodeEnum(Integer code ,String message){         this.code= code;         this.message = message;      }      public Integer getCode() {         return code;     }      public String getMessage() {         return message;     } } 

步骤五:三层架构

mapper层

1.账户表SysUserMapper

public interface SysUserMapper {   int  add(SysUser sysUser); SysUser findByUsername(String username); } 

对应的xml文件

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"         "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- namespace等于mapper接口类的全限定名,这样实现对应 --> <mapper namespace="org.example.mapper.SysUserMapper">       <insert id="add">         insert into sys_user values(default,#{username},#{userPwd})     </insert>     <select id="findByUsername" resultType="sysUser">          select * from sys_user where username =#{username}     </select> </mapper>

2.数据表SysSchedule

package org.example.mapper;  import org.example.pojo.SysSchedule;  import java.util.List;  public interface SysScheduleMapper {     /**      * 用于向数据中增加一条日程记录      * @param schedule 日程数据以SysSchedule实体类对象形式入参      * @return 返回影响数据库记录的行数, 行数为0说明增加失败,行数大于0说明增加成功      */     int addSchedule(int  uid);       /**      * 查询所有用户的所有日程      * @return 将所有日程放入一个:List<SysSchedule>集合中返回      */     List<SysSchedule> findAll();      List<SysSchedule> findItemListByUid(int uid);      Integer addDefault(int uid);      Integer updateSchedule(SysSchedule schedule);      Integer removeSchedule(int sid); } 

对应的xml文件

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"         "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- namespace等于mapper接口类的全限定名,这样实现对应 --> <mapper namespace="org.example.mapper.SysScheduleMapper">      <insert id="addDefault">         insert into sys_schedule values (DEFAULT,#{uid},'请输入日程',0)     </insert>     <insert id="addSchedule">         insert into sys_schedule values(DEFAULT,#{uid},#{title},#{completed})     </insert>     <update id="updateSchedule">         update sys_schedule set title = #{title} ,completed = #{completed} where  sid = #{sid}     </update>       <delete id="removeSchedule">          delete from sys_schedule where sid = #{sid}     </delete>       <select id="findItemListByUid" resultType="org.example.pojo.SysSchedule">         select sid ,uid,title,completed from sys_schedule where uid = #{uid}     </select>      <select id="findAll" resultType="org.example.pojo.SysSchedule">         select * from sys_schedule     </select> </mapper>

Service层

1.账户表SysUserMapper

public interface SysUserService {          int regist(SysUser sysUser);      /**      * 根据用户名获得完整用户信息的方法      * @param username 要查询的用户名      * @return 如果找到了返回SysUser对象,找不到返回null      */     SysUser findByUsername(String username); } 

实现类
 

    @Service public class SysUserServiceImpl implements SysUserService {     @Autowired     private SysUserMapper sysUserMapper;       @Override     public int regist(SysUser sysUser) {         sysUser.setUserPwd(MD5Util.encrypt(sysUser.getUserPwd()));        return   sysUserMapper.add(sysUser);     }      @Override     public SysUser findByUsername(String username) {      return   sysUserMapper.findByUsername(username);     } } 

2.数据表SysSchedule

public interface SysScheduleService {     List<SysSchedule> findItemListByUid(int uid);      Integer addDefault(int uid);      Integer updateSchedule(SysSchedule schedule);      Integer removeSchedul(int sid); } 

实现类

@Service  public class SysScheduleServiceImpl implements SysScheduleService {     @Autowired     private SysScheduleMapper sysScheduleMapper;       @Override     public List<SysSchedule> findItemListByUid(int uid) {         return sysScheduleMapper.findItemListByUid(uid);     }      @Override     public Integer addDefault(int uid) {         return sysScheduleMapper.addDefault(uid);     }      @Override     public Integer updateSchedule(SysSchedule schedule) {         return sysScheduleMapper.updateSchedule(schedule);     }      @Override     public Integer removeSchedul(int sid) {         return sysScheduleMapper.removeSchedule(sid);     } } 

controller层

1.账户表SysUserMapper

@Controller @CrossOrigin @ResponseBody @RequestMapping("user") @Slf4j public class SysUserController {      @Autowired     private SysUserService service;      @RequestMapping("checkUsernameUsed")     public Result checkUsernameUsed(String username) {         SysUser sysUser = service.findByUsername(username);         Result result = Result.ok(null);         if (sysUser != null) {             result = Result.build(null, ResultCodeEnum.USERNAME_USED);         }         log.info("用户名是否被占用:{}", result);         return result;      }      @RequestMapping(value = "login",method = RequestMethod.POST)     public Result login(@RequestBody SysUser sysUser) {         //2 调用服务层方法,根据用户名查询用户信息         SysUser loginUser = service.findByUsername(sysUser.getUsername());          Result result = null;          if (null == loginUser) {             result = Result.build(null, ResultCodeEnum.USERNAEM_ERROR);          } else if (!MD5Util.encrypt(sysUser.getUserPwd()).equals(loginUser.getUserPwd())) {             result = Result.build(null, ResultCodeEnum.PASSWORD_ERROR);         } else {             // 登录程序,将用户uid和username响应给客户端             Map data = new HashMap();             loginUser.setUserPwd("");             data.put("loginUser", loginUser);             result = Result.ok(data);         }         log.info("用户名是否被占用:{}", result);         // 3将登录结果响应给客户端        return result;     }      @RequestMapping("regist")     public Result regist(@RequestBody SysUser sysUser){         int regist = service.regist(sysUser);         Result result = Result.ok(null);         if (regist < 1) {             result = Result.build(null, ResultCodeEnum.USERNAME_USED);         } log.info("用户注册:{}", result); return result;     }      @RequestMapping("select")     public Result select(String username) {         SysUser sysUser = service.findByUsername(username);         Result result = Result.ok(null);         if (sysUser != null) {             result = Result.build(null, ResultCodeEnum.USERNAME_USED);         }         log.info("用户名是否被占用:{}", result);         return result;      } } 

2.数据表SysSchedule

 @Slf4j @CrossOrigin @ResponseBody @Controller @RequestMapping("schedule") public class SysScheduleController {     @Autowired     private SysScheduleService service;       @RequestMapping("removeSchedule")     public Result removeSchedule(int sid){         Integer i = service.removeSchedul(sid);       if(i<0){       return     Result.build(null, ResultCodeEnum.NOTLOGIN);       }else {         return   Result.ok(null);       }     }   @RequestMapping(value = "updateSchedule",method = RequestMethod.POST) public Result updateSchedule(@RequestBody SysSchedule schedule){      Integer i = service.updateSchedule(schedule);      if(i<0){          return     Result.build(null, ResultCodeEnum.NOTLOGIN);      }else {          return   Result.ok(null);      }  }  @RequestMapping("addDefaultSchedule")     public Result addDefaultSchedule(int uid){         Integer i = service.addDefault(uid);         if(i<0){             return     Result.build(null, ResultCodeEnum.NOTLOGIN);         }else {             return   Result.ok(null);         }  } @RequestMapping("findAllSchedule")     public Result findAllSchedule(int uid){     List<SysSchedule> itemList = service.findItemListByUid(uid);      // 将用户的所有日程放入一个Result对象     Map data =new HashMap();     data.put("itemList",itemList);      Result result = Result.ok(data);     // 将Result对象转换为json响应给客户端     return result; } } 

总结

与servlet相比

ssm

简化了响应json的WebUtil

  简化了JDBCUtil

简化了全局统一 处理servlet的BaseContoller

简化了跨域CrosFilter的java文件

ssm 使用@CrossOrigin注解就使当前文件可以跨域大大减少了代码量

ssm使用@ResponseBody注解就使响应数据变为json形式

ssm使用@RequestMapping就相当于一个servlet所以无需统一处理servlet

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!