crud最长用

1.删除操作,用了rest风格的请求,还有post请求的三种方式   
   delHouse(id){ this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { //1.rest风格的delete删除请求 /* this.$http.delete('/house/' + id).then(resp=>{ console.log('resp.data',resp.date) this.$message({ type: 'success', message: '删除成功!' }); }).catch(e=>{ console.log(e) }) */ //2.1.Post请求==>Content-Type:application/x-www-form-urlencoded;charset=UTF-8 /* const param = new URLSearchParams(); param.append('id',id) this.$http.post('/house/del',param).then(resp=>{ console.log(resp.data) this.$message({type: 'success',message: '删除成功!'}); }).catch(e=>{ console.log(e) }) */ //2.2post请求发送==>Content-Type: application/x-www-form-urlencoded;charset=UTF-8 /* let param = {id:id} this.$http.post('/house/del',querystring.stringify(param)).then(resp=>{ this.$message({type: 'success',message: '删除成功!'}); }).catch(e =>{ console.log(e) }) */ //2.3.(引入qs库,) //post请求发送==>Content-Type: application/x-www-form-urlencoded;charset=UTF-8 let param = {id:id} this.$http.post('/house/del',qs.stringify(param)).then(resp=>{ if(resp.data.code === 200){ this.queryHouseList() this.$message.success('删除成功!'); }else{ this.$message.error(resp.data.msg) } }).catch(e=>{ console.log(e) }) }).catch(() => { this.$message({ type: 'info', message: '已取消删除' }); }); },
     
  2.编辑(修改)操作==>弹出一个模态框,先清空模态框,再进行赋值,
(模态框可以先处理好里面得东西,然后再让他弹出,那样就不会有时间差)
  
//提交修改 submitEdit(){ this.$http.put('/house',this.editForm).then(resp =>{ if(resp.data.code === 200){ this.$message.success('修改成功') this.editFormVisible = false this.queryHouseList() } }).catch(e=>{ console.log(e) }) }, //编辑 editHouse(house){ this.editForm ={ province: '', city: '', area: '', rentMode: '', houseType: '', direction: '', address: '', rent: '', } console.log('house',house) this.$http.get('/area/' + house.province).then(resp=>{ console.log('resp',resp) if(resp.data.code ===200){ this.editArea.cityList = resp.data.data this.$http.get('/area/' + house.city).then(resp=>{ if(resp.data.code ===200){ this.editArea.areaList = resp.data.data //this.editForm = house==>这种直接赋值会出现问题 //在表单里一修改,页面就会随之修改,数据库没变化 //(与java中的引用船只类似) this.editForm.id = house.id this.editForm.province = house.province this.editForm.city = house.city this.editForm.area = house.area this.editForm.rentMode = house.rentMode this.editForm.houseType = house.houseType this.editForm.direction = house.direction this.editForm.address = house.address this.editForm.rent = house.rent this.editFormVisible = true } }).catch(e=>{ console.log(e) }) } }).catch(e=>{ console.log(e) }) },
      
  3.在后台把数据库的字段查出来给前端页面进行赋值,
这样做比写死好用多了,在此代码中调用一个方法,查出了三个字段

   //查询字典列表(租赁方式,户型,朝向) queryDict(groupId){ // let url = '/dict?groupId=' + groupId if(groupId){ this.$http.get('dict',{ params:{ groupId:groupId } }).then(res=>{ if(res.data.code === 200){ let result = res.data.data if(groupId ==='rent_mode'){ this.dict.rentModeList = result }else if(groupId==='house_type'){ this.dict.houseTypeList = result }else{ this.dict.directionList = result } } }).catch(e=>{ console.log(e) }) } },

-------------------------------------------------------------------
  //初始化   created() {         this.queryHouseList()         this.queryProvinceList()         this.queryDict('rent_mode')         this.queryDict('house_type')         this.queryDict('direction')     },
-----------------------------------------------------------------
//sql语句
<select id="queryList" parameterType="String" resultType="Dict">
select id,name,value from t_dict where group_id = #{value} order by sort
</select>
------------------------以下是前端页面-------------------------
crud最长用

 


 

 
    
 4.省市区级联查询
        <!-- 横向排列省市区 -->             <el-row :gutter="10">                 <el-col :span="8">                    <el-form-item label="所在省" prop="province">                         <el-select v-model="queryForm.province" @change="queryCityList">                             <el-option label="请选择" value=""></el-option>                             <el-option v-for="area in area.provinceList" :key="area.name"                             :label="area.name" :value="area.id"></el-option>                         </el-select>                        </el-form-item>                  </el-col>                 <el-col :span="8">                     <el-form-item label="所在市" prop="city">                         <el-select v-model="queryForm.city" @change="queryAreaList">                             <el-option label="请选择" value=""></el-option>                             <el-option v-for="city in area.cityList" :key="city.name"                             :label="city.name" :value="city.id"></el-option>                         </el-select>                     </el-form-item>                 </el-col>                 <el-col :span="8">                     <el-form-item label="所在区" prop="area">                         <el-select v-model="queryForm.area" >                             <el-option label="请选择" value=""></el-option>                             <el-option v-for="area in area.areaList" :key="area.name"                             :label="area.name" :value="area.id"></el-option>                         </el-select>                     </el-form-item>                 </el-col>             </el-row>

-----------------------------------------------------------------------------------------------------------------------------

    //查区 queryAreaList(cityId){ this.area.areaList = [] this.queryForm.area = '' this.$http.get('/area/' + cityId).then(resp=>{ if(resp.data.code===200){ this.area.areaList = resp.data.data } }).catch(e=>{ console.log(e) }) }, //查市 queryCityList(provinceId){ this.area.areaList = [] this.area.cityList = [] this.queryForm.area = '' this.queryForm.city = '' this.$http.get('/area/' + provinceId).then(resp=>{ if(resp.data.code===200){ this.area.cityList = resp.data.data } }).catch(e=>{ console.log(e) }) }, //查省 queryProvinceList(){ this.$http.get('/area/-1').then(resp=>{ if(resp.data.code===200){ this.area.provinceList = resp.data.data } }).catch(e=>{ console.log(e) }) },
5.分页
<el-pagination style="margin-top:30px" background :current-page="pageNum" :page-size="pageSize" :page-sizes="[1, 2, 5, 10, 15, 20]" layout="total,sizes,prev, pager, next,jumper" :total="total" @size-change="pageSizeChange" @current-change="pageNumChange"> </el-pagination>
------------------------------------------------------------
 /* 分页 */         pageSizeChange(pageSize){             this.pageSize = pageSize             this.queryHouseList()         },         pageNumChange(pageNum){             this.pageNum = pageNum             this.queryHouseList()         },         //点击查询,第一页         clickQuery(){             this.pageNum = 1             this.queryHouseList()         },
6.登录界面(8是6的登录后台)
重置表单用的是ref,在做的时候一直报validate未定义,
结果是this.$refs.loginFormRef.validate中的loginFormRef中的首字母l写成了大写

<template> <el-form ref="loginFormRef" :rules="loginFormRules" :model="loginForm"> <el-form-item label="用户名" prop="name" > <el-input v-model="loginForm.name" placeholder="用户名"></el-input> </el-form-item> <el-form-item label="密码" prop="password"> <el-input type="password" v-model="loginForm.password" placeholder="密码"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="login">登录</el-button> <el-button @click="resetLoginForm">重置</el-button> </el-form-item> </el-form> </template> <script> export default { data() { return { loginForm:{ name:'', password:'', }, loginFormRules:{ name:[ {required: true, message: '请填写正确的用户名', trigger: 'blur'}, ], password:[ {required: true, message: '请填写正确的用户密码', trigger: 'blur'}, ], } } }, methods: { login(){
        任一表单项被校验后触发 被校验的表单项 prop 值,校验是否通过, this.$refs.loginFormRef.validate(valid =>{ if(valid){ let param = new URLSearchParams(); param.append("name",this.loginForm.name) param.append("password",this.loginForm.password) this.$http.post('/user/login',param).then(resp=>{ if(resp.data.code === 200){ this.$router.push("/") window.sessionStorage.setItem('token',resp.data.data) } else { this.$message.error(resp.data.msg); } }) }else{ console.log('error submit!!') return false; } }) }, resetLoginForm(){ this.$refs.loginFormRef.resetFields() } }, created() { }, } </script> <style scoped> </style>
7.重置表单
7.1
resetLoginForm(){ this.$refs.loginFormRef.resetFields() }
7.2 resetForm(formName){ this.$refs[formName].resetFields(); },
7.3

this.$nextTick(() => {
        this.$refs[formName].resetFields();
       });
 
8.登录后台

@RestController @RequestMapping("/user") @Slf4j public class UserController { @Autowired UserService userService; @PostMapping("/login") public Result login(@RequestParam String name, @RequestParam String password){ User user = userService.getUser(name); //1.判断用户 if(ObjectUtils.isEmpty(user)){ log.warn("用户名错误"); return Result.failed("用户名或密码错误"); } //2.验证密码 password = DigestUtils.md5Hex(password); if(!StringUtils.equals(user.getPassword(),password)){ return Result.failed("用户名或密码错误"); } //3.创建token AccessToken accessToken = new AccessToken(name); String jsonToken = JSONObject.toJSONString(accessToken); //4.加密 String token = EncrypUtil.encrypt(jsonToken); //5.返回前端 return Result.success(token); } }
----------------------------AccessToken 类--------------------------------
package com.etoak.common;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

@Data
public class AccessToken {
//用户名
private String username;
//过期时间
private Long expire;

public AccessToken(String username){
this.username =username;
//暂时默认两分钟
this.expire = System.currentTimeMillis() + 1000*60*2;
}
}
------------------------依赖-------------
<!-- 格式对象转换 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.70</version>
</dependency>

<!-- 加解密工具包 -->
<dependency>
<groupId>org.jasypt</groupId>
<artifactId>jasypt</artifactId>
<version>1.9.2</version>
</dependency>
</dependencies>

-----------------------------mapper接口--------------------------------
crud最长用

 

 

 
9.跨域
9.1先过滤拦截所有请求,处理跨域问题,
@Configuration public class FilterConfig { /** * Spring Boot注册过滤器 * 自定义Filter需要两个步骤:(跨域实现了Filter) * 实现Filter【javax.servlet.Filter】接口,实现Filter方法 * 添加 @Configuration 注解,将自定义Filter加入过滤链 * @return */ //之前做springmvc是在web.xml文件中配置,而现在是springboot工程,没有web.xml文件,所以需要自己写一个类配置Bean @Bean public FilterRegistrationBean<CrossDomainFilter> crossDomainFilter(){ FilterRegistrationBean<CrossDomainFilter> regBean = new FilterRegistrationBean<>(); // <filter-class> regBean.setFilter(new CrossDomainFilter());//注册了写着跨域的类 // <url-pattern> regBean.addUrlPatterns("/*");//拦截所有请求,进入CrossDomainFilter先进行跨域 regBean.setOrder(1);//优先级最高 return regBean; } }
-----------------------------9.2跨域设置------------------------------------
@Slf4j
public class CrossDomainFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("初始化跨域过滤器");
}
@Override
public void doFilter(ServletRequest req,
ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) response;

// 允许所有的请求域名访问我们的跨域资源,可以固定单个或者多个内容
httpResponse.setHeader("Access-Control-Allow-Origin", "*");//
// httpResponse.setHeader("Access-Control-Allow-Origin", "http://localhost:9090");// 允许所有的请求域名访问我们的跨域资源,可以固定单个或者多个内容
httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE,PUT");// 允许何种请求方法访问该跨域资源服务器
httpResponse.setHeader("Access-Control-Max-Age", "3600");// 预检请求的有效期,单位为秒。有效期内,不会重复发送预检请求
httpResponse.addHeader("Access-Control-Allow-Headers",
"Accept,authorization,Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With");// 允许所有的请求header访问,可以自定义设置任意请求头信息 后期加上 authorization
httpResponse.setHeader("Access-Control-Allow-Credentials", "true");// 是否允许用户发送、处理cookie
//如果额外设置自己的头需要在这定义
httpResponse.setHeader("Access-Control-Expose-Headers", "Access-Token");
chain.doFilter(req, httpResponse);
}

@Override
public void destroy() {

}
}
 
10.application.yml文件

server: port: 8000 servlet: context-path: /house-app spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver ##时区问题 url: jdbc:mysql://127.0.0.1:3306/et2006?serverTimezone=UTC username: root password: etoak servlet: multipart: max-file-size: 2MB mybatis: ##给包下边的类起别名 type-aliases-package: com.etoak.bean mapper-locations: classpath:mappers/*.xml pagehelper: ##分页合理化 reasonable: true ##给包下执行的代码添加日志级别debug logging: level: com.etoak.mapper: debug ##图片上传路径 upload: dir: d:/upload
11.全局异常处理(controller)
(
@RestControllerAdvice //@ControllerAdvice + @ResponseBody==>
通过对异常的拦截,统一返回对异常的处理
)
---------------以下是springmvc的异常处理------------------------------- @Slf4j //当controller层抛出异常就会被这个注解拦截 @ControllerAdvice public class GlobalExceptionHandler { //表示拦截RuntimeException异常,Runtime异常下的子异常也会被拦截 @ExceptionHandler(RuntimeException.class) public ModelAndView handle(RuntimeException e) { log.error(e.getMessage(),e); //System.out.println("异常-->" + e); ModelAndView mv = new ModelAndView(); mv.setViewName("student/upload"); mv.addObject("error",e.getMessage()); return mv; } //添加对RunimeException的子异常处理方法 @ExceptionHandler(StudentParamException.class) public ModelAndView handle(StudentParamException e) { System.out.println("StudentParamException异常-->" + e); ModelAndView mv = new ModelAndView(); mv.setViewName("student/upload"); mv.addObject("error",e.getMessage()); return mv; } @ExceptionHandler(UserLoginException.class) public ModelAndView handle(UserLoginException e) { log.error(e.getMessage() , e); ModelAndView mv = new ModelAndView(); mv.setViewName("login"); mv.addObject("error",e.getMessage()); return mv; } }
------------------------------------以下是springboot做的异常处理------------------------------------------
package com.etoak.common;


import com.etoak.exception.HouseException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice //@ControllerAdvice + @ResponseBody==>
// 通过对异常的拦截,统一返回对异常的处理
@Slf4j
public class GlbalExceptionHandler {
@ExceptionHandler(HouseException.class)
public Result handle(HouseException e){
log.error(e.getMessage(),e);
return Result.failed(e.getMessage());
}
}
 
12.文件上传
/** 读取默认配置文件的参数 */ @Value("${upload.dir}") private String destDir; //文件上传 @PostMapping("/upload") public Result<String> upload(MultipartFile file) throws Exception{ //获得源文件名称和后缀 String originalFilename = file.getOriginalFilename(); String suffix = FilenameUtils.getExtension(originalFilename); //创建新的文件名称 String uuid = UUID.randomUUID().toString().replaceAll("-",""); String filename = String.format("%s%s%s",//占位符(占了三个参数),拼接三个参数 uuid,".",suffix); //创建目标文件夹 File destDirectory = new File(destDir); if(!destDirectory.exists()){ destDirectory.mkdirs(); } //创建目标文件.并上传 File destFile = new File(destDirectory,filename); file.transferTo(destFile); String pic = "/pic/" + filename;//是为了之后拿图片的时候有个路径 log.info("pic path-{}" , pic); return Result.success(pic); }
13.密码加密
package com.etoak.util; //加密工具 import org.jasypt.encryption.pbe.StandardPBEStringEncryptor; import org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig; public class EncrypUtil { private static final StandardPBEStringEncryptor encryptor; static { encryptor = new StandardPBEStringEncryptor(); EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig(); config.setAlgorithm("PBEWithMD5AndDES");//加密算法 config.setPassword("et2006_+-");//密码加盐 encryptor.setConfig(config); } /*加密方法*/ public static String encrypt(String text){ return encryptor.encrypt(text); } /*解密方法*/ public static String decrypt(String password){ return encryptor.decrypt(password); } public static void main(String[] args) { String encrypt = encryptor.encrypt("18902161379"); System.out.println(encrypt); String en = "9LzaT5W0ucfqgquKhkknYXRGLaqPVxZ4FNXjNJ7eXYrH/BFfnMDCTqdMUNV8yC0aXJNM70Gm9MU="; System.out.println(encryptor.decrypt(en)); } }
14.后台校验
---------------------serviceImpl层--------------------
@Override public void addHouse( House house) { //校验house ValidationUtil.validate(house); //先校验house,然后再给他赋值,要不会报空 // (用的是postman,传的空对象,所以house.getArea()得到的就是空) house.setAreaName(houseMapper.queryAreaName(house.getArea()).getName()); houseMapper.addHouse(house); }


-----------------------ValidationUtil类-------------------------

//后台校验工具类**自己写的类

public class ValidationUtil {
private static final Validator validator;

static{
ValidatorFactory factory =
Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
}
public static void validate(Object object){
Set<ConstraintViolation<Object>> constraints = validator.validate(object);
//如果为空,表示校验失败
if(CollectionUtils.isNotEmpty(constraints)){
StringBuffer message = new StringBuffer();
constraints.forEach(x->{
String msg = x.getMessage();
message.append(msg).append(";");
});
throw new HouseException(message.toString());
}
}
}
 

15mapper的sql语句
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.etoak.mapper.HouseMapper"> <cache flushInterval="1800000"></cache> <select id="queryList" parameterType="com.etoak.common.HouseRequestVo" resultType="HouseVo"> select t.id,t.province,t.city,t.area,t.area_name as areaName,t.rent_mode as rentMode, t2.name as rentModeName,t.house_type as houseType,t3.name as houseTypeName,t.direction, t4.name as directionName,t.rent,t.address,t.pic,t.create_time as createTime from t_house t left join t_dict t2 on t.rent_mode = t2.value and t2.group_id = 'rent_mode' left join t_dict t3 on t.house_type = t3.value and t3.group_id = 'house_type' left join t_dict t4 on t.direction = t4.value and t4.group_id = 'direction' <where> <if test="province !=null and province != 0"> and t.province = #{province} </if> <if test="city != null and city != 0"> and t.city = #{city} </if> <if test="area !=null and area != 0"> and t.area = #{area} </if> <if test="rentMode != null and rentMode != ''"> and t.rent_mode = #{rentMode} </if> <if test="rentMapList != null and rentMapList.size() != 0"> and <foreach collection="rentMapList" item="rentMap" open="(" close=")" separator="or"> t.rent between #{rentMap.start} and #{rentMap.end} </foreach> </if> <if test="directionList != null and directionList.size() != 0"> and t.direction in <foreach collection="directionList" item="direction" open="(" close=")" separator=","> #{direction} </foreach> </if> <if test="houseTypeList != null and houseTypeList.size() != 0"> and t.house_type in <foreach collection="houseTypeList" item="houseType" open="(" close=")" separator=","> #{houseType} </foreach> </if> </where> order by t.create_time desc </select> <select id="queryAreaName" parameterType="int" resultType="Area"> select * from t_area where id = #{value} </select> <insert id="addHouse" parameterType="House"> insert into t_house(province,city,area,area_name,rent_mode,house_type,direction,rent,address,pic,create_time) values (#{province},#{city},#{area},#{areaName},#{rentMode},#{houseType},#{direction},#{rent},#{address},#{pic},now()) </insert> <update id="updateHouse" parameterType="House" > update t_house <set> <if test="rent != null and rent != 0"> rent = #{rent}, </if> <if test="rentMode != null and rentMode != ''"> rent_mode = #{rentMode}, </if> <if test="houseType != null and houseType !=''"> house_type = #{houseType}, </if> <if test="direction != null and direction != ''"> direction = #{direction}, </if> <if test="address != null and address != ''"> address = #{address}, </if> create_time = now() </set> where id = #{id} </update> <delete id="deleteHouse" parameterType="int"> delete from t_house where id = #{value} </delete> </mapper>

 

上一篇:Jetty权威指南&Jetty6指南书&Jetty源码分析&jetty手册


下一篇:Logback第十章:JMX 配置器