开发商建设审批网站,如何在百度中搜索到网站,企业服务云平台,凡科app目录
持久层
mp
模仿#xff1a;
1.抽取出通用的接口类
2.创建自定义的repository接口
服务层 mp
模仿#xff1a;
1.抽取出一个IService通用服务类
2.创建ServiceImpl类实现IService接口
3.自定义的服务接口
4.创建自定义的服务类
工厂模式
为什么可以使用工厂…目录
持久层
mp
模仿
1.抽取出通用的接口类
2.创建自定义的repository接口
服务层 mp
模仿
1.抽取出一个IService通用服务类
2.创建ServiceImpl类实现IService接口
3.自定义的服务接口
4.创建自定义的服务类
工厂模式
为什么可以使用工厂模式
如何使用工厂模式
枚举类
工厂类
第一种方式使用switch方式来判断要返回哪一种服务类型
第二种通过反射来判断
使用工厂模式 这里我来分享以下参考mybatis-plus的格式来封装neo4j的持久层和设计出一个服务层
持久层
mp
这里我们先看以下mp持久层的是如何操作的 可以发现mp抽取出了一个通用的BaseMapper接口并使用泛型T代指对实体类对象的统一操作 public interface BaseMapperT extends MapperT {int insert(T entity);int deleteById(Serializable id);int deleteById(T entity);
...
}
然后我们就可以创建一个mapper类并继承自BaseMapper接口然后泛型指定为PayChannelEntity实体类这个实体类就是使用TableName注解与数据表一一对应的实体类
Mapper
public interface PayChannelMapper extends BaseMapperPayChannelEntity {}总结mp通过抽取出一个BaseMapper通用的接口然后让我们自己创建的mapper类去继承BaseMapper并指定要操作的实体类这样一来大多数的CURD操作我们就不用自己实现并且我们自己创建的mapper类使用Mapper注解这个注解可以让Spring扫描并为其创建一个代理对象。
模仿
1.抽取出通用的接口类 这个类继承Neo4jRepository接口这个接口有neo4j提供的大多数CURD方法 并且也使用泛型并且规定这个T泛型必须继承自BaseEntity类还有另一个泛型ID,表示id属性的类型 这里使用NoRepositoryBean注解的作用是不用给这个通用接口类生成bean因为继承Neo4jRepository接口的接口都会被扫描生成代理对象这里没必要生成mp是使用了Mapper注解才会生成代理对象 /*** Repository基本方法的实现**/
NoRepositoryBean//让这个类不生成bean
public interface BaseRepositoryT extends BaseEntity, ID extends Neo4jRepositoryT, ID {/*** 根据业务id查询节点数据** param bid 业务id* return 节点数据*/OptionalT findByBid(Long bid);/*** 根据业务id删除节点数据** param bid 业务id* return 删除的数据数量*/Long deleteByBid(Long bid);
}2.创建自定义的repository接口 这里指定泛型为AgencyEntity类和id属性为Long类 AgencyEntity类是与neo4j中AGENCY标签一一对应的实体类 通过实现getAgencyType()抽象方法来区别不同的机构实体类 /*** 网点数据操作*/
public interface AgencyRepository extends BaseRepositoryAgencyEntity, Long {}Node(AGENCY)
Data
ToString(callSuper true)
SuperBuilder(toBuilder true)
NoArgsConstructor
public class AgencyEntity extends BaseEntity {Overridepublic OrganTypeEnum getAgencyType() {return OrganTypeEnum.AGENCY;}
}Data
SuperBuilder(toBuilder true)
NoArgsConstructor
AllArgsConstructor
public abstract class BaseEntity {IdGeneratedValueApiModelProperty(value Neo4j ID, hidden true)private Long id;ApiModelProperty(value 父节点id, required true)private Long parentId;ApiModelProperty(value 业务id, required true)private Long bid;ApiModelProperty(value 名称, required true)private String name;ApiModelProperty(value 负责人, required true)private String managerName;ApiModelProperty(value 电话, required true)private String phone;ApiModelProperty(value 地址, required true)private String address;ApiModelProperty(value 位置坐标, x: 纬度y: 经度, required true)private Point location;ApiModelProperty(value 是否可用, required true)private Boolean status;ApiModelProperty(value 扩展字段以json格式存储)private String extra;//机构类型public abstract OrganTypeEnum getAgencyType();}
还有另外两个持久层接口类 服务层 mp
这里看一下mp的服务层实现 可以发现mp的服务层也抽取出了一个通用的服务接口类也使用了泛型T来代指操作的实体类 public interface IServiceT {int DEFAULT_BATCH_SIZE 1000;default boolean save(T entity) {return SqlHelper.retBool(this.getBaseMapper().insert(entity));}Transactional(rollbackFor {Exception.class})default boolean saveBatch(CollectionT entityList) {return this.saveBatch(entityList, 1000);}boolean saveBatch(CollectionT entityList, int batchSize);
BaseMapperT getBaseMapper();ClassT getEntityClass();
...
}
这个接口类是没有实现的如果我们要自己创建一个服务类去实现这个接口是十分麻烦的所以mp提供了一个ServiceImpl类对这个接口进行了实现 这个实现类使用了一个泛型M代指继承了BaseMapper接口的类还有泛型T代指实体类 这样一来就可以使用M来实现IService接口的所有方法操作了。 public class ServiceImplM extends BaseMapperT, T implements IServiceT {protected Log log LogFactory.getLog(this.getClass());Autowiredprotected M baseMapper;protected ClassT entityClass this.currentModelClass();protected ClassM mapperClass this.currentMapperClass();public ServiceImpl() {}public M getBaseMapper() {return this.baseMapper;}public ClassT getEntityClass() {return this.entityClass;}/** deprecated */Deprecatedprotected boolean retBool(Integer result) {return SqlHelper.retBool(result);}protected ClassM currentMapperClass() {return ReflectionKit.getSuperClassGenericType(this.getClass(), ServiceImpl.class, 0);}
...
}
自定义的服务接口类用来拓展自己特有的方法
public interface PayChannelService extends IServicePayChannelEntity {}
自定义的服务类把对应的mapper接口类型和需要操作的实体类作为泛型传入
Service
public class PayChannelServiceImpl extends ServiceImplPayChannelMapper, PayChannelEntity implements PayChannelService {
}
模仿
1.抽取出一个IService通用服务类
使用泛型T代指需要操作的实体类
public interface IServiceT extends BaseEntity {/*** 根据业务id查询数据** param bid 业务id* return 节点数据*/T queryByBid(Long bid);/*** 新增节点** param t 节点数据* return 新增的节点数据*/T create(T t);/*** 更新节点** param t 节点数据* return 更新的节点数据*/T update(T t);/*** 根据业务id删除数据** param bid 业务id* return 是否删除成功*/Boolean deleteByBid(Long bid);}2.创建ServiceImpl类实现IService接口 这里使用R泛型代指repostory接口类这样一来就可以使用R类型的repostory接口来对方法进行实现。 /*** 基础服务的实现*/
public class ServiceImplR extends BaseRepository, T extends BaseEntity implements IServiceT {Autowiredprivate R repository;Overridepublic T queryByBid(Long bid) {return (T) this.repository.findByBid(bid).orElse(null);}Overridepublic T create(T t) {t.setId(null);//id由neo4j自动生成return (T) this.repository.save(t);}Overridepublic T update(T t) {//先查询再更新T tData this.queryByBid(t.getBid());if (ObjectUtil.isEmpty(tData)) {return null;}BeanUtil.copyProperties(t, tData, CopyOptions.create().ignoreNullValue().setIgnoreProperties(id, bid));return (T) this.repository.save(tData);}Overridepublic Boolean deleteByBid(Long bid) {return this.repository.deleteByBid(bid) 0;}
}
3.自定义的服务接口
public interface AgencyService extends IServiceAgencyEntity {}public interface OLTService extends IServiceOLTEntity {}
public interface TLTService extends IServiceTLTEntity {}
4.创建自定义的服务类 创建实现类并把这个类都交给spring管理 Service
public class AgencyServiceImpl extends ServiceImplAgencyRepository, AgencyEntity implements AgencyService {
}Service
public class TLTServiceImpl extends ServiceImplTLTRepository, TLTEntityimplements TLTService {
}Service
public class OLTServiceImpl extends ServiceImplOLTRepository, OLTEntityimplements OLTService {
}
工厂模式
我们可以使用工厂模式来动态的生成不同的服务实现类供我们使用
为什么可以使用工厂模式
因为所有的服务类都实现了IService这个通用的服务接口这样一来就可以使用父类引用指向子类对象的多态思想
如何使用工厂模式
我们可以创建一个工厂类还有一个枚举类代替不同的机构类型然后再工厂类的静态方法中根据不同的枚举类的code值来创建对应的服务类并返回。
枚举类
public enum OrganTypeEnum implements BaseEnum {OLT(1, 一级转运中心),TLT(2, 二级转运中心),AGENCY(3, 网点);/*** 类型编码*/private final Integer code;/*** 类型值*/private final String value;OrganTypeEnum(Integer code, String value) {this.code code;this.value value;}public Integer getCode() {return code;}public String getValue() {return value;}public static OrganTypeEnum codeOf(Integer code) {return EnumUtil.getBy(OrganTypeEnum::getCode, code);}
}
工厂类
第一种方式使用switch方式来判断要返回哪一种服务类型
根据传入的Integer类型数据使用枚举类的codeOf方法创建对应的枚举类对象
然后使用hutool的SpringUtil获取对应服务类的实例bean对象并返回
/*** 根据type选择对应的service返回** author zzj* version 1.0*/
public class OrganServiceFactory {public static IService getBean(Integer type) {OrganTypeEnum organTypeEnum OrganTypeEnum.codeOf(type);if (null organTypeEnum) {throw new SLException(ExceptionEnum.ORGAN_TYPE_ERROR);}switch (organTypeEnum) {case AGENCY: {return SpringUtil.getBean(AgencyService.class);}case OLT: {return SpringUtil.getBean(OLTService.class);}case TLT: {return SpringUtil.getBean(TLTService.class);}}return null;}}
第二种通过反射来判断
以上方法我们要通过switch语句来判断是要返回哪一种类型的服务类那如果枚举类型很多的话这样是不是冗杂
定义一个接口在接口里定义能返回对应机构枚举类型的方法
public interface OrganTypeService {/*** 获取对应的机构枚举类型*/OrganTypeEnum getOrganTypeEnum();
}然后自定义的服务接口都继承这个接口
public interface AgencyService extends IServiceAgencyEntity ,OrganTypeService{}
public interface OLTService extends IServiceOLTEntity ,OrganTypeService{}
public interface TLTService extends IServiceTLTEntity,OrganTypeService{}
服务类实现这个方法分别返回对应的枚举类型
Service
public class AgencyServiceImpl extends ServiceImplAgencyRepository, AgencyEntity implements AgencyService {Overridepublic OrganTypeEnum getOrganTypeEnum() {return OrganTypeEnum.AGENCY;}
}
Service
public class OLTServiceImpl extends ServiceImplOLTRepository, OLTEntityimplements OLTService {Overridepublic OrganTypeEnum getOrganTypeEnum() {return OrganTypeEnum.OLT;}
}
Service
public class TLTServiceImpl extends ServiceImplTLTRepository, TLTEntityimplements TLTService {Overridepublic OrganTypeEnum getOrganTypeEnum() {return OrganTypeEnum.TLT;}
}
方法实现
public class OrganServiceFactory {public static IService getBean(Integer type) {OrganTypeEnum organTypeEnum OrganTypeEnum.codeOf(type);if (null organTypeEnum) {throw new SLException(ExceptionEnum.ORGAN_TYPE_ERROR);}//先从容器中获取所有的IService类型的bean实例对象MapString, IService beans SpringUtil.getBeansOfType(IService.class);for (Map.EntryString, IService entry : beans.entrySet()) {//通过反射执行getOrganTypeEnum()方法Object invoke ReflectUtil.invoke(entry.getValue(), getOrganTypeEnum);//如果类型一致就返回对应的服务类实例if(ObjectUtil.equal(invoke,organTypeEnum)){return entry.getValue();}}return null;}}
对比
第一种方式不用写额外的方法来返回对应的枚举类型但是需要在工厂的静态方法里来判断枚举类型如果枚举类型少而且不用经常改变代码就可以使用这种方式
第二种方式需要写额外的方法来返回对应的枚举类型但是在工厂方法里就可以使用反射直接执行获取枚举类型的方法来动态获取对应的服务类型。
使用工厂模式
SpringBootTest
public class Test1 {Testpublic void testo1(){IService iService OrganServiceFactory.getBean(1);System.out.println(iService);}
}成功返回OLT类型的服务实现类 如果不使用工厂模式我们就要提前注入这三种类型的服务bean,这样是不是很冗余呢然后还需要根据需要操作的实体类的不同来判断使用哪一个服务类十分麻烦
如
if(type1) 使用oltService来操作
else if(type2) ... ResourceOLTService oltService;ResourceTLTService tltService;ResourceAgencyService agencyService;