JdbcConfig:
java
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;
}
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
DataSourceTransactionManager ds = new DataSourceTransactionManager();
ds.setDataSource(dataSource);
return ds;
}
}
@Bean:定义第三方的插件bean类
MybatisConfig:
java
public class MybatisConfig {
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setTypeAliasesPackage("com.example.domain");
return factoryBean;
}
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer msc = new MapperScannerConfigurer();
msc.setBasePackage("com.example.dao");
return msc;
}
}
ServletConfig:
java
public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
//加载Spring配置类
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
//加载SpringMVC配置类
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
//设置SpringMVC请求地址拦截规则
protected String[] getServletMappings() {
return new String[]{"/"};
}
//设置post请求中文乱码过滤器
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("utf-8");
return new Filter[]{filter};
}
}
SpringConfig:
java
@Configuration
@ComponentScan("com.example.service")
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class, MybatisConfig.class})
@EnableTransactionManagement
public class SpringConfig {
}
@Configuration:标注为配置文件
@ComponentScan:标注要扫描的目录(Spring主要负责service层)
@PropertySource:加载数据库jdbc文件,classPath通过path加载
@Import:加载需要加载的Bean文件
@EnableTransactionManagement:允许启用事务回滚机制
SpringMvcConfig:
java
@Configuration
@ComponentScan("com.example.controller")
@EnableWebMvc
public class SpringMvcConfig {
}
@EnableWebMvc:启用Spring-Mvc功能
resources**\**jdbc.properties
java
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/数据库名
jdbc.username=账户名
jdbc.password=账户密码
项目主要文件层级:
![](https://i-blog.csdnimg.cn/direct/6c42451e590441b38b87b60e951d1300.png)
项目Test层级:
![](https://i-blog.csdnimg.cn/direct/7925a4cd4ab640388b45da5d055342b8.png)
Test文件内容:
java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class BookServiceTest {
@Autowired
private BookService bookService;
@Test
public void testGetById(){
Book book = bookService.getById(15);
System.out.println(book);
}
@Test
public void testGetAll(){
List<Book> all = bookService.getAll();
System.out.println(all);
}
}
@Autowired:自动从spring中取出实体类
@Test:定义为测试类
Dao层:
主要用于数据层,书写sql语句
java
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();
}
Sql方法注解:@Insert、@Update、@Select、@Delete
domain层:
定义数据模态层
java
public class Book {
private Integer id;
private String type;
private String name;
private String description;
//省略Getter和Setter...
}
Service服务层:
java
@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();
}
@Transactional:定义该Service允许事务回滚
Service的实体类Impl:
java
@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookDao bookDao;
public boolean save(Book book) {
bookDao.save(book);
return true;
}
}
@Service:Service层的Impl必须声明为Service才会被Spring自动收集
异常处理类
java
@RestControllerAdvice
public class ProjectExceptionAdvice {
//除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常
@ExceptionHandler(Exception.class)
public void doException(Exception ex){
System.out.println("嘿嘿,异常你哪里跑!")
}
}
@RestControllerAdvice:@ResponseBody风格的异常处理
@RestControllerAdvice=@ControllerAdvice+@ResponseBody
如异常处理为文件夹,须在SpringMvcConfig中配置ComponentScan
异常分类
分为三类:
1.业务异常(Business Excption)
数据遗漏、提示规范操作
java
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;
}
}
2.系统异常(System Excption)
数据库、服务器宕机
java
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 msg, Throwable cause) {
super(msg, cause);
this.code = code;
}
}
3.其他异常(Excption)
未预期到的异常
整合异常处理
java
@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, "系统繁忙,请稍后重试");
}
}
拦截器开发
步骤1:创建ProjectInterceptor,重写HandlerInterceptor
java
@Component
public class ProjectInterceptor implements HandlerInterceptor {
@Override
//原始方法调用前执行的内容
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle...");
return true;
}
@Override
//原始方法调用后执行的内容
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle...");
}
@Override
//原始方法调用完成后执行的内容
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion...");
}
}
步骤2:修改SpringMvcConfig,具有一定侵入性
java
public class SpringMvcConfig implements WebMvcConfigurer {
@Autowired
private ProjectInterceptor projectInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//配置多拦截器
registry.addInterceptor(projectInterceptor).addPathPatterns("/books", "/books/*");
}
}
通过拦截器获取参数
request:请求体 response:响应体 handler:被调用的处理器对象
preHandle
获取header中内容:request.getHeader(头部key名)
handler:
java
HandlerMethod hm = (HandlerMethod) handler;
String methodName = hm.getMethod().getName();
postHandle
ModelAndView modelAndView: 如果处理器执行完成具有返回结果,可以读取到对应数据与页面信息,并进行调整。 因为都是返回 json 数据,所以该参数的使用率不高
afterCompletion
配置多个拦截器
新增拦截器文件,在SpringMvcConfig中添加
java
@Configuration
@ComponentScan({"com.example.controller", "com.example.exception"})
@EnableWebMvc
public class SpringMvcConfig implements WebMvcConfigurer {
@Autowired
private ProjectInterceptor projectInterceptor;
@Autowired
private ProjectInterceptor2 projectInterceptor2;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//配置多拦截器
registry.addInterceptor(projectInterceptor).addPathPatterns("/books", "/books/*");
//新添加的拦截器
registry.addInterceptor(projectInterceptor2).addPathPatterns("/books", "/books/*");
}
}