汽车后端框架搭建(上)

1.背景

        用于记录公司的客户的租车还车记录。维护公司的客户信息,若客户想要租车,根据条件查询相关车辆信息,车辆信息,如果符合条件,出租信息。也需要记录,客户的还车信息。还车信息。

       但是,为了适用于不同的职位,不同的用户登录到系统中,展示的菜单也不相同。不同的用户,可以有不同的角色,不同的角色可以有不同的权限,而用户的权限,可以在系统中进行配置。

2.相关表

用户表

角色表

用户角色表

权限表

角色权限表

客户表

车辆表

租车单表

还车记录表

3.包的划分

        可能项目的表结构比较复杂,数据库比较庞大。开发人员相对较多。如果每个表都对应一个实体类,那么这个类放在一个包中,这个包比较臃肿。不便于开发和维护。基于这种考虑,将相关业务模块的表,使用前缀,这样相关业务的表会放在一起,同样的,相关业务的类,使用同一个包,例如:每个业务都有pojo,mapper,service,controler等等包,而使用一个包表示相关业务包裹这些包。sys.pojo,sys.mapper等等,使用包进行模块的划分。

4.搭建框架

 

|----com.zw

     |---bussi-->存放汽车租赁业务相关的类

     |---common--->系统公共类的包

     |---sys--->系统设置相关的包

     由于在开发中每个表,都要进行基本对CRUD操作,于是可以对整个系统的CRUD进行封装

     --->BaseMapper:对表的基本的增删查改操作.同理:可以对service进行封装

     --->BaseService:对基本的业务增删查改操作.

     将封装的BaseMapper和BaseService放在common包中,

4.1 common包

 1️⃣base包

   4.1.1 BaseMapp接口

       表的基础操作:增删查改 我们对来自不同的表进行CRUD的操作,添加操作还好说,没有返回值,但是查询返回的结果都不一样,所以需要指定两个泛型 F-->添加数据时,指定的类型 V-->查询返回的类型

package com.zw.common.base.mapper;


import com.zw.common.base.Query;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * 表的基础操作:增删查改
 * 我们对来自不同的表进行CRUD的操作,添加操作还好说,没有返回值,但是查询返回的结果都不一样,所以需要指定两个泛型
 * @param <F> 添加数据时,指定的类型
 * @param <V> 查询返回的类型
 */
public interface BaseMapper<F,V> {
    /**
     * 新增数据
     * @param f 添加数据时,指定的类型
     * @return
     */
    int insert(F f);

    /**
     * 根据id删除数据
     * @param id
     * @return
     */
    int delete(@Param("id")Integer id);

    /**
     * 根据id查询数据
     * @param id
     * @return
     */
    V selectOne(@Param("id")Integer id);

    /**
     *   因为列表查询需要传条件,但是在这里,我们并不知道传什么,所以我们在common包里指定
     *   一个类Query作为所有查询参数的基类,就是所有查询参数的父类,
     * @param query
     * @return
     */
    List<V> selectList(Query query);

    /**
     * 更新数据
     * @param f
     * @return
     */
    int update(F f);

}

以后所有的mapper类都继承这个BaseMapper类即可.

  4.1.2 IBaseService接口

       BaseService的增删查改相较于BaseMapper的增删查改比较特殊,对于添加操作,新增的时候,一样需要传入一个F,一样要在BaseService类上指定泛型,V不用指定,执行完某个具体的方法,我们将Result类型作为一个返回结果,Result作为所有业务操作的返回结果.

package com.zw.common.base.service;
import com.zw.common.base.Query;
import com.zw.common.Result;


/**
 * BaseService的增删查改相较于BaseMapper的增删查改比较特殊,
 * 对于添加操作,新增的时候,一样需要传入一个F,一样要在BaseService类上指定泛型,V不用指定,执行完某个具体的方法,
 * 我们将Result类型作为一个返回结果,Result作为所有业务操作的返回结果
 * @ClassName:BaseService
 * @Description: 所有业务的基类
 * @Author: KevinZeng
 * @Date 2020/1/8 下午 7:52
 */
public interface IBaseService<F> {

    /**
     * 新增数据
     * @param f
     * @return
     */
    Result add(F f);

    /**
     * 删除数据
     * @param id
     * @return
     */
    Result delete(Integer id);

    /**
     * 根据查询数据
     * @param id
     * @return
     */
    Result query(Integer id);

    /**
     * 分页查询数据
     * @param query
     * @return
     */
    Result queryPage(Query query);

    /**
     * 修改数据
     * @param f
     * @return
     */
    Result update(F f);

}

  4.1.3 BaseServiceImpl类

   实现IBaseService接口

package com.zw.common.base.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zw.common.Query;
import com.zw.common.Result;
import com.zw.common.base.PageInfo;
import com.zw.common.base.mapper.BaseMapper;
import com.zw.common.base.service.IBaseService;


public class BaseServiceImpl<F> implements IBaseService<F> {
    /**
     * BaseServiceImpl实现IBaseService接口后,service层必须有一个mapper
     */
    private BaseMapper baseMapper;

    /**
     * 通过构造方法传一个baseMapper进来
     * 即子类注入一个BaseMapper
     * @param baseMapper 传入的baseMapper
     */
    public BaseServiceImpl(BaseMapper baseMapper) {
        this.baseMapper = baseMapper;
    }

    @Override
    public Result add(F f) {
        baseMapper.insert(f);
        return new Result();
    }

    @Override
    public Result delete(Integer id) {
        baseMapper.delete(id);
        return new Result();
    }

    @Override
    public Result query(Integer id) {
        Object o = baseMapper.selectOne(id);
        Result rs = new Result(o);
        return  rs;
    }

    @Override
    public Result queryPage(Query query) {

        Page<Object> data = PageHelper.startPage(query.getPage(), query.getLimit());
        /**
         * Result rs = new Result(data);
         * 此时的rs不能直接返回,因为前端框架layui需要四个参数进行分页操作
         *   1.code
         *   2.msg
         *   3.data
         *   4.count
         * 我们需要封装出来一个Page准备这些参数
         */

        /**
         * com.github.pagehelper.Page类中的属性
         *     data.getPageNum() -->返回当前页码
         *     data.getPageSize()-->当前每页数据条数
         *     data.getTotal()  -->总条数
               data.getResult()-->需要进行分页的数据
         */
        PageInfo page = new PageInfo(data.getPageNum(),data.getPageSize(),data.getTotal(),data.getResult());
        Result rs = new Result(page);
        return rs;
    }

    @Override
    public Result update(F f) {
        baseMapper.update(f);
        return new Result();
    }
}

4.1.4 PageInfo

  为了兼容layui封装page类

package com.zw.common.base;

import java.util.List;

/**
 * @ClassName:PageInfo
 * @Description: TODO
 * @Author: KevinZeng
 * @Date 2020/1/8 下午 8:57
 */
public class PageInfo {
    /**
     * 当前页码
     */
    private Integer page;
    /**
     * 当前每页数据条数
     */
    private Integer limit;
    /**
     * 总数据条数
     */
    private long count;
    /**
     * 符合条件的数据(需要进行分页的数据)
     */
    private Object data;

    public PageInfo() {
    }

    public PageInfo(Integer page, Integer limit, long count, Object data) {
        this.page = page;
        this.limit = limit;
        this.count = count;
        this.data = data;
    }

    public Integer getPage() {
        return page;
    }

    public void setPage(Integer page) {
        this.page = page;
    }

    public Integer getLimit() {
        return limit;
    }

    public void setLimit(Integer limit) {
        this.limit = limit;
    }

    public long getCount() {
        return count;
    }

    public void setCount(long count) {
        this.count = count;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

4.1.5 Query

所有查询参数的基类

        因为列表查询需要传条件,但是首先在BaseMapper里,我们并不知道传什么,所以我们在common包里指定 一个类Query作为所有查询参数的基类,就是所有查询参数的父类

package com.zw.common;

/**
 * @ClassName:Query
 * @Description: 所有查询参数的基类
 * @Author: KevinZeng
 * @Date 2020/1/8 下午 7:48
 */
public class Query {
    /**
     * 页码默认第一页
     */
    private Integer page = 1;
    /**
     * 每页的数据条数默认10
     */
    private Integer limit = 10;

    public Query(Integer page, Integer limit) {
        this.page = page;
        this.limit = limit;
    }

    public Integer getPage() {
        return page;
    }

    public void setPage(Integer page) {
        this.page = page;
    }

    public Integer getLimit() {
        return limit;
    }

    public void setLimit(Integer limit) {
        this.limit = limit;
    }
}

 

2️⃣Result类

   业务操作CRUD方法将Result类型作为一个返回结果,Result作为所有业务操作的返回结果

package com.zw.common;

/**
 * @ClassName:Result
 * @Description: 所有业务操作的(执行)返回结果
 * @Author: KevinZeng
 * @Date 2020/1/8 下午 7:57
 */
public class Result {
    /**
     * 业务编码
     */
    private Integer code;

    /**
     * 业务信息
     */
    private  String msg;
    /**
     * 业务数据
      */
    private  Object data;
    /**
     * 正常没有数据的Result
     */
    public Result(){
        this.code = CodeMsg.SUCCESS.CODE;
        this.msg = CodeMsg.SUCCESS.MSG;
    }

    /**
     * 不正常无数据的Result
     * @param codeMsg 业务信息(包括业务编码和业务消息)
     */
    public Result(CodeMsg codeMsg) {
        this.code = codeMsg.SUCCESS.CODE;
        this.msg = codeMsg.SUCCESS.MSG;
    }

    /**
     * 正常带数据的Result
     */
    public Result(Object data) {
        //调用无参构造
        this();
        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;
    }
}

3️⃣CodeMsg类

package com.zw.common;

/**
 * 所有信息枚举
 */
public enum CodeMsg {

    SUCCESS(200,"成功"),
    ERROR(110,"程序员进ICU了...");

    /**
     * 业务码
     */
    Integer CODE;

    /**
     * 业务消息
     */
    String MSG;

    CodeMsg(Integer code, String msg) {
        this.CODE = code;
        this.MSG = msg;
    }
}

4️⃣exception包

①BussiException

        当程序出现数据异常时就抛出异常信息 有一下两种情况: 1.当数据校验不通过时,抛出异常信息 2.当数据操作出现异常时,抛出异常信息,也是为了数据回滚

package com.zw.common.exception;

/**
 * 当程序出现数据异常时就抛出异常信息
 * 两种情况:
 * 1.当数据校验不通过时,抛出异常信息
 * 2.当数据操作出现异常时,抛出异常信息,也是为了数据回滚
 */

/**
 * @ClassName:BussiException
 * @Description: 自定义业务异常类:
 * @Author: KevinZeng
 * @Date 2020/1/8 下午 9:39
 */
public class BussiException extends RuntimeException{
    /**
     * 异常编码
     */
    private  Integer code;
    /**
     * 异常信息
     */
    private String msg;

    public BussiException() {
    }
    public BussiException(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    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;
    }
}

5️⃣interceptor包

①LoginInterceptor

登录拦截器类,后续更

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值