spring SSM搭建demo
一、创建maven项目

二、导入相关坐标
在pom.xml中加入
<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.6</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</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>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
</dependencies>
<build>
<finalName>spring_ssm_demo</finalName>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>8088</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
三、创建配置类
1、创建SpringMvcConfig类配置SpringMvc
package com.itheima.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; @Configuration @ComponentScan(basePackages = {"com.itheima.controller"}) @EnableWebMvc public class SpringMvcConfig { }
2、创建SpringConfig类
package com.itheima.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.PropertySource; @Configuration @ComponentScan(basePackages = {"com.itheima.service", "com.itheima.dao"}) @PropertySource("classpath:jdbc.properties") @Import({JdbcConfig.class,MyBatisConfig.class}) public class SpringConfig { }
3、创建JdbcConfig类
package com.itheima.config; import com.alibaba.druid.pool.DruidDataSource; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import javax.sql.DataSource; 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 dataSource = new DruidDataSource(); dataSource.setDriverClassName(driver); dataSource.setUrl(url); dataSource.setUsername(username); dataSource.setPassword(password); return dataSource; } }
4、创建MyBatisConfig类
package com.itheima.config; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.mapper.MapperScannerConfigurer; import org.springframework.context.annotation.Bean; import javax.sql.DataSource; public class MyBatisConfig { // 配置mybatis的工厂 @Bean public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) { SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); factoryBean.setDataSource(dataSource); factoryBean.setTypeAliasesPackage("com.itheima.domain"); return factoryBean; } // 配置mybatis的扫描 @Bean public MapperScannerConfigurer mapperScannerConfigurer() { MapperScannerConfigurer msc = new MapperScannerConfigurer(); // 指定dao所在的包 msc.setBasePackage("com.itheima.dao"); return msc; } }
5、创建数据源配置文件,在resources文件夹下创建,jdbc.properties文件
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1:3306/test?useSSL=false jdbc.username=root jdbc.password=123456
6、创建ServcletConfig类
package com.itheima.config;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import javax.servlet.Filter;
public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
// 配置Spring
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
// 配置
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
// 映射,将所有请求映射到SpringMVC中
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
// 乱码处理
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
filter.setForceEncoding(true);
return new Filter[]{filter};
}
}
四、创建数据库类
创建domain文件夹,并在下面创建Book类
package com.itheima.domain; public class Book { private Integer id; private String type; private String name; private String description; @Override public String toString() { return "Book{" + "id=" + id + ", type='" + type + '\'' + ", name='" + name + '\'' + ", description='" + description + '\'' + '}'; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } }
五、创建Dao层
创建Dao文件夹,并创建BookDao接口文件
package com.itheima.dao; import com.itheima.domain.Book; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update; import java.util.List; 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} where id = #{id}") 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(); }
六、创建Service层
1、在service文件夹下创建BookService接口类
package com.itheima.service; import com.itheima.domain.Book; import org.springframework.transaction.annotation.Transactional; import java.util.List; @Transactional public interface BookService { /** * 保存 * @param book * @return */ public boolean save(Book book); /** * 修改 * @param book * @return */ public boolean update(Book book); /** * 按id删除 * @param id * @return */ public boolean delete(Integer id); /** * 按id查询 * @param id * @return */ public Book getById(Integer id); /** * 查询全部 * @return */ public List<Book> getAll(); }
2、创建BookService实现类,在service文件夹下创建impl文件夹并创建BookServiceImpl类文件
package com.itheima.service.impl; import com.itheima.dao.BookDao; import com.itheima.domain.Book; import com.itheima.service.BookService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @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(); }
}
七、创建controller层
创建controller文件夹并创建BookController类文件
package com.itheima.controller; import com.itheima.dao.BookDao; import com.itheima.domain.Book; import com.itheima.service.BookService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/books") public class BookController { @Autowired private BookService bookService; @PostMapping("/save") public Boolean save(@RequestBody Book book) { bookService.save(book); return true; } @PutMapping("/update") public Boolean update(@RequestBody Book book) { bookService.update(book); return true; } @DeleteMapping("/{id}") public Boolean delete(@PathVariable Integer id) { bookService.delete(id); return true; } @GetMapping("/{id}") public Book getById(@PathVariable Integer id) { return bookService.getById(id); } @GetMapping public List<Book> getAll() { return bookService.getAll(); }
}
到此,就创建完了。接下来两种方式测试下是否成功。
八、配置tomcat,启动项目

九、写测试类,进行测试
在test文件夹下的java文件夹下创建测试类BookServiceTest文件
import com.itheima.config.SpringConfig; import com.itheima.domain.Book; import com.itheima.service.BookService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.util.List; @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); } @Test public void testGetAll(){ List<Book> all = bookService.getAll(); System.out.println(all); } }
测试类的运行不必要进行第八步启动项目。测试类可以单独运行。
十、增加定义返回类型(返回格式)
1、在controller文件夹中创建Result类文件,用于构造返回类型
package com.itheima.controller; public class Result { private Integer code; private String msg; private Object data; // 构造函数 public Result() { } // 带参构造函数, 传入code和data public Result(Integer code, Object data) { this.code = code; this.data = data; } // 带参构造函数, 传入code, msg和data public Result(Integer code, String msg, Object data) { this.code = code; this.msg = msg; this.data = data; } public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } @Override public String toString() { return "Result{" + "code=" + code + ", msg='" + msg + '\'' + ", data=" + data + '}'; } }
2、修改原先的BookController文件,使其返回类型为Result类
package com.itheima.controller; import com.itheima.dao.BookDao; import com.itheima.domain.Book; import com.itheima.service.BookService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/books") public class BookController { @Autowired private BookService bookService; @PostMapping("/save") public Result save(@RequestBody Book book) { boolean flog = bookService.save(book); // 构造返回对象 Result result = new Result(); if (!flog) { result.setCode(500); result.setMsg("保存失败"); return result; } else { result.setCode(200); result.setMsg("保存成功"); return result; } } @PutMapping("/update") public Result update(@RequestBody Book book) { boolean flog = bookService.update(book); // 构造返回对象 Result result = new Result(); // 设置返回码,成功为200,失败为500 result.setCode(flog? 200 : 500); // 设置返回信息,成功为"保存成功",失败为"保存失败" result.setMsg(flog? "更新成功" : "更新失败"); return result; } @DeleteMapping("/{id}") public Result delete(@PathVariable Integer id) { boolean flog = bookService.delete(id); Result result = new Result(); result.setCode(flog? 200 : 500); result.setMsg(flog? "删除成功" : "删除失败"); return result; } @GetMapping("/{id}") public Result getById(@PathVariable Integer id) { Book book = bookService.getById(id); Result result = new Result(); result.setData(book); result.setCode(book != null ? 200 : 500); result.setMsg(book != null ? "查询成功" : "查询失败"); return result; } @GetMapping public Result getAll() { List<Book> books = bookService.getAll(); Result result = new Result(); result.setData(books); result.setCode(books.size() > 0 ? 200 : 500); result.setMsg(books.size() > 0 ? "查询成功" : "查询失败"); return result; } }
十一、增加异常统一处理
1、在controller文件夹下创建ProjectExceptionAdvice类文件进行处理异常
package com.itheima.controller; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; @RestControllerAdvice public class ProjectExceptionAdvice { private Result setResult(int code, String msg, Object data) { Result result = new Result(); result.setCode(code); result.setMsg(msg); result.setData(data); return result; } @ExceptionHandler(Exception.class) public Result doException(Exception e) { // 输出错误信息 System.out.println(e.getMessage()); //返回错误信息 Result result = setResult(500, "未知异常:" + e.getMessage(), null); return result; } }
2、也可以增加自定义异常分类
创建exception文件夹,进行创建异常分类的类。一般分为:业务异常(BusinessException),系统异常(SystemException)
文件BusinessException
package com.itheima.exception; public class BusinessException extends RuntimeException { private Integer code; private String message; public BusinessException(Integer code, String message) { super(message); this.code = code; } 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; } @Override public String toString() { return "BusinessException{" + "code=" + code + ", message='" + message + '\'' + '}'; } }
文件SystemException
package com.itheima.exception; public class SystemException extends RuntimeException{ private Integer code; private String message; public SystemException(Integer code, String message) { super(message); this.code = code; } 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; } @Override public String toString() { return "BusinessException{" + "code=" + code + ", message='" + message + '\'' + '}'; } }
修改controller类文件
package com.itheima.controller; import com.itheima.exception.BusinessException; import com.itheima.exception.SystemException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; @RestControllerAdvice public class ProjectExceptionAdvice { private Result setResult(int code, String msg, Object data) { Result result = new Result(); result.setCode(code); result.setMsg(msg); result.setData(data); return result; } @ExceptionHandler(SystemException.class) public Result doSystemException(SystemException e) { // 输出错误信息 System.out.println(e.getMessage()); //返回错误信息 Result result = setResult(e.getCode(), "系统异常:" + e.getMessage(), null); return result; } @ExceptionHandler(BusinessException.class) public Result doBusinessException(BusinessException e) { // 输出错误信息 System.out.println(e.getMessage()); //返回错误信息 Result result = setResult(e.getCode(), "操作异常:" + e.getMessage(), null); return result; } @ExceptionHandler(Exception.class) public Result doException(Exception e) { // 输出错误信息 System.out.println(e.getMessage()); //返回错误信息 Result result = setResult(500, "未知异常:" + e.getMessage(), null); return result; } }
测试是否生效,或者如何使用,例如:修改下controller文件下的BookController的delete方法
@DeleteMapping("/{id}")
public Result delete(@PathVariable Integer id) {
// boolean flog = bookService.delete(id);
Result result = new Result();
// result.setCode(flog? 200 : 500);
// result.setMsg(flog? "删除成功" : "删除失败");
if(id == 1){
throw new RuntimeException("删除失败");
}else if(id == 2){
throw new BusinessException(501,"删除失败");
}else if(id == 3){
throw new SystemException(503,"删除失败");
}
return result;
}
十二、最终项目目录结构


浙公网安备 33010602011771号