class ProjectService {

  public boolean updateByPrimaryKeySelective(Project project) throws Exception {
    LOG.info("updateByPrimaryKeySelective({})", project.toString());
    try (SqlSession sqlSession = MyBatisUtil.getSqlSession()) {
      ProjectMapper projectMapper = sqlSession.getMapper(ProjectMapper.class);
      projectMapper.updateByPrimaryKeySelective(project);

      ProjectFilesMapper projectFilesMapper = sqlSession.getMapper(ProjectFilesMapper.class);
      Map<String, Object> where = new HashMap<>();
      where.put("projectId", project.getId());
      // Take two lists of difference
      List<ProjectFiles> oldProjectFiles = projectFilesMapper.selectAll(where);
      List<String> oldProjectFilesId = new ArrayList<>();
      for (ProjectFiles oldProjectFile : oldProjectFiles) {
        oldProjectFilesId.add(oldProjectFile.getId());
      }
      List<ProjectFiles> currProjectFiles = project.getProjectFilesList();
      List<String> currProjectFilesId = new ArrayList<>();
      for (ProjectFiles currProjectFile : currProjectFiles) {
        currProjectFilesId.add(currProjectFile.getId());
      }

      for (ProjectFiles old : oldProjectFiles) {
        if (!currProjectFilesId.contains(old.getId())) {
          projectFilesMapper.deleteByPrimaryKey(old.getId());
        } else {
          for (ProjectFiles currProjectFile : currProjectFiles) {
            if (currProjectFile.getId() != null && currProjectFile.getId().equals(old.getId())) {
              projectFilesMapper.updateByPrimaryKeySelective(currProjectFile);
            }
          }
        }
      }
      for (ProjectFiles curr : currProjectFiles) {
        if (curr.getId() == null) {
          // TODO(zhulinhao)：The front desk should pass the projectId
          curr.setProjectId(project.getId());
          projectFilesMapper.insert(curr);
        }
      }

      sqlSession.commit();
    } catch (Exception e) {
      LOG.error(e.getMessage(), e);
      throw new Exception(e);
    }
    return true;
  }

}