SSM整合

SSM整合流程

1.创建工程

 pom.xml添加依赖和插件:

 1 <dependencies>
 2     <dependency>
 3       <groupId>org.springframework</groupId>
 4       <artifactId>spring-webmvc</artifactId>
 5       <version>5.2.10.RELEASE</version>
 6     </dependency>
 7 
 8     <dependency>
 9       <groupId>org.springframework</groupId>
10       <artifactId>spring-jdbc</artifactId>
11       <version>5.2.10.RELEASE</version>
12     </dependency>
13 
14     <dependency>
15       <groupId>org.springframework</groupId>
16       <artifactId>spring-test</artifactId>
17       <version>5.2.10.RELEASE</version>
18     </dependency>
19 
20     <dependency>
21       <groupId>org.mybatis</groupId>
22       <artifactId>mybatis</artifactId>
23       <version>3.5.6</version>
24     </dependency>
25 
26     <dependency>
27       <groupId>org.mybatis</groupId>
28       <artifactId>mybatis-spring</artifactId>
29       <version>1.3.0</version>
30     </dependency>
31 
32     <dependency>
33       <groupId>mysql</groupId>
34       <artifactId>mysql-connector-java</artifactId>
35       <version>8.0.13</version>
36     </dependency>
37 
38     <dependency>
39       <groupId>com.alibaba</groupId>
40       <artifactId>druid</artifactId>
41       <version>1.1.16</version>
42     </dependency>
43 
44     <dependency>
45       <groupId>junit</groupId>
46       <artifactId>junit</artifactId>
47       <version>4.12</version>
48       <scope>test</scope>
49     </dependency>
50 
51     <dependency>
52       <groupId>javax.servlet</groupId>
53       <artifactId>javax.servlet-api</artifactId>
54       <version>3.1.0</version>
55       <scope>provided</scope>
56     </dependency>
57 
58     <dependency>
59       <groupId>com.fasterxml.jackson.core</groupId>
60       <artifactId>jackson-databind</artifactId>
61       <version>2.9.0</version>
62     </dependency>
63   </dependencies>
64 
65   <build>
66     <plugins>
67       <plugin>
68         <groupId>org.apache.tomcat.maven</groupId>
69         <artifactId>tomcat7-maven-plugin</artifactId>
70         <version>2.2</version>
71         <configuration>
72           <port>80</port>
73           <path>/</path>
74         </configuration>
75       </plugin>
76     </plugins>
77   </build>

2.SSM整合

Spring

SpringConfig

1 @Configuration
2 @ComponentScan("com.test.service")
3 @PropertySource("classpath:jdbc.properties")
4 @Import({JdbcConfig.class,MybatisConfig.class})
5 @EnableTransactionManagement //开启Spring事务管理
6 public class SpringConfig {
7 }

MyBatis

MybatisConfig

 1 public class MybatisConfig {
 2     @Bean
 3     public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
 4         SqlSessionFactoryBean factoryBean= new SqlSessionFactoryBean();
 5         factoryBean.setDataSource(dataSource);
 6         factoryBean.setTypeAliasesPackage("com.test.domain");
 7         return factoryBean;
 8     }
 9 
10     @Bean
11     public MapperScannerConfigurer mapperScannerConfigurer(){
12         MapperScannerConfigurer msc = new MapperScannerConfigurer();
13         msc.setBasePackage("com.test.dao");
14         return msc;
15     }
16 }

JdbcConfig

 1 public class JdbcConfig {
 2     @Value("${jdbc.driver}")
 3     private String driver;
 4     @Value("${jdbc.url}")
 5     private String url;
 6     @Value("${jdbc.username}")
 7     private String username;
 8     @Value("${jdbc.password}")
 9     private String password;
10     //配置连接池
11     @Bean
12     public DataSource dataSource() {
13         DruidDataSource dataSource=new DruidDataSource();
14         dataSource.setDriverClassName(driver);
15         dataSource.setUrl(url);
16         dataSource.setUsername(username);
17         dataSource.setPassword(password);
18         return dataSource;
19     }
20     //Spring事务管理需要的平台事务管理器对象
21     @Bean
22     public PlatformTransactionManager transactionManager(DataSource dataSource){
23         DataSourceTransactionManager dtm = new DataSourceTransactionManager();
24         dtm.setDataSource(dataSource);
25         return dtm;
26     }
27 }

jdbc.properties

1 jdbc.driver=com.mysql.jdbc.Driver
2 jdbc.url=jdbc:mysql://localhost:3306/test?useSSL=false&useServerPrepStmts=true&serverTimezone=UTC
3 jdbc.username=root
4 jdbc.password=123456

SpringMVC

ServletConfig

 1 public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
 2     protected Class<?>[] getRootConfigClasses() {
 3         return new Class[]{SpringConfig.class};
 4     }
 5 
 6     protected Class<?>[] getServletConfigClasses() {
 7         return new Class[]{SpringMvcConfig.class};
 8     }
 9 
10     protected String[] getServletMappings() {
11         return new String[]{"/"};
12     }
13 }

SpringMvcConfig

1 @Configuration
2 @ComponentScan("com.test.controller")
3 @EnableWebMvc
4 public class SpringMvcConfig {
5 }

3.功能模块

表与实体类

1 public class Book {
2     private Integer id;
3     private String type;
4     private String name;
5     private String description;
6     ...    //getter、setter、toString()方法
7 }

dao(接口+自动代理)

 1 public interface BookDao {
 2     //@Insert("insert into tbl_book values(null,#{type},#{name},#{description})")
 3     @Insert("insert into tbl_book (type,name,description) values(#{type},#{name},#{description})")
 4     public int save(Book book);  //返回值表示影响的行数
 5 
 6     @Update("update tbl_book set type = #{type}, name = #{name}, description = #{description} where id = #{id}")
 7     public int update(Book book);
 8 
 9     @Delete("delete from tbl_book where id = #{id}")
10     public int delete(Integer id);
11 
12     @Select("select * from tbl_book where id = #{id}")
13     public Book getById(Integer id);
14 
15     @Select("select * from tbl_book")
16     public List<Book> getAll();
17 }

service(接口+实现类)

接口:

 1 @Transactional  //表示所有方法进行事务管理
 2 public interface BookService {
 3     /**
 4      * 增加
 5      * @param book
 6      * @return
 7      */
 8     public boolean save(Book book);
 9 
10     /**
11      * 修改
12      * @param book
13      * @return
14      */
15     public boolean update(Book book);
16 
17     /**
18      * 根据id删除
19      * @param id
20      * @return
21      */
22     public boolean delete(Integer id);
23 
24     /**
25      * 根据id查询
26      * @param id
27      * @return
28      */
29     public Book getById(Integer id);
30 
31     /**
32      * 查询全部
33      * @return
34      */
35     public List<Book> getAll();
36 }

实现类:

 1 @Service
 2 public class BookServiceImpl implements BookService {
 3     @Autowired
 4     private BookDao bookDao;
 5 
 6     public boolean save(Book book) {
 7         bookDao.save(book);
 8         return true;
 9     }
10 
11     public boolean update(Book book) {
12         bookDao.update(book);
13         return true;
14     }
15 
16     public boolean delete(Integer id) {
17         bookDao.delete(id);
18         return true;
19     }
20 
21     public Book getById(Integer id) {
22         return bookDao.getById(id);
23     }
24 
25     public List<Book> getAll() {
26         return bookDao.getAll();
27     }
28 }

业务层接口测试(整合JUnit)

 1 @RunWith(SpringJUnit4ClassRunner.class)
 2 @ContextConfiguration(classes = SpringConfig.class)
 3 public class BookServiceTest {
 4     @Autowired
 5     private BookService bookService;
 6 
 7     @Test
 8     public void testGetById(){
 9         Book book = bookService.getById(1);
10         System.out.println(book);
11     }
12     @Test
13     public void testGetAll(){
14         List<Book> books = bookService.getAll();
15         System.out.println(books);
16     }
17 }

controller

Result类封装响应结果:

 1 public class Result {
 2     //描述统一格式中的数据
 3     private Object data;
 4     //描述统一格式中的编码,用于区分操作,可以简化配置0或1表示成功失败
 5     private Integer code;
 6     //描述统一格式中的消息,可选属性
 7     private String msg;
 8 
 9     public Result() {
10     }
11     public Result(Integer code,Object data) {
12         this.data = data;
13         this.code = code;
14     }
15     public Result(Integer code, Object data, String msg) {
16         this.data = data;
17         this.code = code;
18         this.msg = msg;
19     }
20      ...   //添加getter、setter方法
21 }

Code类封装响应码:

 1 //状态码
 2 public class Code {
 3     public static final Integer SAVE_OK = 20011;
 4     public static final Integer DELETE_OK = 20021;
 5     public static final Integer UPDATE_OK = 20031;
 6     public static final Integer GET_OK = 20041;
 7 
 8     public static final Integer SAVE_ERR = 20010;
 9     public static final Integer DELETE_ERR = 20020;
10     public static final Integer UPDATE_ERR = 20030;
11     public static final Integer GET_ERR = 20040;
12 }

表现层数据封装返回Result对象:

 1 @RestController
 2 @RequestMapping("/books")
 3 public class BookController {
 4     @Autowired
 5     private BookService bookService;
 6 
 7     @PostMapping
 8     public Result save(@RequestBody Book book) {
 9         boolean flag = bookService.save(book);
10         return new Result(flag?Code.SAVE_OK:Code.SAVE_ERR,flag);
11     }
12     @PutMapping
13     public Result update(@RequestBody Book book) {
14         boolean flag = bookService.update(book);
15         return new Result(flag?Code.UPDATE_OK:Code.UPDATE_ERR,flag);
16     }
17     @DeleteMapping("/{id}")
18     public Result delete(@PathVariable Integer id) {
19         boolean flag = bookService.delete(id);
20         return new Result(flag?Code.DELETE_OK:Code.DELETE_ERR,flag);
21     }
22     @GetMapping("/{id}")
23     public Result getById(@PathVariable Integer id) {
24         Book book = bookService.getById(id);
25         Integer code= book!=null?Code.GET_OK:Code.GET_ERR;
26         String msg=book!=null?"":"数据查询失败,请重试!";
27         return new Result(code,book,msg);
28     }
29     @GetMapping
30     public Result getAll() {
31         List<Book> books = bookService.getAll();
32         Integer code= books!=null?Code.GET_OK:Code.GET_ERR;
33         String msg=books!=null?"":"数据查询失败,请重试!";
34         return new Result(code,books,msg);
35     }
36 }

表现层接口测试(PostMan)

项目异常处理

项目异常分类

业务异常(BusinessException)
  规范的用户行为产生的异常
  不规范的用户行为操作产生的异常
系统异常(SystemException)
  项目运行过程中可预计且无法避免的异常
其他异常(Exception)
  编程人员未预期到的异常

项目异常处理方案

业务异常(BusinessException)
  发送对应消息传递给用户,提醒规范操作
系统异常(SystemException)
  发送固定消息传递给用户,安抚用户
  发送特定消息给运维人员,提醒维护
  记录日志
其他异常(Exception)
  发送固定消息传递给用户,安抚用户
  发送特定消息给编程人员,提醒维护(纳入预期范围内)
  记录日志

项目异常处理代码实现

根据异常分类自定义异常类

自定义项目系统级异常

 1 //自定义异常处理器,用于封装异常信息,对异常进行分类
 2 public class SystemException extends RuntimeException{
 3     private Integer code;
 4 
 5     public Integer getCode() {
 6         return code;
 7     }
 8     public void setCode(Integer code) {
 9         this.code = code;
10     }
11 
12     public SystemException(Integer code, String message) {
13         super(message);
14         this.code = code;
15     }
16 
17     public SystemException(Integer code, String message, Throwable cause) {
18         super(message, cause);
19         this.code = code;
20     }
21 }

自定义项目业务级异常

 1 //自定义异常处理器,用于封装异常信息,对异常进行分类
 2 public class BusinessException extends RuntimeException{
 3     private Integer code;
 4 
 5     public Integer getCode() {
 6         return code;
 7     }
 8     public void setCode(Integer code) {
 9         this.code = code;
10     }
11 
12     public BusinessException(Integer code, String message) {
13         super(message);
14         this.code = code;
15     }
16 
17     public BusinessException(Integer code,String message,Throwable cause) {
18         super(message, cause);
19         this.code = code;
20     }
21 }

自定义异常编码(持续补充)

1 public class Code {
2     //之前其他状态码省略没写,以下是新补充的状态码,可以根据需要自己补充  
3     public static final Integer SYSTEM_ERR = 50001;
4     public static final Integer SYSTEM_TIMEOUT_ERR = 50002;
5     public static final Integer SYSTEM_UNKNOW_ERR = 59999;
6     public static final Integer BUSINESS_ERR = 60002;
7     
8 }

触发自定义异常

 1 @Service
 2 public class BookServiceImpl implements BookService {
 3     @Autowired
 4     private BookDao bookDao;
 5     //在getById演示触发异常,其他方法省略
 6     public Book getById(Integer id) {
 7         //模拟业务异常,包装成自定义异常
 8         if(id <0){
 9             throw new BusinessException(Code.BUSINESS_ERR,"请不要使用你的技术挑战我的耐性!");
10         }
11     }
12 }

在异常通知类中拦截并处理异常(异常处理器)

@RestControllerAdvice
  类型:类注解
  位置:Rest风格开发的控制器增强类定义上方。
  作用:为Rest风格开发的控制器类做增强。
  说明:此注解自带@ResponseBody注解与@Component注解,具备对应的功能。

@ExceptionHandler
  类型:方法注解
  位置:专用于异常处理的控制器方法上方。
  作用:设置指定异常的处理方案,功能等同于控制器方法,出现异常后终止原始控制器执行,并转入当前方法执行。
  说明:此类方法可以根据处理的异常不同,制作多个方法分别处理对应的异常。

 1 @RestControllerAdvice //用于标识当前类为REST风格对应的异常处理器
 2 public class ProjectExceptionAdvice {
 3     //@ExceptionHandler用于设置当前处理器类对应的异常类型
 4     @ExceptionHandler(SystemException.class)
 5     public Result doSystemException(SystemException ex){
 6         //记录日志
 7         //发送消息给运维
 8         //发送邮件给开发人员,ex对象发送给开发人员
 9         return new Result(ex.getCode(),null,ex.getMessage());
10     }
11 
12     @ExceptionHandler(BusinessException.class)
13     public Result doBusinessException(BusinessException ex){
14         return new Result(ex.getCode(),null,ex.getMessage());
15     }
16 
17     //除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常
18     @ExceptionHandler(Exception.class)
19     public Result doOtherException(Exception ex){
20         //记录日志
21         //发送消息给运维
22         //发送邮件给开发人员,ex对象发送给开发人员
23         return new Result(Code.SYSTEM_UNKNOW_ERR,null,"系统繁忙,请稍后再试!");
24     }
25 }

注:该方法所在的包要在SpringMvcConfig配置类的@ComponentScan()注解中添加。

  

 测试结果:

SSM整合页面开发【重点】

准备工作

为了确保静态资源能够被访问到,需要设置静态资源过滤

 1 @Configuration
 2 public class SpringMvcSupport extends WebMvcConfigurationSupport {
 3     @Override
 4     protected void addResourceHandlers(ResourceHandlerRegistry registry) {
 5         registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
 6         registry.addResourceHandler("/css/**").addResourceLocations("/css/");
 7         registry.addResourceHandler("/js/**").addResourceLocations("/js/");
 8         registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
 9     }
10 }

列表查询功能

前端代码

1 //列表
2 getAll() {
3     //发送ajax请求
4     axios.get("/books").then((res)=>{
5         this.dataList = res.data.data;
6     });
7 }

添加功能

前端代码

 1 //弹出添加窗口
 2 handleCreate() {
 3     this.dialogFormVisible = true;
 4     this.resetForm();
 5 },
 6 //重置表单
 7 resetForm() {
 8     this.formData = {};
 9 },
10 //添加
11 handleAdd () {
12     //发送ajax请求
13     axios.post("/books",this.formData).then((res)=>{
14         console.log(res.data);
15         //如果操作成功,关闭弹层,显示数据
16         if(res.data.code == 20011){
17             this.dialogFormVisible = false;
18             this.$message.success("添加成功");
19         }else if(res.data.code == 20010){
20             this.$message.error("添加失败");
21         }else{
22             this.$message.error(res.data.msg);
23         }
24     }).finally(()=>{
25         this.getAll();
26     });
27 },

后台代码改进

 1 public interface BookDao {
 2     @Insert("insert into tbl_book values (null,#{type},#{name},#{description})")
 3     public int save(Book book); //返回值改为int
 4     @Update("update tbl_book set type=#{type},name=#{name},description=#{description} where id=#{id}")
 5     public int update(Book book);   //返回值改为int
 6     @Delete("delete from tbl_book where id=#{id}")
 7     public int delete(Integer id);  //返回值改为int
 8     @Select("select * from tbl_book where id=#{id}")
 9     public Book getById(Integer id);
10     @Select("select * from tbl_book")
11     public List<Book> getAll();
12 }
 1 @Service
 2 public class BookServiceImpl implements BookService {
 3     @Autowired
 4     private BookDao bookDao;
 5     //增删改的方法判断了影响的行数是否大于0,而不是固定返回true
 6     public boolean save(Book book) {
 7         return bookDao.save(book) > 0;
 8     }
 9     //增删改的方法判断了影响的行数是否大于0,而不是固定返回true
10     public boolean update(Book book) {
11         return bookDao.update(book) > 0;
12     }
13     //增删改的方法判断了影响的行数是否大于0,而不是固定返回true
14     public boolean delete(Integer id) {
15         return bookDao.delete(id) > 0;
16     }
17 
18     public Book getById(Integer id) {
19         if(id < 0){
20             throw new BusinessException(Code.BUSINESS_ERR,"请不要使用你的技术挑战我的耐性!");
21             return bookDao.getById(id);
22         }
23     }
24     public List<Book> getAll() {
25         return bookDao.getAll();
26     }
27 }

修改功能

显示弹出框查询图书信息

 1 //弹出编辑窗口
 2 handleUpdate(row) {
 3     // console.log(row);   //row.id 查询条件
 4     //查询数据,根据id查询
 5     axios.get("/books/"+row.id).then((res)=>{
 6         // console.log(res.data.data);
 7         if(res.data.code == 20041){
 8             //展示弹层,加载数据
 9             this.formData = res.data.data;
10             this.dialogFormVisible4Edit = true;
11         }else{
12             this.$message.error(res.data.msg);
13         }
14     });
15 }

保存修改后的图书信息

 1 //编辑
 2 handleEdit() {
 3     //发送ajax请求
 4     axios.put("/books",this.formData).then((res)=>{
 5         //如果操作成功,关闭弹层,显示数据
 6         if(res.data.code == 20031){
 7             this.dialogFormVisible4Edit = false;
 8             this.$message.success("修改成功");
 9         }else if(res.data.code == 20030){
10             this.$message.error("修改失败");
11         }else{
12             this.$message.error(res.data.msg);
13         }
14     }).finally(()=>{
15         this.getAll();
16     });
17 }

删除功能

 1 // 删除
 2 handleDelete(row) {
 3     //1.弹出提示框
 4     this.$confirm("此操作永久删除当前数据,是否继续?","提示",{
 5         type:'info'
 6     }).then(()=>{
 7         //2.做删除业务
 8         axios.delete("/books/"+row.id).then((res)=>{
 9             if(res.data.code == 20021){
10                 this.$message.success("删除成功");
11             }else{
12                 this.$message.error("删除失败");
13             }
14         }).finally(()=>{
15             this.getAll();
16         });
17     }).catch(()=>{
18         //3.取消删除
19         this.$message.info("取消删除操作");
20     });
21 }

 

posted @ 2023-07-28 13:56  溯鸣  阅读(7)  评论(0编辑  收藏  举报