• 一步一步学grails:5 分页查询


    资源在 此处 下载。

    1、  我们需要为产品编号设计一个动态组合查询,运行效果如下:

    点击确定后,以分页方式列出查询结果:

    点击下面的分页导航按钮可以进行翻页:

    2、  首先在list.gsp页面增加一个“查找产品编号”链接:

    需要注意,这个链接需要传递一个flag参数(随便什么值,只要不为空就行),这在后面的search控制器中用于区分是要显示查询页面还是呈现查询结果,这个技巧非常有用。

               <span class="menuButton"><g:link class="create" action="search" params="[flag:1]">查找生产编号</g:link></span>

     

    3、  productionNo控制器中添加search闭包,用于组合查询产品编号:

    打开grails-app/controllers/productionNoController.groovy:

    def search={

     

        def cooid=params['coo.id']

    //取参数:协作单位id

        if(params.flag==null){ 

    //取参数flag,flag为空则执行,当点击查找生产编号,会带有一个flag参数,则直接跳到render处执行

            def max=10        //每页显示记录数

     

            def offset        //每页偏移量

     

                def criteria=ProductionNo.createCriteria()

    //通过criteria接口动态查询

            offset=params.offset?params.offset.toInteger():0

    //若请求参数offset不为空,取请求参数

                def results=criteria{

    //执行criterial动态查询

                and{

    //and组合查询条件

                    if(cooid)eq('coo',CooperationUnit.get(cooid.toInteger()))

    //若请求参数coo.id不为空,查询条件中加上coo(该属性是一个协作单位对象,需通过id去数据库进行查找)

                   if(params.sno)eq('sno',params.sno.toInteger())

    //若请求参数sno不为空,查询条件中加上该月编号

                    if(params.prefix)like('prefix',params.prefix+'%')

    //若请求参数prefix不为空,查询条件中加上前缀

                   if(params.suffix)eq('suffix',params.suffix)

    //加上条件后缀

                   maxResults(max)      //仅取10条记录

     

                        firstResult(offset) //从排序后的偏移量开始取

     

                        order('id', 'asc')  //排序方式:升序

     

                }

     

            }

     

            def criteria1=ProductionNo.createCriteria()

    //另需一criteria接口

            def total=criteria1{

    //取得符合条件的记录的总条数

                and{

    //and组合查询条件

                    if(cooid)eq('coo',CooperationUnit.get(cooid.toInteger()))

    //同前

                   if(params.sno)eq('sno',params.sno.toInteger())

    //同前

                    if(params.prefix)like('prefix',params.prefix+'%')

    //同前

                   if(params.suffix)eq('suffix',params.suffix)

    //同前

                   projections{

    //返回hibernate投影list(属性集合)

                       rowCount()

    //总行数

                   }

     

                }

     

            }

     

            render(view:'list',model:[productionNoInstanceList:results,

    //使用指定的model渲染list视图,包括:查询的结果List

                productionNoInstanceTotal: total[0],offset:offset,

    //总行数(通过criteria返回的是一个list,我们只取第一个值)、偏移位置

                params:params] )

    //把上次请求参数也传过去(最重要的是把查询条件也传到翻页动作中去)

        }

     

        }

     

    4、  创建产品编号查询页面grails-app/views/productionNo/search.gsp:

    <g:formaction="search"method="post">

    //查询条件表单action=search

    ……

     

    <g:selectoptionKey="id"from="${CooperationUnit.list()}"name="coo.id"value="${productionNoInstance?.coo?.id}"></g:select>

    //查询条件1:协作单位

    ……

     

    <inputtype="text"id="prefix"name="prefix"/>

    //查询条件2:前缀,即年月份

    ……

     

    <inputtype="text"id="sno"name="sno"/>

    //查询条件3:当月序号

    ……

     

    <g:selectid="suffix"name="suffix"from="${['']+ProductionNo.constraints.suffix.inList}"></g:select>

    //查询条件4:后缀,并且通过集合加法在list前面加一空白选项

    ……

     

    <inputclass="button"type="submit"value="确定"/>

    //提交按钮

    ……

     

    </g:form>

     

    5、  创建查询结果页面grails-app/views/productionNo/lisg.gsp:

    <table>

     

    ……

     

    <tbody>

     

    <g:each in="${productionNoInstanceList}" status="i" var="productionNoInstance">

     

    <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">

     

    <td>${fieldValue(bean:productionNoInstance, field:'id')}</td>

    //显示id

    <td><g:link action="show" id="${productionNoInstance.id}">${productionNoInstance}</g:link></td>

    //显示产品编号,产品编号是一个对象,调用其定义的toString方法进行显示

    <td>${fieldValue(bean:productionNoInstance, field:'coo')}</td>

    //显示协作单位,也会调用其toString方法

    </tr>

     

    </g:each>

     

    </tbody>

     

    </table>

     

    ……

     

    <g:paginate total="${productionNoInstanceTotal}" params="${params}"/>

    //分页组件,total参数必须-总条数,params参数-指定了请求参数,包括查询条件、maxoffset

      ${productionNoInstanceTotal}

    //显示总条数

    ……

     

    6、  新建一个域类LoginUser

    class LoginUser {//域:登陆用户

        static constraints = {

    userId(length:6..8,unique:true)//帐号6-8

    password(length:6..8)//密码6-8

    name(nullable:false)//姓名不可为空

    level(range:1..10)//用户级别分10级,够了吧?

        }

        String userId//用户名

        String password//密码

        String name//用户姓名

        int level//用户权限级别

    }

     

    7、  为系统配置一个默认的系统管理员:

    打开grails-app/conf/BootStrap.groovy,编辑init闭包:

         def init = { servletContext ->

         final String BACK_ADMIN='admin'

         if(!LoginUser.findByUserId(BACK_ADMIN)){

         new LoginUser(userId:BACK_ADMIN,password:'admin88',name:'/u7BA1/u7406/u5458',level:10).save()

         }

         }

    这样,只要系统一启动,就会自动添加admin用户。

    8、  新建登陆页面:

    编辑grails-app/views/loginUser/login.gsp:

     

    <html>

        <head>

            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>

            <meta name="layout" content="main" />

            <title>系统登录</title>        

        </head>

        <body>       

            <div class="body" align="center">

                <h1>系统登录</h1>

                <g:if test="${flash.message}">

                <div class="message">${flash.message}</div>

                </g:if>

                <g:hasErrors bean="${loginUserInstance}">

                <div class="errors">

                    <g:renderErrors bean="${loginUserInstance}" as="list" />

                </div>

                </g:hasErrors>

                <g:form controller="loginUser" method="post" >

                    <div class="dialog">

                        <table>

                            <tbody>

                           

                                <tr class="prop">

                                    <td valign="top" class="name">

                                        <label for="userId">用户名:</label>

                                    </td>

                                    <td valign="top" class="value ${hasErrors(bean:loginUserInstance,field:'userId','errors')}">

                                        <input type="text" id="userId" name="userId" value="${loginUserInstance?.userId}" maxlength="8"/>

                             </td>

                                </tr>

                           

                                <tr class="prop">

                                    <td valign="top" class="name">

                                        <label for="password">密码:</label>

                                    </td>

                                    <td valign="top" class="value ${hasErrors(bean:loginUserInstance,field:'password','errors')}">

                                        <input type="password" id="password" name="password" value="${loginUserInstance?.password}" maxlength="8"/>

                                    </td>

                                </tr>

                            </tbody>

                        </table>

                    </div>

                    <div class="buttons">

                        <span class="button"><g:actionSubmit value="登录" /></span>

                    </div>

                </g:form>

            </div>

        </body>

    </html>

     

    9、  loginuser控制器中定义登录/注销action

    打开grails-app/controllers/LoginUserController.groovy:

    def login={

        if(request.method=='GET'){//清除session

        session.userId=null

        session.level=null

        def loginUserInstance=new LoginUser()

        }else{

        def loginUserInstance=LoginUser.findByUserIdAndPassword(

        params.userId,params.password)

        if(loginUserInstance){//添加session

        session.userId=params.userId

        session.level=loginUserInstance.level

        switch(loginUserInstance.level){

        case 5..10:

        redirect(controller:'planning',action:'create_2')

        break

        case 2..4:

        redirect(controller:'planning',action:'edit')

        break

        case 1:

        redirect(controller:'planning',action:'list')

        break

        default:

        redirect(controller:'loginUser',action:'login')

        break

        }

        }else{//登录帐号或密码错误

        flash['message']='/u767B/u5F55/u5E10/u53F7/u6216/u5BC6/u7801/u9519/u8BEF'

        }

        }   

        }

        def logout={

        session.userId=null

        session.level=null

        flash['message']='/u6210/u529F/u9000/u51FA/u767B/u5F55' //成功退出登录

        redirect(controller:'loginUser',action:'login')//转向登录页

        }

    10、               

  • 相关阅读:
    iOS 后台定位
    关于烂代码的那些事
    APP上线前,如何做运营推广工作?
    iOS图片折叠效果:Layer的contentsRect属性和渐变层
    iOS中几种数据持久化方案:我要永远地记住你!
    iOS-CoreLocation:无论你在哪里,我都要找到你!
    轻松学习之 IMP指针的作用
    iOS之友盟错误统计解决
    文字渐变效果:图层中的mask属性
    如何坚持每周写一篇博客
  • 原文地址:https://www.cnblogs.com/encounter/p/2188553.html
Copyright © 2020-2023  润新知