JEECG上手使用总结

写在前面

由于之前的一个项目公司外包出去但是没有做好,于是公司打算自己做,使用的是 JEECG 框架,所以用这篇文章记录下使用这个框架的一些总结,刚开始只是随手记,遇到什么写什么,等内容差不多了再分类整理。

文章有点长,可以根据目录查看相应的模块。在文章的右侧工具栏可以快捷地查看目录:
在这里插入图片描述

文章写得还不全, 如果没能解决问题, 可以移步 JEECG官方文档, 不过官方文档格式有些乱。

数据列表:Datagrid

Datagrid是JEECG生成列表的通用解决方案之一,用户可以根据自己的需求自定义列表展示的效果:
在这里插入图片描述
官网文档 对各个参数介绍很详细,这边主要就贴下整体代码(代码生成的页面和上图无关, 上图代码在框架的UserController.java类的user()中):

<!-- 需要引入相关的tag -->
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@include file="/context/mytags.jsp" %>
<t:base type="jquery,easyui,tools,DatePicker"/>
<div class="easyui-layout" fit="true">
    <div region="center" style="padding:0;border:0">
	    <!-- datagrid标签中的相关属性说明
			actionUrl: 获取数据的地址
			rowStyler: 行样式
			autoLoadData: 页面初始化的时候自动加载数据
		 -->
        <t:datagrid name="userList" checkbox="true" title="用户管理"
                    actionUrl="userController.do?datagrid&user.departId=${departId}" idField="id" sortName="user.createDate"
                    rowStyler="gridRowStyler" autoLoadData="false"
                    fitColumns="false" fit="true" singleSelect="true" queryMode="group">
            <t:dgCol title="主键" field="id" hidden="true" queryMode="single" width="120" />
            <t:dgCol title="姓名" field="user.name" queryMode="single" width="120" />
            <t:dgCol title="人员类型" field="user.userType" queryMode="single" dictionary="biz_user_type,code,name" width="120" />
            <t:dgCol title="出生日期" field="user.birthday" formatter="yyyy-MM-dd hh:mm:ss" queryMode="single" width="140" />
            <t:dgCol title="手机号" field="user.phone" queryMode="single" width="120" />
            <!-- dictionary: 可以使用字典, 也可以使用表名加字段名, 如籍贯中的p_basic_place即表名 -->
            <t:dgCol title="性别" field="user.sex" queryMode="single" dictionary="biz_sex_type,code,name" width="120" />
            <t:dgCol title="籍贯" field="user.birthplace" queryMode="single" dictionary="p_basic_place,id,name" width="120" />
            <!-- formatterjs定义一个函数, 该列的值由该函数计算 -->
            <t:dgCol title="年龄" field="user.age" queryMode="single" width="100" formatterjs="calcAge"/>
        </t:datagrid>
        <!-- 1. 列表名 + tb: 框架会将这段代码渲染成查询条件框, 如果没有这段代码则框架会自动生成默认代码 -->
        <div id="userListtb" style="padding: 3px; height: 27px;border-bottom:1px solid #D7D7D7">
            <div style="float: left;" class="searchColums">
                姓名:<input class="inuptxt ac_input" type="text" name="user.name" value="${name}">
                人员类型:<t:dictSelect field="user.userType" type="list"
                                   extendJson="{class:'form-control',style:'width:158px'}"
                                   datatype="*"
                                   typeGroupCode="biz_user_type"
                                   hasLabel="false" title="人员类型"/>
                出生日期:
                <!-- 2. 不使用自动生成的时间范围控件, 可以使用如下方式自己定义 -->
                <input type="text" id="birthday_begin" name="user.birthday_begin" class="Wdate" value="${startTime}" autocomplete="off"
                       style="width: 145px; height: 20px;" onclick="WdatePicker({dateFmt: 'yyyy-MM-dd',maxDate:'#F{$dp.$D(\'formDate_end\',{d:-1});}'});" />&nbsp;~
                <input type="text" id="birthday_end" name="user.birthday_end" class="Wdate" value="${endTime}" autocomplete="off"
                       style="width: 145px; height: 20px; margin-right: 20px;"  onclick="WdatePicker({dateFmt: 'yyyy-MM-dd',minDate:'#F{$dp.$D(\'formDate_begin\',{d:1});}'});" />
            </div>
            <div align="right">
                <a href="#" class="easyui-linkbutton" iconCls="icon-search" onclick="userListsearch();">查询</a>
                <a href="#" class="easyui-linkbutton" iconCls="icon-reload" onclick="searchReset('userList')">重置</a>
            </div>
        </div>
        <!-- 3. 列表名 + tb2: 框架会将这段代码渲染成工具栏, 如果没有这段代码则框架会自动生成默认代码 -->
        <div id="userListtb2" style="padding: 3px; height: 25px">
            <div style="float: left;">
                <a href="#" class="easyui-linkbutton" plain="true" icon="icon-chakan" onclick="masterView('userController.do?goView', 'userList', 'user.id');">查看</a>
                <a href="#" class="easyui-linkbutton" plain="true" icon="icon-remove" onclick="masterDelete('userController.do?doBatchDel', 'userList', 'user.id');">删除</a>
            </div>
        </div>
    </div>
</div>
<script type="text/javascript">
    window.onload = function () {
        userListsearch();
    };
</script>

当页面初始化后框架会自动生成一个 name + search()的函数,如果 autoLoadData 属性为 true 则页面加载后就会自动调用该函数查询数据并展示出来,如果为false则需要手动调用该函数查询数据,可以看到「查询」按钮也是绑定该函数。

该框架在生成页面的时候会生成一些函数和样式,所以框架中大部分页面的问题都可以考虑从已经生成的页面上去查看代码,寻找解决方案。

后端查询数据接口 userController.do?datagrid 按照一定的规范进行编写,命名统一是datagrid

UserController.java

/**
 * easyui AJAX请求数据
 */
@RequestMapping(params = "datagrid")
public void datagrid(UserEntity user, HttpServletRequest request, HttpServletResponse response, DataGrid dataGrid) {
    userService.datagrid(user, request.getParameterMap(), dataGrid);
    TagUtil.datagrid(response, dataGrid);
}

UserService.java

// UserEntity 需要对应到数据库中的表
public void datagrid(UserEntity user, Map<String, String[]> parameterMap, DataGrid dataGrid){
    CriteriaQuery cq = new CriteriaQuery(UserEntity.class, dataGrid);
    //查询条件组装器
    org.jeecgframework.core.extend.hqlsearch.HqlGenerateUtil.installHql(cq, user, parameterMap);
    try{
        //自定义追加查询条件
    }catch (Exception e) {
        throw new BusinessException(e.getMessage());
    }
    cq.add();
    this.getDataGridReturn(cq, true);
}

UserEntity.java

@Entity
@Table(name = "p_basic_user", schema = "")
public class UserEntity implements Serializable {
	属性...
}

数据列表:AppendGrid

AppendGrid 是JEECG实现数据列表的又一解决方案,相比 DataGrid 这种列表可以实现动态增加行、删除行、编辑行功能,可以满足特定的业务需求,效果图如下:
AppendGrid实现的列表

这个模块主要是引用了开源的AppendGrid插件, 可以看看官方示例,不知道是不是用的人不多,遇到问题的时候很少能找到解决方案

这里就以上图为例,演示下大致的实现逻辑,有些地方会用注释加以说明(这里由于长度限制省略部分代码):

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@include file="/context/mytags.jsp" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <t:base type="jquery,bootstrap,bootstrap-form,common-form,DatePicker"/>
</head>
<body>
<div class="container">
    <div class="panel-body">
        <!-- formvalid类似于form表单, 其中的action属性表示当前表单页面提交的地址 -->
        <t:formvalid formid="formObj" dialog="true" layout="table" tiptype="6"
                     action="storagePlanController.do?doAdd" styleClass="form-horizontal" >
            <input type="hidden" name="id" value='${user.id}'>
            <div class="row">
                <div class="bt-item col-xs-12">
                    <div class="row">
                        <div class="col-xs-1 bt-label required-img">供货商:</div>
                        <div class="col-xs-2 bt-content">
                            <!-- popupClick方法作用是弹窗显示选择列表, basic_supplier_select 是Online报表配置的编码 -->
                            <input id="supplierName" name="supplierName" type="text" value='${supplierName}' class="form-control Wpopup"
                                   datatype="*" ignore="checked" onclick="popupClick(this,'id,name','supplierId,supplierName','basic_supplier_select')"/>
                            <input id="supplierId" name="supplierId" type="hidden" value='${supplierId}'>
                        </div>
                        <div class="col-xs-1 bt-label required-img">日期:</div>
                        <div class="col-xs-2 bt-content">
                            <!-- 自定义事件控件 -->
                            <input id="formDate" name="formDate" type="text"
                                   class="form-control Wdate" onClick="WdatePicker({dateFmt:'yyyy-MM-dd HH:mm:ss',isShowToday:true})" datatype="date" ignore="checked"
                                   value="<fmt:formatDate value='${formDate}' type='date' pattern='yyyy-MM-dd HH:mm:ss'/>"/>
                        </div>
                        单据号...
                        制单人...
                    </div>
                </div>
                <div class="bt-item col-xs-12">
                    <div class="row">
                        <div class="col-xs-1 bt-label required-img">审核:</div>
                        <div class="col-xs-2 bt-content">
                            <!-- 人员选择框 -->
                            <t:userSelect title="审核选择" datatype="*"
                                          selectedNamesInputId="auditUserName"
                                          selectedIdsInputId="auditUserId"
                                          userNamesDefalutVal="${auditUserName}"
                                          userIdsDefalutVal="${auditUserId}"
                                          windowWidth="1000px" windowHeight="600px" />
                        </div>
                        验收...
                        仓管...
                        财务...
                    </div>
                </div>
            </div>

            <div id="detail_tab" class="tab-wrapper">
                <!-- tab -->
                <ul class="nav nav-tabs" role="tablist">
                    <!-- tab-ajax-url 用来查询列表展示的数据, 其中field参数规定了后端需要返回哪些字段的值 -->
                    <li role="presentation" class="active" tab-ajax-url="storagePlanController.do?datagridDetail&field=id,itemEntity.itemCategoryName,itemEntity.id,itemEntity.code,itemEntity.name,itemEntity.specification,itemEntity.unitName,unitPrice,batchNo,quantity,sumAmount&rows=50&user.id=${user.id}">
                        <a href="#con-wrapper0" role="tab" data-toggle="tab">采购计划物品</a>
                    </li>
                    <!-- 加号按钮 -->
                    <li role="presentation" id="tabAddData">
                        <button id="addDetailBtn" type="button" class="btn btn-default"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
                    </li>
                </ul>
                <!-- AppendGrid 展示列表的区域 -->
                <div class="tab-content">
                    <div id="con-wrapper0" role="tabpanel" class="tab-pane active table-responsive">
                        <table id="tblAppendGrid" class="table"></table>
                    </div>
                </div>
            </div>
        </t:formvalid>
    </div>
</div>
<script src="plug-in/layer/layer.js"></script>
<script src="plug-in/jquery-plugs/AppendGrid.js"></script>
<script type="text/javascript">
    var myAppendGrid = null;
    var detailList = [];

    $(document).ready(function () {
        // 1. 初始化 AppendGrid 对象
        myAppendGrid = new AppendGrid($.extend({}, AppendGridGlobalParam, {
            element: "tblAppendGrid",
            idPrefix: "storagePlanDetailList",
            maxRowsAllowed: 5,
            maxNumRowsReached: function () {
                // Show an alert message
                alert('You cannot add more than 5 rows!');
            },
            // columns: 设置字段, 如果必填, 增加 datatype 属性(可以是任意值)
            columns: [
                { name: "id", display: "id", type: "hidden" },
                { name: "itemId", display: "itemId", type: "hidden" },
                { name: "itemCategoryName", display: "类别", type: "readonly", ctrlClass: "form-control input-sm", ctrlAttr: { disabled: true }  },
                { name: "itemName", display: "名称", type: "readonly", ctrlClass: "form-control input-sm", ctrlAttr: { disabled: true } },
                { name: "specification", display: "规格", type: "readonly", ctrlClass: "form-control input-sm", ctrlAttr: { disabled: true } },
                { name: "unitName", display: "单位", type: "readonly", ctrlClass: "form-control input-sm", ctrlAttr: { disabled: true } },
                { name: "batchNo", display: "批次", type: "text", ctrlClass: "form-control input-sm", ctrlAttr: { "datatype": "*" } },
                { name: "quantity", display: "数量", type: "number", ctrlClass: "form-control input-sm", ctrlAttr: { "datatype": "num" }, events: {
                        change: function(e) {// 自定义处理函数, 在值发生变化后触发, 还有click事件
                            // 获取当前行的下标, 从0开始
                            var rowIdx = myAppendGrid.getRowIndex(e.uniqueIndex);
                            // 获取当前行中的字段值
                            var quantity = myAppendGrid.getCtrlValue("quantity", rowIdx);
                            var unitPrice = myAppendGrid.getCtrlValue("unitPrice", rowIdx);
                            // 设置当前行中某个字段值
                            myAppendGrid.setCtrlValue("sumAmount", rowIdx, (quantity * unitPrice).toFixed(3));
                        }
                    }
                },
                { name: "unitPrice", display: "单价", type: "text", ctrlClass: "form-control input-sm", ctrlAttr: { "datatype": "num" }},
                { name: "sumAmount", display: "金额", type: "text", ctrlClass: "form-control input-sm", ctrlAttr: { disabled: true } }
            ]
        }));

        // 2. 初始化: 查询列表数据, 并动态添加到列表中
        initDetail();
    });

    function initDetail() {
        var tabHead = $("#detail_tab li:first");
        // 通过这个地址查询列表数据
        var url = tabHead.attr("tab-ajax-url");
        $.get(url, {}, function (data) {
            detailList = [];
            // 组装数据
            $.each( data.rows, function(i, n){
                var dataMap = {};
                dataMap.id = n['id'];
                dataMap.itemId = n['itemEntity.id'];
                dataMap.itemCategoryName = n['itemEntity.itemCategoryName'];
                dataMap.itemCode = n['itemEntity.code'];
                dataMap.itemName = n['itemEntity.name'];
                dataMap.specification = n['itemEntity.specification'];
                dataMap.unitName = n['itemEntity.unitName'];
                dataMap.unitPrice = n['unitPrice'];
                dataMap.batchNo = n['batchNo'];
                dataMap.quantity = n['quantity'];
                dataMap.sumAmount = (n['quantity'] * n['unitPrice']).toFixed(3);
                detailList.push(dataMap);
            });

            // 将数据添加到列表中
            myAppendGrid.appendRow(detailList);
        });
    }

</script>
</body>
</html>

数据列表:Online报表配置

先看官方介绍:

报表配置可以通过在线配置,无需编写代码生成数据报表页面。JEECG Online报表开发是一种配置式的报表开发模式,省去了报表的开发工作,将报表的开发简化为SQL + 配置的形式。

意思就是在网页上进行配置,然后直接调用就可以生成一张简单的列表页面,如下图中2所示:
在这里插入图片描述
上图是点击加号后弹出配置好的弹窗,要实现这种效果要分两步走,第一步配置报表的基本信息,第二部在前端页面中引用报表,接下来以上图例子来实现以下。

首先是报表配置,官网介绍的很清楚了,见 Online数据报表配置,这里简单讲一下:
在这里插入图片描述
配置好以后,就在前端页面中编写弹窗代码,先写一个 「+」 按钮:

<li role="presentation" id="tabAddData">
	<button id="addBtn" type="button" class="btn btn-default">
		<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
	</button>
</li>

绑定onclick事件,事件中进行弹窗:

// 定义click事件
$('#addBtn').bind('click', function(){
    var departId = $("input[name=departId]").val();
    if (isEmpty(departId)) {
        tip("请先选择部门。");
        return false;
    }
    // 这里的 'sys_user_select' 就是报表的编码
    popupClick2('sys_user_select', departId);
    return false;
});

function popupClick(pcode, departId) {
	// 该地址格式固定, 可以在后面添加参数如depart_id
    var url = "cgReportController.do?popup&id=" +pcode + "&depart_id="+departId;
    $.dialog({
        content: "url:"+url,
        zIndex: getzIndex(),
        lock : true,
        title:$.i18n.prop('common.select'),
        width:800,
        height: 400,
        parent:windowapi,
        cache:false,
        // 定义弹窗中确认按钮的事件
        ok: function() {
        	// 获取弹窗中选择的行
            iframe = this.iframe.contentWindow;
            var selected = iframe.getSelectRows();
            if (selected == '' || selected == null ){
                alert($.i18n.prop('common.select.please'));
                return false;
            }

            // 获取当前所以行的关联ID
            var rows = myAppendGrid.getAllValue();
            var cascadeIds = "";
            if (!isEmpty(rows)) {
                for (var i = 0; i < rows.length; i++) {
                    cascadeIds += rows[i]["cascadeId"] + ",";
                }
            }

			// 本来到这里就差不多了, 可以拿到选择到的行的所有信息, 可以根据自己的需要写回页面
			// 下面这些是结合 AppendGrid 动态添加行的代码, 如果没有用到可以忽略
            var isSelected = false;
            $.each(selected, function(i, n) {
                if (cascadeIds.indexOf(n['request_detail_id']) !== -1) {
                    isSelected = true;
                }
            });

            if (isSelected) {
                tip("该人员已存在,请重新选择");
            } else {
                detailList = [];
                $.each( selected, function(i, n) {
                    if (isEmpty(parseInt(n['name']))) {
                        tip("数据问题");
                        return true;
                    }
                    var dataMap = {};
                    dataMap.id = "";
                    dataMap.cascadeId = n['request_detail_id'];
                    dataMap.name = n['name'];
                    dataMap.age = n['age'];
                    dataMap.phone = n['phone'];
                    dataMap.address = n['address'];
                    dataMap.sex = n['sex'];
                    detailList.push(dataMap);
                });

                myAppendGrid.appendRow(detailList);
            }
            return true;
        },
        cancelVal: $.i18n.prop('dialog.close'),
        cancel: true
    });
}

到这里就已经完成了一个基本的报表配置和使用了。

用户选择框:UserSelectTag

1. 效果图

点击标签后弹出用户选择弹窗,该弹窗数据来源 t_s_user
在这里插入图片描述

2. 实现代码

在使用时需要先引入JEECG自定义标签:

<%@ taglib prefix="t" uri="/easyui-tags"%>
<div class="col-xs-1 bt-label required-img">审核:</div>
<div class="col-xs-2 bt-content">
	 <!-- 标签各属性说明在 easyui.tld 中都有备注 -->
     <t:userSelect title="审核选择" datatype="*"
                   selectedNamesInputId="auditByName"
                   selectedIdsInputId="auditBy"
                   userNamesDefalutVal="${auditByName}"
                   userIdsDefalutVal="${auditBy}"
                   windowWidth="1000px" windowHeight="600px" />
 </div>

3. 标签内部实现

这是JEECG自定义的标签,如下图:
在这里插入图片描述
对应的处理该标签的Java类是<tag-class>标签中的UserSelectTag类,该类继承了JSP包中的TagSupport类,并重写了父类的方法。在doEndTag()中将end()组装的页面进行输出,该页面作用是弹窗,定义「确定」按钮绑定的事件
在这里插入图片描述
这里还有一个userUrl参数, 通过它就可以获取弹窗内显示的具体内容, 也就是人员选择页面。

导出Excel: @Excel注解

JEECG框架导入导出表格主要是通过@Excel注解来完成的, 注解作用在属性上, 这里说下具体使用步骤。

1. 前端代码

前端部分主要就是写一个导出按钮, 有两种写法:

<!-- 写法一: 使用easyui样式生成按钮 -->
<div id="storageOutListtb2" style="padding: 3px; height: 25px">
    <div style="float: left;">
        <a href="#" class="easyui-linkbutton" plain="true" icon="icon-putout"
           onclick="ExportXls('storageStoreController.do?exportXls', 'storageStoreList','id')">导出</a>
    </div>
</div>

<!-- 写法二: 使用dgToolBar标签生成导出按钮 -->
<t:datagrid name="storagePlanList" checkbox="true" ...>
            <t:dgCol title="主键" field="id" hidden="true" queryMode="single" width="120" />
            <t:dgCol title="单据号" field="formNo" queryMode="single" query="true" width="120" />
            ...
            <t:dgToolBar title="导出" icon="icon-putout" onclick="\"masterExport('storageStoreController.do?exportXls', 'storageStoreList', 'id');\"" funname="ExportXls" />
        </t:datagrid>

生成的按钮如图:
在这里插入图片描述
两种方法中的onclick绑定了两种方法, 它们的实现都代码基本一致, 在common.js中; 方法都需要有三个入参, 第一个入参是进行导出处理的URL, 第二个参数是datagrid列表的name属性值, 第三个参数是传递到后端的参数名。

2. 后端代码

后端代码主要分三步:

  • 对需要导出的字段使用@Excel进行注解
  • 查询需要导出的数据
  • 将Excel表格的信息组装并导出

接下来使用一个完整的例子来说明, 首先是对需要导出的字段添加@Excel注解:

public class SysUser implements Serializable {
    /**id*/
    private String id;
    /**登录账号 */
    @Excel(name = "登录账号", width = 15)
    private String username;
    /**真实姓名*/
    @Excel(name = "真实姓名", width = 15)
    private String realname;
    /**生日*/
    @Excel(name = "生日", width = 15, format = "yyyy-MM-dd")
    private Date birthday;
    /**性别(1:男 2:女)*/
    @Excel(name = "性别", width = 15,dicCode="sex")
    private Integer sex;
    /**状态(1:正常  2:冻结 )*/
    @Excel(name = "状态", width = 15,replace={"正常_1","冻结_0"})
    private Integer status;

	// 忽略getter、setter方法
}

不需要导出的不用加注解,注解的各个属性说明可以参照JEECG Excel注解说明

接着在service层查询需要导出的数据, 可以直接使用SQL进行查询或者JEECG统一的datagrid()查询:

/**
 * 入参说明参考下面第三点里的代码便知
 */
public void datagrid(SysUser user, Map<String, String[]> parameterMap, DataGrid dataGrid) {
        CriteriaQuery cq = new CriteriaQuery(SysUser.class, dataGrid);
        //查询条件组装器
        org.jeecgframework.core.extend.hqlsearch.HqlGenerateUtil.installHql(cq, SysUser, parameterMap);
        try {
            //自定义追加查询条件
            String birthday= StringUtil.getRequestParamValue(parameterMap, "birthday");

            cq.createAlias("sysUser", "sysUser");
            if (StringUtils.isNotBlank(birthday)) {
                cq.ge("sysUser.birthday", DateUtils.parseDate(birthday, "yyyy-MM-dd"));
            }
            cq.add();
        } catch (Exception e) {
            throw new BusinessException(e.getMessage());
        }
        cq.add();

        this.getDataGridReturn(cq, true);
    }

最后在controller层将所有数据组装起来:

	/**
     * 导出Excel
     */
    @RequestMapping(params = "exportXls")
    public String exportXls(SysUser user, HttpServletRequest request, DataGrid dataGrid, ModelMap map) {
    	// 1. 查询数据, 对象的属性必须带有 @Excel 注解, 否则无法导出
        userService.datagrid(user, request.getParameterMap(), dataGrid);
        List<SysUser> dataList = dataGrid.getResults();
        
		// 2. 将基本信息组装起来
        String format = org.apache.tools.ant.util.DateUtils.format(currentTimeMillis(), "yyyy-MM-dd");
        map.put(NormalExcelConstants.FILE_NAME, "用户表"+format);
        // 要导出的对象类信息
        map.put(NormalExcelConstants.CLASS, SysUser.class);
        String tableName = "用户表";
        map.put(NormalExcelConstants.PARAMS, new ExportParams(tableName, "导出人:" + ResourceUtil.getSessionUser().getUserName(),
                "导出信息"));
        map.put(NormalExcelConstants.DATA_LIST, dataList);

		// 3. 跳转导出
        return NormalExcelConstants.JEECG_EXCEL_VIEW;
    }

不能将Map<Object, Object>类型作为数据来导出, 因为缺少@Excel注解, 框架无法解析

持久层注解: MiniDao

用来注解Dao层接口的自定义注解, 如
在这里插入图片描述
该注解对应的注解处理器是MiniDaoHandler.java, 被注解所标注接口中的方法如果有加@Sql注解则查询用的SQL语句就在其属性中, 若只有@ResultType注解, 则需要创建一个名字为接口名_方法名.sql的SQL文件, 如:
在这里插入图片描述
这里有一个getDepartAuthGroupList()方法, 则它所对应的文件是DepartAuthGroupDao_getDepartAuthGroupList.sql, 文件中只有简单的一句查询语句:
在这里插入图片描述

发布了14 篇原创文章 · 获赞 0 · 访问量 743

猜你喜欢

转载自blog.csdn.net/JasonWeng/article/details/104490643
今日推荐