ssm框架整合

系列文章目录

第一章、SSM整合
第二章、表现数据封装
第三章、异常处理器
第四章、项目异常处理方案


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

Spring整合MyBatis、SpringMVC的实现,并实现简单的处理异常


提示:以下是本篇文章正文内容,下面案例可供参考

一、SSM整合流程

1、创建web工程

  • 导入依赖
<dependencies>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.10.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.2.10.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>5.2.10.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.2</version>
    </dependency>

    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.3.1</version>
    </dependency>

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.47</version>
    </dependency>

    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.16</version>
    </dependency>

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.13.1</version>
    </dependency>
    
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.1</version>
    </dependency>
  </dependencies>

2、SSM整合

  • Spring
    • SpringConfig
@Configuration
@ComponentScan("com.itheima.service")
@PropertySource("jdbc.properties")
@Import({JdbcConfig.class,MybatisConfig.class})
public class SpringConfig {
}
  • Mybatis

    • MybatisConfig
public class MybatisConfig {
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
        SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
        ssfb.setTypeAliasesPackage("com.itheima.domain");
        ssfb.setDataSource(dataSource);
        return ssfb;
    }
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer msc = new MapperScannerConfigurer();
        msc.setBasePackage("com.itheima.dao");
        return msc;
    }

}
 - JdbcConfig
public class JdbcConfig {
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    @Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(username);
        ds.setPassword(password);
        return ds;
    }
    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource){
        DataSourceTransactionManager ds = new DataSourceTransactionManager();
        ds.setDataSource(dataSource);
        return ds;
    }

}
 - jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm
jdbc.username=root
jdbc.password=root
  • SpringMVC
    • ServletConfig
public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringConfig.class};
    }

    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringConfig.class};
    }

    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}
- SpringMVCConfig
@Configuration
@ComponentScan("com.itheima.controller")
@EnableWebMvc
public class SpringMVCConfig {
}

3、功能模块

  • 表与实体类
    在这里插入图片描述
    在这里插入图片描述
public class book {
    private Integer id;
    private String type;
    private String name;
    private String description;
	//自动生成get/set方法和toSpring方法
}

-数据层标准开发

public interface BookDao {

    @Insert("insert into tbl_book (type,name,description) values(#{type},#{name},#{description}) ")
    public void save(Book book);

    @Update("update tbl_book set type=#{type},name=#{name},description=#{description}")
    public void update(Book book);

    @Delete("delete from tbl_book where id=#{id}")
    public void delete(Integer id);

    @Select("select * from tbl_book where id=#{id}")
    public book getById(Integer id);

    @Select("select * from tbl_book")
    public List<Book>getAll();

}
  • 业务层标准开发
@Transactional
public interface BookService {
    public boolean save(Book book);

    public boolean update(Book book);

    public boolean delete(Integer id);

    public book getById(Integer id);

    public List<Book> getAll();
}
@Service
public class BookServiceImpl implements BookService {
    @Autowired
    private BookDao bookDao;
    public boolean save(Book book) {
        bookDao.save(book);
        return true;
    }

    public boolean update(Book book) {
        bookDao.update(book);
        return true;
    }

    public boolean delete(Integer id) {
        bookDao.delete(id);
        return true;
    }

    public book getById(Integer id) {
        return bookDao.getById(id);
    }

    public List<Book> getAll() {
        return bookDao.getAll();
    }
}
 - 测试接口-----业务层接口测试(整合Junit)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class BookServiceTest {
    @Autowired
    private BookService bookService;
    @Test
    public void testGetById(){
        book book = bookService.getById(1);
        System.out.println(book);
    }
}
  • controller
@RestController
@RequestMapping("/books")
public class BookController {
    @Autowired
    private BookService bookService;
    @PostMapping
    public boolean save(@RequestBody Book book) {
        return bookService.save(book);
    }
    @PutMapping
    public boolean update(@RequestBody Book book) {
        return bookService.update(book);
    }
    @DeleteMapping("/{id}")
    public boolean delete(@PathVariable Integer id) {
        return bookService.delete(id);
    }
    @GetMapping("/{id}")
    public book getById(@PathVariable Integer id) {
        return bookService.getById(id);
    }
    @GetMapping
    public List<Book> getAll() {
        return bookService.getAll();
    }
}
- 表现层接口测试(PostMan) 

二、表现数据封装

1. 表现层与前端数据传输协议的定义

  • 前端接收数据格式-创建结果模型,封装数据到data属性中

  • 前端接收数据格式-封装操作结果到code属性中

  • 前端接收数据格式-封装特殊消息到message(msg)属性中
    2. 表现层与前端数据传输协议的实现

  • 编写Result类 设置统一数据返回结果类

/**
 * 根据情况设定合理的Result
 */
public class Result {
    private Object data;
    private Integer code;
    private String msg;

    public Result() {
    }

    public Result( Integer code,Object data) {
        this.data = data;
        this.code = code;
    }

    public Result( Integer code,Object data, String msg) {
        this.data = data;
        this.code = code;
        this.msg = msg;
    }
}

注意:Result类中的字段并不是固定的,可以根据需要自行增减,提供若干个构造方法,方便操作

  • 编写Code类 设置统一数据返回结果编码
public class Code {
    // 尾数为1表示成功 0表示失败
    public static final Integer SAVE_OK=20011;
    public static final Integer DELETE_OK=20021;
    public static final Integer UPDATE_OK=20031;
    public static final Integer GET_OK=20041;

    public static final Integer SAVE_ERR=20010;
    public static final Integer DELETE_ERR=20020;
    public static final Integer UPDATE_ERR=20030;
    public static final Integer GET_ERR=20040;
}

注意:Code类的常量设计也不是固定的,可以根据需要自行增减,
例如将查询再进行细分为GET_OK,GET_ALL_OK,GET_PAGE_OK

  • 修改表现层controller代码,实现前端数据传输协议
@RestController
@RequestMapping("/books")
public class BookController {
    @Autowired
    private BookService bookService;
    @PostMapping
    public Result save(@RequestBody Book book) {
        boolean flag = bookService.save(book);
        return new Result(flag ? Code.SAVE_OK :Code.SAVE_ERR,flag);
    }
    @PutMapping
    public Result update(@RequestBody Book book) {
        boolean flag = bookService.update(book);
        return new Result(flag ? Code.UPDATE_OK :Code.UPDATE_ERR,flag);
    }
    @DeleteMapping("/{id}")
    public Result delete(@PathVariable Integer id) {
        boolean flag = bookService.delete(id);
        return new Result(flag ? Code.DELETE_OK :Code.DELETE_ERR,flag);
    }
    @GetMapping("/{id}")
    public Result getById(@PathVariable Integer id) {

        book book= bookService.getById(id);
        Integer code= book !=null ? Code.GET_OK : Code.GET_ERR;
        String msg=book !=null ? "" : "数据查询失败,请重试!";
        return new Result(code,book,msg);
    }
    @GetMapping
    public Result getAll() {
        List<Book> bookList= bookService.getAll();
        Integer code= bookList !=null ? Code.GET_OK : Code.GET_ERR;
        String msg=bookList !=null ? "" : "数据查询失败,请重试!";
        return new Result(code,bookList,msg);
    }
}

三、异常处理器

出现异常现象的常见位置与常见诱因如下:

  • 框架内部抛出的异常:因使用不合规导致
  • 数据层抛出的异常:因外部服务器故障导致(例如:服务器访问超时)
  • 业务层抛出的异常:因业务逻辑书写错误导致
  • 表现层抛出的异常:因数据收集,校验等规则导致(例如:不匹配的数据类型间导致异常)
  • 工具类抛出的异常:因工具类书写不严谨不够健壮导致(例如:必要释放的连接长期未释放等)

两个注解:

  1. @RestControllerAdvice:在类上标识,表示标识的类做异常处理工作
  2. @ExceptionHandler:在方法上标识,表示异常处理器
    注意:需要在SpringMVCConfig中配置 让其扫描到此注解

四、项目异常处理方案

  1. 业务异常(BusinessException)
    • 发送对应消息传递给用户,提醒规范操作
  2. 系统异常(SystemException)
    • 发送固定消息传递给用户,安抚用户
  3. 其他异常(Exception)
    • 发送固定消息传递给用户,安抚用户

步骤:

  1. 自定义项目系统异常
public class SystemException extends RuntimeException {
    private Integer code;

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public SystemException(Integer code, String message) {
        super(message);
        this.code = code;
    }

    public SystemException(Integer code,String message, Throwable cause) {
        super(message, cause);
        this.code = code;
    }
  1. 自定义项目业务异常
public class BusinessException extends RuntimeException {
    private Integer code;

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
}

    public BusinessException(Integer code, String message) {
        super(message);
        this.code = code;
    }

    public BusinessException(Integer code, String message, Throwable cause) {
        super(message, cause);
        this.code = code;
    }

}

  1. 自定义统异常编码(补充在Code类中)
public static final Integer SYSTEM_ERR=50001;     //系统异常结果编码
    public static final Integer SYSTEM_TIEMOUT_ERR=50002;  //系统超时异常结果编码
    public static final Integer SYSTEM_UNKNOW_ERR=59999;    //系统未知异常结果编码

    public static final Integer BUSINESS_ERR=60002;    //业务异常结果编码

  1. 自定义异常并包装异常(触发自定义异常)
  • 在实现业务层中模拟异常(BookServiceImpl)
 public book getById(Integer id) {
        //模拟异常
        if(id<0){
            throw new BusinessException(Code.BUSINESS_ERR,"请不要使用你的技术挑战我的耐心!");
        }
        //将可能出现的异常进行包装,转换成自定义异常
        try {
            int i=1/0;
        }catch (Exception e){
            throw new SystemException(Code.SYSTEM_TIEMOUT_ERR,"服务器启动超时,请稍后重试!");
        }
        return bookDao.getById(id);
    }
  1. 拦截并处理异常
@RestControllerAdvice
public class ProjectExceptionAdvice {

    @ExceptionHandler(SystemException.class)
    public Result doSystemException(SystemException ex){
    
        return new Result(ex.getCode(),null,ex.getMessage());
    }
    @ExceptionHandler(BusinessException.class)
    public Result doBusinessException(BusinessException ex){
    
        return new Result(ex.getCode(),null,ex.getMessage());
    }
    @ExceptionHandler(Exception.class)
    public Result doException(Exception ex){
    
        return new Result(Code.SYSTEM_UNKNOW_ERR,null,"系统繁忙,请稍联系管理员!");
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值