项目在源代码无错误的前提下报错:
1:检查解释器配置
2:检查pom文件包导入的错误或者包版本之间的冲突
3:有没有重复文件导致冲突
4:注解开发时忘记注入
完整ssm开发:
项目链接
该框架开发包括mybatis框架,数据库连接,控制器,前端vue开发,拦截器等的编写开发
配置类config:
Spring的核心配置类
SpringConfig:
({"com.controller", "com.config", "com.service"}) //开启bean的扫描,注意别重复写!!!
//开启json数据转换成为数据对象的功能,重点开发注解
public class SpringMvcConfig {
}
数据库信息的配置:
JdbcConfig:
("classpath:jdbc.properties") //资源的导入
//表示该类为spring的配置类
public class JdbcConfig {
("${jdbc.driver}")
private String driver;
("${jdbc.url}")
private String url;
("${jdbc.username}")
private String username;
("${jdbc.password}")
private String password;
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
Mybatis框架整理
MybatisConfig:
//表示该类为spring的配置类
public class MyBatisConfig {
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setTypeAliasesPackage("com.domain"); //扫描javabean
return factoryBean;
}
public MapperScannerConfigurer mapperScannerConfigurer() {
MapperScannerConfigurer msc = new MapperScannerConfigurer();
msc.setBasePackage("com.dao"); //进行dao接口的扫描
return msc;
}
}
Spring容器的建立,前后端交互控制
springContainerConfig:
class SpringContainerConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
} //该操作会阻挡所有的网页访问,所以需要重新建立访问规则:SpringMvcSupport.java
//乱码处理,当发送post请求时无法处理中文
protected javax.servlet.Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("utf-8");
return new Filter[]{filter};
}
}
public
当Spring容器建立后静态资源会被拦截器阻拦导致无法访问,因此需要重新建立静态资源的访问规则
SpringMvcSupport:
//表示该类为spring的配置类public class SpringMvcSupport extends WebMvcConfigurationSupport {
// @Autowired
// private HandlerInterceptor loginInterceptor;
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
//当访问html文件的时候,直接可以进行访问
registry.addResourceHandler("/static2/**", "/static2/"); //当访问pages目录时就加载pages目录下的东西
registry.addResourceHandler("/static2/css/**", "/static2/css/"); //当访问css目录时就加载css目录下的东西
registry.addResourceHandler("/static2/element-ui/**", "/static2/element-ui/"); //当访问element-ui目录时就加载element-ui目录下的东西
registry.addResourceHandler("/static2/images/**", "/static2/images/"); //当访问images目录时就加载images目录下的东西
registry.addResourceHandler("/static2/js/**", "/static2/js/"); //当访问js目录时就加载js目录下的东西
}
/**
* 配置默认servlet处理
* 先经过 DefaultServletHttpRequestHandler 判断是否是静态文件,如果是静态文件,则进行处理,不是则放行交由 DispatcherServlet 控制器处理。
*/
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
数据查询控制器类,在该类里边加载访问以及访问方式(自己建立访问示例)
BrandController:
//标志为控制器类
("/brands")
public class BrandController {
//属性的注入
private BrandService brandService;
public Result save( Brand brand) {
boolean flag = brandService.save(brand);
return new Result(flag ? Code.SAVE_OK : Code.SAVE_ERR, flag);
}
public Result update( Brand brand) {
boolean flag = brandService.update(brand);
return new Result(flag ? Code.UPDATE_OK : Code.UPDATE_ERR, flag);
}
("/{id}")
public Result delete( int id) {
boolean flag = brandService.delete(id);
return new Result(flag ? Code.DELETE_OK : Code.DELETE_ERR, flag);
}
("/{id}")
public Result getById( int id) {
Brand brand = brandService.getById(id);
int code = brand != null ? Code.GET_OK : Code.GET_ERR;
String msg = brand != null ? " " : "数据查询失败,请重试";
return new Result(code, brand, msg);
}
public Result getAll() {
// int i = 1 / 0;
List<Brand> brandList = brandService.getAll();
int code = brandList != null ? Code.GET_OK : Code.GET_ERR;
String msg = brandList != null ? " " : "数据查询失败,请重试";
return new Result(code, brandList, msg);
}
}
异常码类,该类在当程序运行时输出相应的码,表示错误缘由
前后端交互:
异常编码:(创建一个异常编码类)
code
//异常代码
public class Code {
//测试成功返回编码
public static final int SAVE_OK = 20011;
public static final int DELETE_OK = 20021;
public static final int UPDATE_OK = 20031;
public static final int GET_OK = 20041;
//测试失败返回编码
public static final int SAVE_ERR = 20010;
public static final int DELETE_ERR = 20020;
public static final int UPDATE_ERR = 20030;
public static final int GET_ERR = 20040;
//开发过程异常码
public static final int SYSTEM_ERR = 50001;
public static final int BUSINESS_ERR = 50002;
public static final int TIME_OUT_ERR = 50003;
}
异常返回类,向前后端人员返回异常
ProjectExceptionAdvice
import com.exception.BusinessException;
import com.exception.SystemException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
//类注解,为rest风格开发的控制器类做增强
public class ProjectExceptionAdvice {
(BusinessException.class) //方法注解,拦截异常,也可以获得返回值
public Result BusinessException(BusinessException ex) {
//开发过程
//记录日志
//发送消息给运维
//发送邮件给开发人员
System.out.println("异常报错");
return new Result(ex.getCode(), null, ex.getMessage());
}
(SystemException.class) //方法注解,拦截异常,也可以获得返回值
public Result SystemException(SystemException ex) {
//开发过程
//记录日志
//发送消息给运维
//发送邮件给开发人员
System.out.println("异常报错");
return new Result(ex.getCode(), null, ex.getMessage());
}
(Exception.class) //方法注解,拦截异常,也可以获得返回值
public Result doException(Exception ex) {
System.out.println("异常报错");
return new Result(666, null, "异常报错");
}
}
交互码模块
Result
//该类为状态码交互类,表现层数据封装
public class Result {
private Object data;
private int code;
private String msg;
public Result() {
}
public Result(int code, Object data) {
this.data = data;
this.code = code;
}
public Result(int code, Object data, String msg) {
this.data = data;
this.code = code;
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
Dao层,主要就是封装一些数据库的增删改查操作
BrandDao
public interface BrandDao {
("insert into tb_brand(id,brand_name,company_name,ordered,description,status) values(#{id},#{brand_name},#{company_name},#{ordered},#{description},#{status})")
int save(Brand brand); //这里的void变成int作为判断,因为数据库变动会生成影响行数,int接收之后就可以作为判断后台插入语句是否有错误
("update tb_brand set brand_name=#{brand_name},company_name=#{company_name},ordered=#{ordered},description=#{description},status=#{status} where id=#{id}")
int update(Brand brand);
("delete from tb_brand where id=#{id}")
int delete(int id);
("select * from tb_brand where id=#{id}")
Brand getById(int id);
("select * from tb_brand")
List<Brand> getAll();
}
Domain层:与数据库中的表,一 一对应起来的JavaBean
Brand:
public class Brand {
private int id;
private String brand_name;
private String company_name;
private int ordered;
private String description;
private int status;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getBrand_name() {
return brand_name;
}
public void setBrand_name(String brand_name) {
this.brand_name = brand_name;
}
public String getCompany_name() {
return company_name;
}
public void setCompany_name(String company_name) {
this.company_name = company_name;
}
public int getOrdered() {
return ordered;
}
public void setOrdered(int ordered) {
this.ordered = ordered;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String toString() {
return "Brand{" +
"id=" + id +
", brand_name='" + brand_name + '\'' +
", company_name='" + company_name + '\'' +
", ordered=" + ordered +
", description='" + description + '\'' +
", status=" + status +
'}';
}
}
设置异常报错模块:
业务报错:
package com.exception;
//业务异常处理
public class BusinessException extends RuntimeException {
private final int code;
public int getCode() {
return code;
}
public BusinessException(int code, String message ) {
super(message);
this.code = code;
}
public BusinessException( int code,String message, Throwable cause) {
super(message, cause);
this.code = code;
}
}
系统报错
package com.exception;
//系统异常处理
public class SystemException extends RuntimeException {
private final int code;
public int getCode() {
return code;
}
public SystemException(int code, String message) {
super(message);
this.code = code;
}
public SystemException(int code, String message, Throwable cause) {
super(message, cause);
this.code = code;
}
}
Service层主要负责业务模块的逻辑。一般service层我们会先写一个interface,这个接口以service为后缀表示这是一个service接口,在这个类里定义好我们需要的方法,然后写实现类去实现这个接口里的方法,这样可以做到高度解耦合:
BrandService:
public interface BrandService {
boolean save(Brand brand); //保存
boolean update(Brand brand); //更新
boolean delete(int id); //删除
Brand getById(int id); //查询id
List<Brand> getAll(); //查询所有
}
BrandServiceImpl:
//表示改类为bean,表示业务层
public class BrandServiceImpl implements BrandService {
private BrandDao brandDao;
public boolean save(Brand brand) {
return brandDao.save(brand) > 0; //返回值变成数值表示数据库影响行级数是否大于0作为操作成功或者失败
}
public boolean update(Brand brand) {
return brandDao.update(brand) > 0;
}
public boolean delete(int id) {
return brandDao.delete(id) > 0;
}
public Brand getById(int id) {
if (id == 1) {
throw new BusinessException(Code.BUSINESS_ERR, "业务层异常");
}
// try {
// int i = 1 / 0;
// } catch (Exception e) {
// throw new SystemException(Code.SYSTEM_ERR, "系统异常", e); //抛出异常
// }
return brandDao.getById(id);
}
public List<Brand> getAll() {
return brandDao.getAll();
}
}
resource中的properties文件
jdbc.properties:(数据库连接信息)
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?allowPublicKeyRetrieval=true
jdbc.username=sa
jdbc.password=123456
log4j.properties:(加载日志信息)
log4j.rootLogger=debug,stdout,D,E
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss} %p %c\:%L - %m%n
log4j.appender.D=org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File=D://DataSpace/java_project/logs/log.log
log4j.appender.D.Append=true
log4j.appender.D.Threshold=DEBUG
log4j.appender.D.layout=org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss} %p %c\:%L - %m%n
log4j.appender.E=org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File=D://DataSpace/java_project/logs/log.log
log4j.appender.E.Append=true
log4j.appender.E.Threshold=ERROR
log4j.appender.E.layout=org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
前端模块,vue开发界面:
只展示相关开发:
//查询所有
getAll() {
//发送异步请求
axios.get("/brands/").then((res) => {
this.pagination.pageSize = res.data.data.size;
this.pagination.currentPage = res.data.data.current;
this.pagination.total = res.data.data.total;
console.log(res.data.data)
console.log(res.data.data.records)
this.filterTableData = res.data.data; //表示从数据库中读取的数据进行放入相关前端列表
console.log(this.filterTableData)
});
},
//删除
Delete(row) {
this.$confirm("此操作永久删除当前信息,是否继续?", "提示", {type: "info"}).then(() => {
axios.delete("/brands/" + row.id).then((res) => {
if (res.data.code=20021) {
this.$message.success("删除成功");
} else {
this.$message.error("数据同步失败,自动刷新");
}
}).finally(() => {
//2.重新加载数据
this.getAll();
});
}).catch(() => {
this.$message.info("取消操作");
});
},
//弹出添加窗口
handleCreate() {
this.dialogFormVisible = true;
this.resetForm() //表示当点击弹出框的时候表单清空
},
//重置表单
resetForm() {
this.form = {}; //使表单为空
},
//添加
add() {
axios.post("/brands", this.form).then((res) => {
console.log(res.data)
//在此完成对于添加失败或者成功的
if (res.data.code == 20011) {
this.dialogFormVisible = false;
this.$message.success("添加成功")
} else if (res.data.code == 20010) {
this.$message.error("添加失败")
}
}).finally(() => {
this.getAll()
})
},