前言:刚来公司时导师给了一个元数据管理系统让我熟悉,里面大部分接口的实现还是基于neo4j图数据库的,也有用到hive数据库,但只是作为中间库来同步一些数据信息。后面给了些具体需求,让我针对MySQL来开发一些接口。由于代码在内网,所以就不详细展示代码了,主要记录一些碰到的坑和优化点以及一个基本流程。

  • 项目技术栈:SpringBoot+gradle+MySQL/neo4j+jpa

基本开发流程

  1. 看需求文档,设计好数据库表,定义好接口,包括请求参数和返回值等等
  2. 在entity模块定义好实体类
  3. 在dto模块定义好dto,方便后续代码优化
  4. 在repository模块定义持久层接口
  5. 在service层定义好业务接口并具体实现service类
  6. 公共模块可以定义好需要的各种工具类:例如json格式转换,返回值模型,日期处理等等
  7. 在controller层实现业务入口

简单举例

我这边简单拿一个查询记录的接口做举例好了
//下面的代码我没测验过,有问题可以提出来
1 定义实体类

//Data注解属于lombok,可以提高开发效率,省去你自己去get和set了
@Data
@Entity
@Table(name = "student")
public class Student {
	@id
	private int id;
	
	private String name;

	private String course;
}

2 定义好DTO
这个不写了,你可以根据具体场景进行设计

3 持久层接口

@Repository
public interface JpaStudentRepository extends JpaReposity<Student, Long> {
	String TABLE_NAME = "student";
	String SELECT_FIELDS = "id,name,course";
	
	//我写下面这一段是想说如果传入的是DTO对象,参数该怎么写,nativeQuery = true表示使用原生sql
	@Query(value = "select " + SELECT_FIELDS + " from " + TABLE_NAME + " where if(:#{#dto.name}) is not null, name like %:#{#dto.name}%, 1 = 1 )", nativeQuery = true)
	Student findByName(@Param("dto")StudentDTO studentDTO); 

	//直接字段传参
	@Query(value = "select " + SELECT_FIELDS + " from " + TABLE_NAME + " where name like %?1%", nativeQuery = true)
	Student findByName(String name); 

}

4 定义service接口

public interface DataService {
	
	Student queryStudent(String data);
}

5 实现service层代码

@Service
public class StudentService implements DataService {
	
	@Autowired
	JpaStudentRepository jpaStudentRepository
	
	@Override
	public Student queryStudent(String data) {
		StudentDTO studentDTO = JSON.parseObject(data, StudentDTO.class);
		//引入dto主要是为了当匹配参数很多的时候简化代码,当然你也可以像下面这样写
		/*
		Map<String, Object> dataMap;
		dataMap = GsonUtil.jsonToMap(data);
		String name = (String)dataMap.get("name");
		student = jpaStudentRepository.selectByName(name);
		*/
		Student student = new Student();
		try {
			student = jpaStudentRepository.selectByName(studentDTO);
		} catch (Exception e) {
			return null;
		}
		return student;
	}
}

6 Controller层业务入口

@RestController
@RequestMapping(value = "/test")
public class StudentController {

	@Autowired;
	DataService dataService;

	@RequestMapping(value = "/query", method = RequestMethod.GET)
	public Result queryStudent(@RequestParam("operation") String operation, @RequestParam("data") String data, HttpServletRequest req) {
		Result result = new Result("metedata", operation);
		Student student = new Student();
		try {
			student = dataService.queryStudent(data);
		} catch (Exception e) {
			result.setMsg(MsgInfo.ERROR);
			result.setErrorInfo("查询错误");
			return result;
		}
		List<Object> returnList = new ArrayList<>();
		returnList.add(student);
		result.setResult(returnList);
		return result;
	}
}

上述代码其实还涉及两个公共类:返回值包装类和json格式转换类
一般开发阿里的fastjson依赖还是要装下的

  • 返回值包装类
public class MsgInfo {
    
    public static final String SUCCESS = "success";
    public static final String ERROR = "error";
}
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Result {
    
    private Integer status_code;
    private String type;
    private String operation;
    private String msg;
    private List<Object> result;
    private String errorInfo;
    private Map<String, Object> extraInfo = new HashMap<>();
    
    public Result() {
        this.status_code = 200;
        this.setMsg(MsgInfo.SUCCESS);
    }
    
    public Result(String type, String operation) {
        this.type = type;
        this.operation = operation;
        this.status_code = 200;
        this.setMsg(MsgInfo.SUCCESS);
    }

    public Integer getStatus_code() {
        return status_code;
    }

    public void setStatus_code(Integer status_code) {
        this.status_code = status_code;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getOperation() {
        return operation;
    }

    public void setOperation(String operation) {
        this.operation = operation;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public List<Object> getResult() {
        return result;
    }

    public void setResult(List<Object> result) {
        this.result = result;
    }

    public String getErrorInfo() {
        return errorInfo;
    }

    public void setErrorInfo(String errorInfo) {
        this.errorInfo = errorInfo;
    }

    public Map<String, Object> getExtraInfo() {
        return extraInfo;
    }

    public void setExtraInfo(Map<String, Object> extraInfo) {
        this.extraInfo = extraInfo;
    }
}

如何与前段交互完成前后端整合

不考虑什么前端框架的话,简单点html+jquery+ajax就可以完成功能实现
拿avalonjs的控制器举例,代码如下

var viewmodel = avalon.define({

    $id: "viewmodel",
    datalist: {},
    text: "请求数据",
    request: function() {
        var search = {};
        search["name"] = $('#name').val();
        var data = JSON.stringify(search);
        $.ajax(
            {
                type: "get",
                datatype: "json",
                url: "index/query?operation=queryStudent&data=" + data,
                success: function(data) {
                    $('button').removeClass("btn-search").addClass("btn-success");
                    viewmodel.datalist = data.result;
                }
            }
        )
    }
}
);