人才招聘库是企业用于储存和管理潜在候选人信息的数据库。通常情况下,这些候选人可能已经应聘过公司的职位,也可能是通过其他途径获取的,例如社交网络、招聘网站等。
对于一个中小公司来说,人力资源部绝对是一个重要部门,有着举足轻重的作用。
人才招聘库可以帮助企业更好地利用和管理人力资源,在公司需要新员工时,能够及时查找并联系到合适的候选人。此外,人才招聘库还能够提高企业对人才储备的掌握程度,有助于发现和培养优秀的人才,并提高企业的竞争力。人才招聘库通常包含候选人的基本信息、教育背景、工作经历、技能证书以及推荐信等资料,这些信息都可以帮助企业更全面地了解候选人的能力和素质。
对于人力资源部来说,如果靠纸质或Excel来维护人才档案,效率低下,所以功能完整的人才招聘库模块,还是非常重要的,本文旨在完成人才招聘库的设计和实现。
一、实体类(entity)设计
实体类是面向对象编程中的一个重要概念,用于描述现实世界中的实体或概念,并将其抽象为程序中的一个类。在设计实体类时,需要考虑实体之间的关系以及它们的属性和行为。
在设计功能模块之前,首先要对实体进行设计,本文设计的实体有以下几个。
- 人才库档案(a_talent_pool)
- 人才库标签关系(a_talent_pool_and_label)
- 人才类型关系表(a_talent_pool_and_type)
- 人才面试记录(a_talent_pool_interview_record)
- 人才库标签(a_talent_pool_label)
- 人才简历(a_talent_pool_resume)
- 人才沟通记录(a_talent_pool_say_record)
- 人才类型(a_talent_pool_type)
实体类设计代码如下。
@Table(name = "a_talent_pool") @TableName("a_talent_pool") @ApiModel(value = "人才库档案") public class TalentPool extends ZwzBaseEntity { private static final long serialVersionUID = 1L; @ApiModelProperty(value = "人才姓名") private String userName; @ApiModelProperty(value = "人才性别") private String userSex; @ApiModelProperty(value = "人才手机号") private String userMobile; @ApiModelProperty(value = "人才意向") private String userMean; @ApiModelProperty(value = "人才优势") private String advantage; @ApiModelProperty(value = "人才状态") private String status; @Transient @TableField(exist=false) @ApiModelProperty(value = "应聘岗位ID") private String postOffer; @Transient @TableField(exist=false) @ApiModelProperty(value = "应聘岗位名称") private String postTitle; @ApiModelProperty(value = "备注") private String remark; @Transient @TableField(exist=false) @ApiModelProperty(value = "人才标签") private List<TalentPoolLabel> labelList; @Transient @TableField(exist=false) @ApiModelProperty(value = "沟通记录") private List<TalentPoolSayRecord> sayList; @Transient @TableField(exist=false) @ApiModelProperty(value = "面试记录") private List<TalentPoolInterviewRecord> interviewList; @Transient @TableField(exist=false) @ApiModelProperty(value = "简历档案") private List<TalentPoolResume> resumeList; }
@Table(name = "a_talent_pool_and_label") @TableName("a_talent_pool_and_label") @ApiModel(value = "人才库标签关系") public class TalentPoolAndLabel extends ZwzBaseEntity { private static final long serialVersionUID = 1L; @ApiModelProperty(value = "标签ID") private String labelId; @ApiModelProperty(value = "人才Id") private String talentId; }
@Table(name = "a_talent_pool_and_type") @TableName("a_talent_pool_and_type") @ApiModel(value = "人才类型关系表") public class TalentPoolAndType extends ZwzBaseEntity { private static final long serialVersionUID = 1L; @ApiModelProperty(value = "类型ID") private String typeId; @ApiModelProperty(value = "人才Id") private String talentId; }
@Table(name = "a_talent_pool_interview_record") @TableName("a_talent_pool_interview_record") @ApiModel(value = "人才面试记录") public class TalentPoolInterviewRecord extends ZwzBaseEntity { private static final long serialVersionUID = 1L; @ApiModelProperty(value = "人才Id") private String talentId; @ApiModelProperty(value = "面试日期") private String interviewDate; @ApiModelProperty(value = "入职意向") private String inMean; @ApiModelProperty(value = "面试评价") private String interviewAns; @ApiModelProperty(value = "备注") private String remark; }
@Table(name = "a_talent_pool_label") @TableName("a_talent_pool_label") @ApiModel(value = "人才库标签") public class TalentPoolLabel extends ZwzBaseEntity { private static final long serialVersionUID = 1L; @ApiModelProperty(value = "名称") private String title; @ApiModelProperty(value = "分类") private String type; @ApiModelProperty(value = "备注") private String remark; @ApiModelProperty(value = "状态") private String status; @ApiModelProperty(value = "排序值") private BigDecimal sortOrder; }
@Table(name = "a_talent_pool_resume") @TableName("a_talent_pool_resume") @ApiModel(value = "人才简历") public class TalentPoolResume extends ZwzBaseEntity { private static final long serialVersionUID = 1L; @ApiModelProperty(value = "人才Id") private String talentId; @ApiModelProperty(value = "查收日期") private String date; @ApiModelProperty(value = "简历文件") private String url; @ApiModelProperty(value = "备注") private String remark; }
@Table(name = "a_talent_pool_say_record") @TableName("a_talent_pool_say_record") @ApiModel(value = "人才沟通记录") public class TalentPoolSayRecord extends ZwzBaseEntity { private static final long serialVersionUID = 1L; @ApiModelProperty(value = "人才Id") private String talentId; @ApiModelProperty(value = "沟通日期") private String sayDate; @ApiModelProperty(value = "沟通内容") private String sayContent; @ApiModelProperty(value = "沟通反馈") private String sayAns; @ApiModelProperty(value = "备注") private String remark; }
@Table(name = "a_talent_pool_type") @TableName("a_talent_pool_type") @ApiModel(value = "人才类型") public class TalentPoolType extends ZwzBaseEntity { private static final long serialVersionUID = 1L; @ApiModelProperty(value = "标题") private String title; @ApiModelProperty(value = "是否展开直子节点") private boolean expand = true; @ApiModelProperty(value = "禁用") private boolean disabled = false; @ApiModelProperty(value = "是否选中") private boolean selected = false; @Transient @TableField(exist=false) @ApiModelProperty(value = "子类型") private List<TalentPoolType> children = new ArrayList<>(); @ApiModelProperty(value = "排序值") @Column(precision = 10, scale = 2) private BigDecimal sortOrder = BigDecimal.TEN; @ApiModelProperty(value = "父id") private String parentId; @Transient @TableField(exist=false) @ApiModelProperty(value = "父类型名称") private String parentTitle; }
二、数据链路层(Mapper)设计
在Java MVC模式中,Mapper层是指用于持久化数据的一层,通常负责与数据库交互,以及将数据库中的数据转换为应用程序中的对象。具体来说,Mapper层通常包括以下几个部分:
- 数据库连接:Mapper层需要与数据库进行交互,因此需要建立数据库连接。通常来说,这可以通过JDBC或ORM框架来实现。
- 数据映射:Mapper层需要将数据库中的数据映射到Java对象中。通常来说,这可以通过ORM框架如Hibernate、MyBatis等来完成。
- 数据访问:Mapper层需要提供对数据库的读写操作,包括增删改查等基本操作。通常来说,这可以通过使用SQL语句或ORM框架提供的API来实现。
- 事务管理:Mapper层需要处理数据库事务,保证数据的完整性和一致性。通常来说,这可以通过使用JDBC的事务机制或者ORM框架提供的事务管理器来实现。
总之,Mapper层在Java MVC模式中起着很重要的作用,它负责将数据库和应用程序之间的数据交互进行封装,并提供了一些有价值的功能,例如数据访问、数据映射和事务管理等,大大简化了应用程序开发人员的工作,同时也提高了应用程序的可维护性和扩展性。
人才招聘库的数据链路层接口,只需要继承 MybatisPlus
的 BaseMapper
类即可,设计代码如下。
/** * 人才库标签关系数据处理层 * @author 郑为中 */ public interface TalentPoolAndLabelMapper extends BaseMapper<TalentPoolAndLabel> { }
/** * 人才类型关系表数据处理层 * @author 郑为中 */ public interface TalentPoolAndTypeMapper extends BaseMapper<TalentPoolAndType> { }
/** * 人才面试记录数据处理层 * @author 郑为中 */ public interface TalentPoolInterviewRecordMapper extends BaseMapper<TalentPoolInterviewRecord> { }
/** * 人才库标签数据处理层 * @author 郑为中 */ public interface TalentPoolLabelMapper extends BaseMapper<TalentPoolLabel> { }
/** * 人才库档案数据处理层 * @author 郑为中 */ public interface TalentPoolMapper extends BaseMapper<TalentPool> { }
/** * 人才简历数据处理层 * @author 郑为中 */ public interface TalentPoolResumeMapper extends BaseMapper<TalentPoolResume> { }
/** * 人才沟通记录数据处理层 * @author 郑为中 */ public interface TalentPoolSayRecordMapper extends BaseMapper<TalentPoolSayRecord> { }
/** * 人才类型数据处理层 * @author 郑为中 */ public interface TalentPoolTypeMapper extends BaseMapper<TalentPoolType> { }
二、服务层(Service)设计
在Java MVC模式中,Service层通常负责处理业务逻辑和数据处理。具体来说,Service层通常包括以下几个部分:
- 业务逻辑:Service层负责实现应用程序的业务逻辑,例如验证用户输入、处理表单数据、生成报告等。
- 数据处理:Service层负责将数据库操作从Controller层中分离出来,包括查询、更新、删除和插入数据等操作。
- 事务管理:Service层需要保证事务的完整性和一致性,并且需要提供回滚和提交事务的功能。
- 异常处理:Service层需要处理可能发生的异常,例如数据库连接错误、数据访问异常等。
总之,Service层在Java MVC模式中承担着很重要的角色,它负责处理业务逻辑和数据处理,可以有效地将Controller层与DAO层分离开来,使代码更加清晰和易于维护。此外,Service层还可以通过统一的接口为多个Controller层提供服务,大大简化了应用程序的设计和开发过程。
人才招聘库的服务层接口,只需要继承 MybatisPlus
的 IService
类即可。
人才招聘库的服务层接口实现,只需要继承 MybatisPlus
的 ServiceImpl
类,实现对应的服务层接口即可,设计代码如下。
- 人才库标签关系接口
public interface ITalentPoolAndLabelService extends IService<TalentPoolAndLabel> { }
- 人才库标签关系接口实现
@Slf4j @Service @Transactional public class ITalentPoolAndLabelServiceImpl extends ServiceImpl<TalentPoolAndLabelMapper, TalentPoolAndLabel> implements ITalentPoolAndLabelService { @Autowired private TalentPoolAndLabelMapper talentPoolAndLabelMapper; }
- 人才类型关系接口
public interface ITalentPoolAndTypeService extends IService<TalentPoolAndType> { }
- 人才类型关系接口实现
@Slf4j @Service @Transactional public class ITalentPoolAndTypeServiceImpl extends ServiceImpl<TalentPoolAndTypeMapper, TalentPoolAndType> implements ITalentPoolAndTypeService { @Autowired private TalentPoolAndTypeMapper talentPoolAndTypeMapper; }
- 人才面试记录接口
public interface ITalentPoolInterviewRecordService extends IService<TalentPoolInterviewRecord> { }
- 人才面试记录接口实现
@Slf4j @Service @Transactional public class ITalentPoolInterviewRecordServiceImpl extends ServiceImpl<TalentPoolInterviewRecordMapper, TalentPoolInterviewRecord> implements ITalentPoolInterviewRecordService { @Autowired private TalentPoolInterviewRecordMapper talentPoolInterviewRecordMapper; }
- 人才库标签接口
public interface ITalentPoolLabelService extends IService<TalentPoolLabel> { }
- 人才库标签接口实现
@Slf4j @Service @Transactional public class ITalentPoolLabelServiceImpl extends ServiceImpl<TalentPoolLabelMapper, TalentPoolLabel> implements ITalentPoolLabelService { @Autowired private TalentPoolLabelMapper talentPoolLabelMapper; }
- 人才简历接口
/** * 人才简历接口 * @author 郑为中 */ public interface ITalentPoolResumeService extends IService<TalentPoolResume> { }
- 人才简历接口实现
@Slf4j @Service @Transactional public class ITalentPoolResumeServiceImpl extends ServiceImpl<TalentPoolResumeMapper, TalentPoolResume> implements ITalentPoolResumeService { @Autowired private TalentPoolResumeMapper talentPoolResumeMapper; }
- 人才沟通记录接口
public interface ITalentPoolSayRecordService extends IService<TalentPoolSayRecord> { }
- 人才沟通记录接口实现
@Slf4j @Service @Transactional public class ITalentPoolSayRecordServiceImpl extends ServiceImpl<TalentPoolSayRecordMapper, TalentPoolSayRecord> implements ITalentPoolSayRecordService { @Autowired private TalentPoolSayRecordMapper talentPoolSayRecordMapper; }
- 人才库档案接口
public interface ITalentPoolService extends IService<TalentPool> { }
- 人才库档案接口
@Slf4j @Service @Transactional public class ITalentPoolServiceImpl extends ServiceImpl<TalentPoolMapper, TalentPool> implements ITalentPoolService { @Autowired private TalentPoolMapper talentPoolMapper; }
- 人才类型接口
public interface ITalentPoolTypeService extends IService<TalentPoolType> { }
- 人才类型接口实现
@Slf4j @Service @Transactional public class ITalentPoolTypeServiceImpl extends ServiceImpl<TalentPoolTypeMapper, TalentPoolType> implements ITalentPoolTypeService { @Autowired private TalentPoolTypeMapper talentPoolTypeMapper; }
三、控制器层(Controller)设计
在Java MVC模式中,Controller层是指用于接收用户请求并处理请求的一层。Controller层通常负责业务流程控制和调度,将用户请求传递给Service层完成相关业务逻辑处理,并将结果返回给前端视图(View)层进行展示,具体来说,Controller层通常包括以下几个部分:
- URL路由:Controller层需要根据不同的URL路由来匹配对应的请求处理方法。
- 请求参数解析:Controller层需要解析HTTP请求中的参数,并进行校验和验证。
- 业务逻辑处理:Controller层需要将请求转发给Service层进行业务逻辑处理,并获取处理结果。
- 视图渲染:Controller层需要将处理结果传递给View层进行渲染和展示。
总之,Controller层在Java MVC模式中起着很重要的作用,它负责接收用户请求、处理请求、调度业务逻辑和协调其他层之间的交互,大大简化了应用程序开发人员的工作,同时也提高了应用程序的可维护性和扩展性。
人才招聘库的控制器层接口,需要自行编写业务相关的接口,给前端提供数据支持。
3.1 人才类型管理接口
人才类型控制器用于提供人才类型的一级新增、子节点新增、编辑、删除接口。
因为人才类型用到了树形结构,需要用到深搜(dfs)算法进行查询回显。
首先创建 TalentPoolTypeController
类,注入 ITalentPoolTypeService
服务,代码如下。
@RestController @Api(tags = "人才类型接口") @RequestMapping("/zwz/talentPoolType") @Transactional public class TalentPoolTypeController { @Autowired private ITalentPoolTypeService iTalentPoolTypeService; }
3.1.1 查询人才类型
在设计人才类似的实体时,我们设计了 parentId
字段。
@ApiModelProperty(value = "父id") private String parentId;
只需要指定一级标题的 parentId
为 0
,其余节点的 parentId
是父节点的 id
。
设计深搜方法 dfsFindTalentPoolTypeChildren
。
@ApiOperation(value = "深搜查询人才库类型") private void dfsFindTalentPoolTypeChildren(List<TalentPoolType> allList,TalentPoolType talentPoolType) { boolean flag = false; for (TalentPoolType type : allList) { if(Objects.equals(talentPoolType.getId(),type.getParentId())) { type.setParentTitle(talentPoolType.getTitle()); talentPoolType.getChildren().add(type); flag = true; } } if(flag) { for (TalentPoolType child : talentPoolType.getChildren()) { dfsFindTalentPoolTypeChildren(allList,child); } } }
接着编写查询人才类型的 getAll
方法。
@RequestMapping(value = "/getAll", method = RequestMethod.GET) @ApiOperation(value = "查询人才库类型") public Result<List<TalentPoolType>> getAll(){ QueryWrapper<TalentPoolType> qw = new QueryWrapper<>(); qw.eq("parent_id","0"); qw.orderByAsc("sort_order"); List<TalentPoolType> oneList = iTalentPoolTypeService.list(qw); List<TalentPoolType> allList = iTalentPoolTypeService.list(); for (TalentPoolType type : oneList) { type.setParentTitle("顶级类型"); dfsFindTalentPoolTypeChildren(allList,type); } return new ResultUtil<List<TalentPoolType>>().setData(oneList); }