1. 前端目录结构
分为html、js、css三部分,新迁移功能时需要在html、js、css(一般不用额外新建了)相应目录下新建文件,以元数据导入为例则需要在html/metadata/register下新建idnex.html,javascript/metadata/register新建index.js。
2.后台菜单的url路由修改
更改YU后台中menu.json文件里相应菜单的href为其index的相对路径
3.初步迁移HTML
找到NEAN中相应HTML,全部复制到YU中,将HTML最后的javascript 删除,引入该页面的js
注意删除HTML中原scala的注释
在最外层的section标签上添加id = “vue”,用于vue绑定
4.初始化index.js
初始化index.js,模板如下
var that;
var app = new Vue({
el:"#vue",//绑定之前html写的ID
data:{//相当于成员变量
},
mounted(){//页面一加载就会触发,可以用于初始化页面,相当于window.onload
},
methods:{//相当于成员方法
}
})
到这里,可以打开YU后台访问一下新增的菜单,就可以正常显示出页面了。
5.后端目录
java目录中存放的都是java文件,每个功能点都包含controller、service、dao、entity、(DTO、VO视情况增加)
后台统一API消息体
所有API方法均须返回ApiResp,其返回前端结构如下
{
code: 200,
data: [{flag: "1"}, {lack: [,…]},…],
msg: "SUCCESS"
}
前端通过msg为SUCCESS判断该次请求是否成功,data为后端处理后返回的数据,可为空。
后台统一异常处理
当需要处理异常时,可以通过以下代码进行抛出,将被拦截通过ApiResp封装返回前台
throw new CommonException("用户不存在");
前台显示的结果:
{
code: 3001,
data: {},
msg: "用户不存在"
}
6.controller
编写对外提供的webAPI接口,可参考如下代码
@RestController
@CrossOrigin
//Swagger接口文档,描述该controller
@Api(description = "元数据注册、编目",tags = {"MetadataRegister Controller"})
//请求的url一级路径
@RequestMapping("metadata_register")
public class MetadataRegisterController {
//注入Service
@Resource(name = "metadataRegisterServiceImpl")
MetadataRegisterService metadataRegisterService;
//post方法的二级路径
@PostMapping("catalog_by_class")
//Swagger接口,描述该方法
@ApiOperation(value = "编目对象")
public ApiResp catalogByClass(@RequestBody @ApiParam(name = "传入flag、classId、nodeId、state、entityArray",value = "传入json数据类型",required = true) JSONObject jsonObject){
//获取入参
String classId = jsonObject.getString("classId");
int flag = jsonObject.getInteger("flag");
int state = jsonObject.getInteger("state");
...
//这里写业务逻辑
...
//返回成功,无数据
return ApiResp.retOK();
//返回成功,有数据
return ApiResp.retOk(data);
}
}
以上catalogByClass方法的请求路径即为metadata_register/catalog_by_class,方法为POST,当需要入参时推荐方法都用post,无需入参时可用get。
前端通过封装好的getDataByPost/getDataByGet请求
var data = {
classId: that.classId,
nodeId: JSON.stringify(nodeList),
entityArray:JSON.stringify(entityArray),
state: state,
flag:flag,
queryCondition:JSON.stringify(queryData)
}
getDataByPost('/metadata_register/catalog_by_class',data,res=> {//成功回调
if (res.msg == "SUCCESS") {
toastr.success("编目成功!");
} else {
toastr.error("编目失败!");
}
},err=>{//失败回调
toastr.error(err.msg);
});
7.dao、entity以及resources/mapper下的xml文件
这些文件是通过MybatisGenerator生成,可以git下来https://github.com/q757682793/MybatisGenerate_Oracle.git
1. 修改generator.properties配置文件
//填写maven仓库下的oracle的jdbc jar包
jdbc.driverLocation=C:\\Users\\admin\\.m2\\repository\\com\\oracle\\ojdbc\\ojdbc8\\19.3.0.0\\ojdbc8-19.3.0.0.jar
jdbc.driverClass=oracle.jdbc.driver.OracleDriver
jdbc.connectionURL=jdbc:oracle:thin:@10.196.83.88:1521/HHU
jdbc.username=ZYML
jdbc.password=ZYML_HH
2.修改generatorConfig.xml配置需要生成的数据表
- 配置包名
- 配置需要映射的表
3.生成前保持java和resources目录下整洁,然后点击右上角的run即可
4.生成成功如图
5.将java以及xml文件复制到YU中对应包名的相应目录即可
8.service
新建xxxService.java接口
新建impl package 在里面新建xxxServiceImpl.java 实现 xxxService,模板如下
下面以查询资源目录列表为例
ResourceDirService.java
public interface ResourceDirService{
public List<RcResDirModel> getAll();
}
resourceDirServiceImpl.java
@Service("resourceDirServiceImpl")
public class resourceDirServiceImplimplements ResourceDirService{
//注入mapper
@Autowired
ResDirModelMapper resDirModelMapper;
/***
* 获取所有树节点
* @return
*/
@Override
public List<ResDirModel> getAll()
{
//创建查询条件,无条件即可查询所有列表
//相当于select * from RC_RESDIR
ResDirModelExample resDirModelExample = new ResDirModelExample();
return resDirModelMapper.selectByExample(resDirModelExample);
}
}
下面再以RC_RESDIR多举几个例子
查询
/***
* 根据节点ID获取节点
* @param ids
* @return
*/
@Override
public List<ResDirModel> getListByNodeIdList(List<Long> ids) {
ResDirModelExample resDirModelExample = new ResDirModelExample();
//这里就进行了创建条件
//相当于 select * from RC_RESDIR where NODE_ID in (ids)
resDirModelExample.createCriteria().andNodeIdIn(ids);
return resDirModelMapper.selectByExample(resDirModelExample);
}
//查询审核状态(check_state、long 类型)为通过的节点
public List<ResDirModel> getPassNodes() {
ResDirModelExample resDirModelExample = new ResDirModelExample();
//这里就进行了创建条件
//相当于 select * from RC_RESDIR where check_state = 1
resDirModelExample.createCriteria().andCheckStateEqualTo(1L);
return resDirModelMapper.selectByExample(resDirModelExample);
}
插入
/***
* 创建新的节点
* @param resDirModel
* @return
*/
@Override
public void addNode(ResDirModel resDirModel) {
//直接传入该实体类即可插入,注意主键不可为空等约束
resDirModelMapper.insert(resDirModel);
}
删除
//删除有两种方式:
//1.根据条件删除。
@Override
public void delete(List<Long> ids){
ResDirModelExample resDirModelExample = new ResDirModelExample();
resDirModelExample.createCriteria().andNodeIdIn(ids);
resDirModelMapper.deleteByExample(resDirModelExample)
}
//2.根据主键删除
@Override
public void delete(String id){
resDirModelMapper.deleteByPrimaryKey(id);
}
更新
更新有四种方法,推荐用含有selective的两种方法,selective可以不更新值为空的字段,如果不是selectvie,传入的实体有值为空的字段则会将该字段置空。
//1.根据条件进行更新
public void update(ResDirModel resDirModel){
//相当于update RC_RESDIR set check_state = 0 where check_state =1
ResDirModelExample resDirModelExample = new ResDirModelExample();
resDirModelExample.createCriteria().andCheckStateEqualsTo(1L);
//这边实体赋值传参之前在controller中已经完成,这里只是用于演示
resDirModel.setCheckState(0L);
resDirModelMapper.updateByExampleSelective(resDirModel,resDirModelExample);
}
//2.根据主键进行更新
public void update(ResDirModel resDirModel){
//这边实体赋值传参之前在controller中已经完成,这里只是用于演示
resDirModel.setNodeId("111111");//主键必须有值
resDirModel.setCheckState(1L);
//相当于update RC_RESDIR set check_state = 1 where node_id = '111111'
resDirModelMapper.updateByPrimaryKeySelective(resDirModel);
}
9.完整的controller调用
@RestController
@CrossOrigin
@RequestMapping("resource_dir")
@Api(description = "资源目录树管理",tags = {"ResourceDirTree Controller"})
public class ResourceDirController {
//注入service
@Resource(name = "resourceDirServiceImpl")
ResourceDirService resourceDirService;
@ApiOperation(value = "获取资源目录树")
@GetMapping("get_all_resdir_node")
public ApiResp getAllResdirNode() {
List<ResDirModel> list = resourceDirService.getAll();
return ApiResp.retOK(list);
}
}
通过请求接口resource_dir/get_all_resdir_node即可得到resdir的list
查询结果如下
10.多表联合查询
MybatisGenerator适用于单表查询,如果需要进行复杂的多表查询,可以直接编写相应的dao以及xxxMapper.xml,如下所示
FdRelModelMapper.java
List<FdRelAndAttInfoDTO> getFdRelAndAttInfo(String attCName,String classId,String databaseId);
FdRelModelMapper.xml
<resultMap id="FdRelAndAttInfoMap" type="org.hhu.yu.metadata.extract.management.DTO.FdRelAndAttInfoDTO" >
<result column="ATT_E_NAME" jdbcType="VARCHAR" javaType="java.lang.String" />
<result column="ATT_TAB_EN" jdbcType="VARCHAR" javaType="java.lang.String" />
<result column="P_TAB_ID" jdbcType="VARCHAR" javaType="java.lang.String" />
<result column="F_TAB_ID" jdbcType="VARCHAR" javaType="java.lang.String" />
<result column="P_FD_ID" jdbcType="VARCHAR" javaType="java.lang.String" />
<result column="F_FD_ID" jdbcType="VARCHAR" javaType="java.lang.String" />
</resultMap>
<select id="getFdRelAndAttInfo" parameterType="java.lang.String" resultMap="FdRelAndAttInfoMap">
select a.att_e_name,a.att_tab_en,c.p_tab_id,c.f_tab_id,c.p_fd_id,c.f_fd_id
from oom_attinfo a
left join oom_attconf b on a.att_id=b.att_id
left join dom_fd_rel c on b.rel_id=c.rel_id
where a.att_c_name=#{attCName}
and b.class_id=#{classId}
and c.db_id=#{databaseId}
order by b.rel_order asc
</select>
FdRelAndAttInfoDTO.java
@Getter
@Setter
@AllArgsConstructor
public class FdRelAndAttInfoDTO {
private String attEName;
private String attTabEn;
private String pTabId;
private String fTabId;
private String pFdId;
private String fFdId;
}
以上仅是简易说明,具体还需自学Vue以及Springboot相关知识。