spring boot项目实战之公共代码抽取

在一个web项目内,会有很多重复性的代码,如果将共性代码进行提取并规范使用,对后续运维和开发是很有帮助的。下面我们来看一下在一个web项目内有那些部分会出现诸多重复性的代码:
1. model内:id、标记删除、创建时间、创建人、修改时间、修改人等字段
2. service内:根据id查询、新增&修改、删除、分页查询等方法
3. dao内: 根据id查询、新增&修改、删除、分页查询等方法

model

根据当前公司的情况,对model进行了以下抽象:
1. BaseModel 接口,仅包含getId一个方法
2. AbstractBaseModel 抽象类,继承BaseModel接口,提取了创建人、创建时间、修改人、修改时间字段
3. MarkDeleteableModel 抽象类,继承AbstractBaseModel,增加了标记删除标记字段

代码如下:

public interface BaseModel<ID extends Serializable> extends Serializable{
    ID getId();
}

/**
 * 提取了部分公共字段,可以避免多个实体重复设置这些属性
 */
@MappedSuperclass
public abstract class AbstractBaseModel<ID extends Serializable> implements BaseModel<ID>{

    private static final long serialVersionUID = 1195969732659409799L;

    @ApiModelProperty(value="创建者ID")
    @Column(columnDefinition="int default 0")
    private int creator = 0;

    @ApiModelProperty(value="创建时间")
    @Column(name="create_time")
    private Timestamp createTime;

    @ApiModelProperty(value="最后修改人")
    @Column(columnDefinition="int default 0")
    private int updator = 0;

    @ApiModelProperty(value="最后修改时间")
    @Column(name="update_time")
    private Timestamp updateTime;

    //省略get set
}

/**
 * 需要标记删除的实体继承该类
 */
@MappedSuperclass
public abstract class MarkDeleteableModel<ID extends Serializable> extends AbstractBaseModel<ID>{

    private static final long serialVersionUID = -1880548221110317053L;

    @ApiModelProperty(value="标记删除字段 0未删除 1已删除 ")
    @Column(name = "del", columnDefinition = "tinyint default 0")
    private int del = Constants.DEL_NO;

    //省略get set
}

@MappedSuperclass用于说明该类不是某个实体,不和数据库的表相对应。

所有的实体皆继承以上三个类中的一个,数据需要标记删除的继承MarkDeleteableModel(如用户)、需要创建时间、修改时间的继承AbstractBaseModel(如角色),其它的实现BaseModel接口(如用户角色关系)

dao

公司项目使用的是spring boot + JPA,所以DAO层的公共操作已经在spring-data-jpa内进行了完善的抽象,如CrudRepository、PagingAndSortingRepository、JpaRepository、JpaSpecificationExecutor等接口,我们自己的DAO只需要根据需要进行继承就可以使用对应的查询方法。

但这里存在一个问题,当我抽取service层代码时肯定需要设置对应的dao,那就希望dao层能有一个统一的接口,如UserDao继承PagingAndSortingRepository和JpaRepository,UserRoleDao继承CrudRepository,虽然满足了对应实体的操作需要,但对service层代码的提取需求冲突,所以为了所有的DAO拥有相同的接口,因此我们可以提供一个公共DAO,满足绝大部分实体所需要的查询操作。

@NoRepositoryBean
public interface BaseDao<T,ID extends Serializable> extends JpaSpecificationExecutor<T>,JpaRepository<T, ID>{

}
  • JpaRepository满足基本的增删改查、分页等需求
  • JpaSpecificationExecutor满足多可选条件查询需求

service

service层主要提取通用的新增、修改、常用查询方法,这样在创建一个实体的service后,不需要在每个service的接口内都创建一遍这些同样的方法,就可以直接调用其上层方法进行操作。

public interface BaseService<T extends BaseModel<ID>, ID extends Serializable> {

 
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值