- 包结构
- 环境搭建
- 基础案例
config
dao
service
controller
domain
exception (异常类)
resource———》 jdbc.properties
环境搭建
pom.xml坐标:
<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.0modelVersion>
<groupId>com.itheima.SpringMvcSumgroupId>
<artifactId>SpringMvcSumartifactId>
<version>1.0-SNAPSHOTversion>
<packaging>warpackaging>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.2.10.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>5.2.10.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>5.2.10.RELEASEversion>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.6version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatis-springartifactId>
<version>1.3.0version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.47version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.1.16version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
<scope>testscope>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>3.1.0version>
<scope>providedscope>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.0version>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
<dependency>
<groupId>org.apache.logging.log4jgroupId>
<artifactId>log4j-to-slf4jartifactId>
<version>2.11.2version>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.mavengroupId>
<artifactId>tomcat7-maven-pluginartifactId>
<version>2.1version>
<configuration>
<port>80port>
<path>/path>
configuration>
plugin>
plugins>
build>
project>
Config:
SpringConfig:
@Configuration
@ComponentScan("com.it.service")
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class,MybatisConfig.class})
public class SpringConfig {
}
Spring整合Mybatis:
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 dataSource = new DruidDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
MybatisConfig:
public class MybatisConfig {
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setTypeAliasesPackage("com.it.domain");
return factoryBean;
}
@Bean
public MapperScannerConfigurer mapperScannerConfigurer() {
MapperScannerConfigurer msc = new MapperScannerConfigurer();
msc.setBasePackage("com.it.dao");
return msc;
}
}
resources:
jdbc.properties:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm_db
jdbc.username=root
jdbc.password=1234
SpringMvcConfig:
@Configuration
@EnableWebMvc
@ComponentScan("com.it.controller")
@EnableTransactionManagement //SpringMvc开启事务
public class SpringMvcConfig {
}
ServletConfig:替代web.xml
public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
protected String[] getServletMappings() {
return new String[]{"/"}; //拦截所有
}
//这里可以添加一个过滤器,用来设置字符集编码
}
基础案例
dao:
BookDao:
public interface BookDao {
@Insert("insert into tbl_book values(null,#{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")
public List<Book> getAll();
@Select("select * from tbl_book where id=#{id}")
public Book getByid(Integer id);
}
service:
BookService:
@Transactional //开启事务 一般情况下 都在业务层接口开启事务
public interface BookService {
/**
* 保存,添加
* @param book 添加的图书信息
* @return 返回布尔型,表示该 *** 作成功与否
*/
public boolean save(Book book);
/**
* 更新,修改
* @param book 更新的图书信息
* @return 返回布尔型,表示该 *** 作成功与否
*/
public boolean update(Book book);
/**
* 删除
* @param id 要删除的id号
* @return 返回布尔型,表示该 *** 作成功与否
*/
public boolean delete(Integer id);
/**
* 查询所有
* @return 返回一个集合 集合中包括所有书籍信息
*/
public List<Book> getAll();
/**
* 通过id查询一本图书
* @param id 图书id
* @return 返回一本图书信息
*/
public Book getByid(Integer id);
}
BookServiceImpl:
@Service
public class BookServiceImpl implements BookService {
@Autowired //这里使用dao层接口,使用spring自动注入
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 List<Book> getAll() {
return bookDao.getAll();
}
public Book getByid(Integer id) {
//模拟异常
if(id==1){
throw new BusinessException(Code.BUSINESS_ERR,"异常出现的消息提示");
}
//将可能出现的异常进行包装,转换成自定义异常
try {
int i = 1/0;
} catch (Exception e) { // throw语句通常用在方法体中,并且抛出一个异常对象。程序在执行到throw语句时立即停止,它后面的语句都不执行
throw new SystemException(Code.SYSTEM_ERR,"服务器超时,请重试",e);
}
return bookDao.getByid(id);
}
}
controller:
BookController:
@RestController
@RequestMapping("/books")
@ResponseBody
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
public Result getAll() {
List<Book> books = bookService.getAll();
Integer code = books != null ? Code.GET_OK : Code.GET_ERR;
String msg = books != null ? "查询成功" : "数据查询失败,请重试";
return new Result(code, books, msg);
}
@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);
}
}
由于前端人员看到异常信息的多样性和复杂性,我们后端给予处理,在表现层将所有调用业务层处理后的数据统一返回一个格式,方便前端人员处理,所以我们定义一个类,用来做为统一返回的类型格式(在实际开发中,返回的类型可能不止这些,根据业务需求而定,这里只简单的举例,思想是一样的,应该学会灵活运用)
没有经过处理的异常信息:
Result:
public class Result {
private Object data;//返回的结果数据
private Integer code; //返回的状态码
private String msg; //返回的提示信息
public Result( Integer code,Object data, String msg) {
this.data = data;
this.code = code;
this.msg = msg;
}
public Result(Integer code,Object data ) {
this.data = data;
this.code = code;
}
public Result() { }
public Object getData() {
return data;
}
public void setData(Object data) {
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;
}
}
由于状态码直接使用数字写在程序中不够专业,这里编写一个对象,用来存放这些状态码,并且将它们设置为静态常量这样在使用时,可以不创建对象,直接通过 对象.常量名 进行访问
Code:根据需求持续添加状态码,可以无数多
public class Code {
//增删改查状态码
public static final Integer SAVE_OK =2011;
public static final Integer DELETE_OK =2021;
public static final Integer UPDATE_OK =2031;
public static final Integer GET_OK =2041;
//失败
public static final Integer SAVE_ERR =2000;
public static final Integer DELETE_ERR =2020;
public static final Integer UPDATE_ERR =2030;
public static final Integer GET_ERR =2040;
//系统异常
public static final Integer SYSTEM_ERR = 50001;
//业务异常
public static final Integer BUSINESS_ERR = 60002;
//系统位置异常
public static final Integer SYSTEM_UNKONW_ERR = 59999;
}
前面是解决表现层返回值类型问题,我们进行了统一的要求。但在实际开发过程中,在前端中返回的结果可能会出现异常信息,所以我们应该定义一个异常处理器,用来拦截异常信息,并将异常信息封装为上面统一的格式,方便前端人员辨别和处理。
ProjectExceptionAdvice:异常拦截器,用户的异常信息会被该拦截器拦下,并进行分类(业务异常,系统异常,其它异常等)处理
/**
* 异常处理器类
*/
@RestControllerAdvice //advice:通知
public class ProjectExceptionAdvice {
/**
* 系统异常处理:应记录相关的异常信息,让运维和开发解决
* @param ex 异常参数
* @return 返回异常状态码,提示信息
*/
@ExceptionHandler(SystemException.class) // 异常处理器 拦截System异常
public Result doSystemException(SystemException ex) { //收集异常的方法
//记录日志
//发送消息给运维
//发送邮件给开发人员
return new Result(ex.getCode(), null, ex.getMessage());
}
/**
* 业务层异常:由于用户输入了不规范的数据导致,直接返回异常信息即可
* @param ex
* @return
*/
@ExceptionHandler(BusinessException.class) // 异常处理器 拦截Business异常
public Result doBusinessException(BusinessException ex) { //收集异常的方法
return new Result(ex.getCode(), null, ex.getMessage());
}
/**
* 其他异常
* @param ex
* @return
*/
@ExceptionHandler(Exception.class) // 异常处理器 拦截所有异常
public Result doException(Exception ex) { //收集异常的方法 所有异常都会进来
//记录日志
//发送消息给运维
//发送邮件给开发人员
return new Result(Code.SYSTEM_UNKONW_ERR, null, "系统繁忙,请稍后再试!");
}
}
下面定义了系统异常和业务异常,除此之外的异常统一为其它异常
exception:
SystemException:
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;
}
}
BusinessException:
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;
}
}
异常定义完之后,可以在合适的地方抛出异常,异常会被拦截器拦截并分类处理,最终返回给前端
模拟异常抛出:
if(id==1){
throw new BusinessException(Code.BUSINESS_ERR,"异常出现的消息提示"); //抛出业务异常
}
结果:
//将可能出现的异常进行包装,转换成自定义异常
try {
int i = 1/0;
} catch (Exception e) { // throw语句通常用在方法体中,并且抛出一个异常对象。程序在执行到throw语句时立即停止,它后面的语句都不执行
throw new SystemException(Code.SYSTEM_ERR,"服务器超时,请重试",e); //抛出系统异常
}
结果:
测试表现层正常情况下的返回值:
提示:该文章为学习笔记,如有错误,望大佬批评指正,留言必回
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)