SPED关于权限管理模块的开发

来源:互联网 发布:染发剂推荐 知乎 编辑:程序博客网 时间:2024/05/21 18:42

 SPED是一个强大的开发工具,SPED通过编写业务描述文档,根据文档构建业务系统。
       本文以用户资源权限为主,演示SPED快速神奇的开发过程。

需求分析
权限管理和用户操作记录是业务系统中常用的功能,本文以这些功能的开发实现为例介绍SPED开发过程。下面是本案例E-R图(实体关系图):

图1 E-R实体关系

    权限管理中涉及资源、角色、用户、用户组4个核心的实体类,其中,资源只能分配给角色,资源与角色之间是一个多对多的关系,然后通过将角色分配给用户或用户组,建立起用户与资源的分配关系。通常情况下,系统管理员会关心以下需求:

●新建用户、用户组、角色

●权限分配

●查询特定用户或用户组具有哪些角色

●查询特定用户或用户组可以访问哪些资源

●查询特定角色被分配给哪些用户或用户组

●查询特定资源可以被哪些用户或用户组访问

●查询特定资源被分配给哪些角色

●查询特定用户被划分到哪些用户组

●查询用户登录、访问情况


本文从开发者的视角出发,分为以下几个部分:

●实体类描述 案例中资源、用户、角色等JAVA实体类的SPED描述代码

●关系描述 实体之间的一对多、多对多等关系的SPED描述代码

●数据表描述创建数据表的SPED描述代码

●DAO实现描述 生成DAO相关程序的SPED描述代码

●开发实现和演示
    添加角色
    查询用户和用户组具有哪些角色
    查询角色被分配给了哪些用户和用户组
    查询资源分配给了哪些角色
    查询角色可以访问哪些资源
    查询用户登录信息

●SPED代码分析以注释方式详细解释本案例的SPED业务描述文档


实体类描述 实体设计可以使用SPED描述实现,也可以在集成开发环境(IDE)中实现,本文采用SPED描述。展开查看SPED实体类描述
package sped;
// 下面是关于实体类的SPED描述
bean {
  src = demo; // POJO源文件夹是工程下的demo目录
  pkg = com.admin; // POJO的package是com.admin
  User:用户实体类{
    pkg:.user; // User类的package是com.admin.user。
    fl:[
      id:int:编号:-1, // 用户编号类型int,初始值为-1
      name::用户姓名,
      userName::用户名,
      email::电子邮箱,
      pwd::登陆密码,
      mobilephone::手机号码,
      telephone::电话号码,
      portrait::用户头像,
      regTime::注册时间,
      activate::是否激活:N, // 初始值为N,Y表示已经激活,N表示没有激活
      activatedTime::激活时间,
      status::有效状态:Y,
    ];
  }
  Resource:资源实体类{
    pkg:.resource;
    fl:[
      id::资源编号,
      url::请求url,
      name::资源名称,
      actionClass:Class<?>:处理请求的类,
      method:java.lang.reflect.Method:处理请求的方法,
    ];
  }
  Role:角色实体类{
    pkg:.auth;
    fl:[id::编号,
      name::名称,
      status::有效状态:Y, // 初始值为Y,Y表示有效,N表示无效
    ];
  }
  UserGroup:用户组实体类{
    pkg:.auth;
    fl:[
      id::编号,
      name::名称,
      status::有效状态:Y, // 初始值为Y,Y表示有效,N表示无效
    ];
  }
  ResourceRoleMapping:角色与资源的映射{
    pkg:.auth;
    fl:[
      id::编号,
      resourceId::资源编号,
      roleId::角色编号,
    ];
  }
  RoleUserMapping:角色与用户的映射{
    pkg:.auth;
    fl:[
      id::编号,
      roleId::角色编号,
      userId::人员编号,
    ];
  }
  RoleGroupMapping:角色与组的映射{
    pkg:.auth;
    fl:[
      id::编号,
      roleId::角色编号,
      groupId::组编号,
    ];
  }
  GroupUserMapping:用户组与用户的映射{
    pkg:.auth;
    fl:[
      id::编号,
      groupId::组编号,
      userId::人员编号,
    ];
  }
  UserOperation:用户操作记录实体类{
    pkg:.record;
    fl:[
      id::记录编号,
      userId::用户编号:-1,
      userName::用户名,
      time::记录时间,
      host::用户IP,
      url::访问的URL,
      action::操作对象,
      actionState::操作结果或状态,
      sessionId::浏览器sessionid,
    ];
  }
  UserLogin:用户登录记录实体类{
    pkg:.record;  
    fl:[
      id::记录编号,
      userId::用户编号:-1,
      time::登陆时间,
      userName::用户名,
      host::用户IP地址,
    ];
  }
  UserDownload:用户下载记录实体类{
    pkg:.record;
    fl:[
      id::记录编号,
      userId::用户编号:-1,
      userName::用户名,
      time::下载时间:,
      fileName::下载文件,
    ];
  }
}

关系描述SPED关系描述实现实体与实体之间的关联关系,更详细的说明请看SPED代码分析
package sped;
mapping {
  // User和所有拥有userId属性的类存在一对多的关系,关系的主外属性分别是id和userId
  { fb:User;     tb:*; ff:id; tf:userId; } 
  // UserGroup和所有拥有groupId属性的类存在一对多的关系,关系的主外属性分别是id和groupId
  { fb:UserGroup;tb:*; ff:id; tf:groupId; }
  { fb:Role;     tb:*; ff:id; tf:roleId; }
  { fb:Resource; tb:*; ff:id; tf:resourceId; }
     // 下面是多对多关系描述
 // User和UserGroup存在多对多关系,mb:*,表示SPED从所有类中寻找拥有userId和groupId两个属性的类作为映射  
  { fb:User;     tb:UserGroup; ff:id; tf:id; mb:*; fm:userId-groupId;  }
 // User和Role存在多对多关系,mb:*,表示SPED从所有类中寻找拥有userId和roleId两个属性的类作为映射  
  { fb:User;     tb:Role;      ff:id; tf:id; mb:*; fm:userId-roleId;   }  
  { fb:UserGroup;tb:Role;      ff:id; tf:id; mb:*; fm:groupId-roleId;  }  
  { fb:Resource; tb:Role;      ff:id; tf:id; mb:*; fm:resourceId-roleId; }
}

数据表描述SPED数据表描述实现数据库构建,更详细的说明请看SPED代码分析
package sped;
db = sqlite; // 使用嵌入式数据库SQLite
ctm = %user%:demo_user_&name-l, // 类全名带user字样的POJO数据表为“demo_user_类名小写”,下同
      %resource%:demo_res_&name-l,
      %auth%:demo_auth_&name-l,
      %record%:demo_record_&name-l;
fcm = *(*c_&name-l); // 所有POJO的所有属性的字段名为“c_属性名小写”
cc = config.DemoUtil.getConnection();
igf = Resource:[method,actionClass];
table{
  psql = true// 是否打印创建数据表的SQL,缺省为true
  drop = true// 是否删除同名数据表,缺省为false
  *{ l:100; } // 所有字段长度为100
  id{ l:100; c:PRIMARY KEY; } // id的字段作为数据表的主键
  fileName,url{ l:2000; } // fileName和url的字段长度为2000
}

DAO描述SPED DAO描述实现DAO相关程序开发,更详细的说明请看SPED代码分析
package sped;
db = sqlite;
ctm = %user%:demo_user_&name-l, // 类全名带user字样的POJO数据表为“demo_user_类名小写”,下同
      %resource%:demo_res_&name-l,
      %auth%:demo_auth_&name-l,
      %record%:demo_record_&name-l;
fcm = *(*c_&name-l); // 所有POJO的所有属性的字段名为“c_属性名小写”
cover = true// 新的源代码是否覆盖旧的源代码,缺省为false
osf = demo; // Object Source Folder,POJO的源文件夹是demo
tsf = demo; // Generate To Source Folder,存放DAO相关程序的源文件夹也是demo
cc = config.DemoUtil.getConnection(); // JDBC数据库连接代码
igf = Resource:[method,actionClass]; // Ignore Field,忽略Resource中method和actionClass属性
dao {
  pkf = *id; // pkf变量,所有POJO的主键属性是id(没有id属性的POJO例外)。
  dft = com.admin.factory.DAOFactory; // dft变量,声明工厂类
  { md:c,p,i,bi,m,e; } // 每个POJO都生成代号为c、p、i、bi、m、e对应的DAO方法
  id{ md:ga,da,d,bu,u,f; } // 具有id属性的POJO都生成代号为ga、da、d、bu、u、f对应的DAO方法
  %Id{ md:g,ga,fp,fc; } // 具有属性名以Id结尾的属性的POJO都生成代号为g、ga、fp、fc对应的DAO方法
  status{ md:g; } // 具有status属性的POJO都生成代号为g对应的DAO方法
}

开发实现和演示
       将以上各个部分的SPED描述汇总到同一个文件中,如demo1.sped,然后将该文件放到项目的sped目录下,然后执行org.sped.YUNSOFT_ORG_RUN类中的main方法,如下图:

图2 执行SPED业务描述


       在SPED主窗口中选择需要执行的SPED描述文件,然后,点击“执行”,执行完后刷新项目(通常按F5刷新),将会得到如下图的结果:

图3 SPED执行结果


下面通过编写测试代码的方式对SPED开发的结果进行演示,测试代码如下:

package com.admin;
import java.util.ArrayList;
import java.util.List;
import com.admin.auth.Role;
import com.admin.auth.UserGroup;
import com.admin.resource.Resource;
import com.admin.user.User;
public class DemoTest {
  /**
   * 添加角色
   * @return boolean
   * @throws Exception
   
*/

  public boolean roleInsert() throws Exception{
    Role role = new Role();
    role.setId("r0001");
    role.setName("测试角色");
    role.setStatus("Y"); // Y表示角色有效
    return role.insert();
  }
  /**
   * 以角色为主,查询角色拥有哪些资源的访问权限
   * @param roleId 角色编号
   * @return Resource[]
   * @throws Exception
   
*/

  public Resource[] getResourcesByRole(String roleId) throws Exception{
    Role role = new Role();
    role.setId(roleId);
    return role.toResources();
  }
  /**
   * 以资源为主,查询资源被分配给哪些角色
   * @param resourceId 资源编号
   * @return Role[]
   * @throws Exception
   
*/

  public Role[] getRolesByResource(String resourceId) throws Exception{
    Resource resource = new Resource();
    resource.setId(resourceId);
    return resource.toRoles();
  }
  /**
   * 以用户为主,查询用户拥有的所有角色,
   * 这些角色包括与该用户相关的用户组拥有的角色。
   * @param userId 用户编号
   * @return Role[]
   * @throws Exception
   
*/

  public Role[] getRolesByUser(int userId) throws Exception{
    List<Role> list = new ArrayList<Role>();
    User user = new User();
    user.setId(userId);
    // 查询直接分配给用户的角色
    Role[] userRoles = user.toRoles();
    if(null != userRoles && userRoles.length > 0){
      int size = userRoles.length;
      for (int i = 0; i < size; i++) {
        list.add(userRoles[i]);
      }
    }
    // 查询用户所属的用户组
    UserGroup[] userGroups  = user.toUserGroups();
    if(null == userGroups || userGroups.length < 1){
      return list.toArray(new Role[list.size()]);
    }
    int size = userGroups.length;
    for (int i = 0; i < size; i++) {
      // 查询用户组拥有的角色
      Role[] groupRoles = userGroups[i].toRoles();
      if(null != groupRoles && groupRoles.length > 0){
        for (int j = 0; j < groupRoles.length; j++) {
          list.add(groupRoles[j]);
        }
      }
    }
    return list.toArray(new Role[list.size()]);
  }
  /**
   * 以角色为主,查询角色被分配给哪些用户,
   * 这些用户包括与该角色相关的用户组中存在的用户
   * @param roleId 角色编号
   * @return User[]
   * @throws Exception
   
*/

  public User[] getUsersByRole(String roleId) throws Exception{
    List<User> list = new ArrayList<User>();
    Role role = new Role();
    role.setId(roleId);
    // 查询资源被直接分配给哪些用户
    User[] roleUsers = role.toUsers();
    if(null != roleUsers && roleUsers.length > 0){
      int size = roleUsers.length;
      for (int i = 0; i < size; i++) {
        list.add(roleUsers[i]);
      }
    }
    // 查询资源被分配给哪些用户组
    UserGroup[] roleGroups  = role.toUserGroups();
    if(null == roleGroups || roleGroups.length < 1){
      return list.toArray(new User[list.size()]);
    }
    int size = roleGroups.length;
    for (int i = 0; i < size; i++) {
      // 查询用户组中存在哪些用户
      User[] groupUsers = roleGroups[i].toUsers();
      if(null != groupUsers && groupUsers.length > 0){
        for (int j = 0; j < groupUsers.length; j++) {
          list.add(groupUsers[j]);
        }
      }
    }
    return list.toArray(new User[list.size()]);
  }
  /**
   * 通过用户查询用户的所有登录日志
   * @param userId 用户编号
   * @return UserLogin[]
   * @throws Exception
   
*/

  public UserLogin[] getUserLoginsByUser(int userId) throws Exception{
    User user = new User();
    user.setId(userId);
    return user.toUserLogins();
  }
}

SPED代码分析

package sped;
  
/**
 * bean模块,用于定义JAVA业务实体类(POJO,下同)。
 * bean模块执行完后,bean模块中定义的所有POJO会自动导入到pojo变量(pojo容器)中,
 * bean模块不是必须的,POJO的定义可以在集成开发环境(IDE,如Eclipse)中进行,然后
 * 将在IDE中创建的POJO存放到pojo变量中,详情参见pojo变量
 * 
 * 
 * bean模块内部用到的主要变量:
 *    en变量:Enable,用于是否启用该模块,缺省为true,若为false则模块被忽略。
 *
 *   src变量:描述POJO存放的源文件夹,缺省为src,告诉bean模块将生成的POJO源代码存
 *           放到哪里,如src = demo。
 *
 *   pkg变量:描述POJO默认package,如“pkg = com.admin;”。
 *
 *   cmf变量:Class Modify,类修饰,描述所有类的默认修饰,缺省为public,
 *           如“cmf = public final;”,表示所有类将声明为final。
 *
 *   fmf变量:Field Modify,属性修饰,描述所有属性的默认修饰,缺省为private,
 *           如“fmf = public;”,表示所有属性被声明为可以被直接访问的public属性。
 *
 *   fdt变量:Field Default Type,属性默认类型,缺省为String,如“fdt = int;”,
 *           表示在定义POJO属性的时,当类型声明为空,那么该属性的类型为int。
 * 
 *
 * POJO定义方式:
 *     类名:类描述{ fl:[属性,....,属性]; }
 *   类名如果包含package(类全名,下同),那么pkg变量和pkg关键字都失效;
 *   类描述不是必须的,如果有类描述,将会生成类的注释;
 *   fl是FieldList(属性列表)的简写。
 *
 *
 * POJO定义中用到的主要关键字:
 *    fl关键字:Field List,属性列表。
 *
 *   src关键字:特别指定该POJO存放的源文件夹,src关键字将覆盖src变量。
 *
 *   pkg关键字:特别指定该POJO的package,如果src关键字以“.”开头,那么该POJO的package
 *             为pkg变量的值加上pkg关键字的值,否则,pkg关键字将覆盖pkg变量。
 *
 *   cmf关键字:特定指定该POJO修饰,cmf关键字将覆盖cmf变量。
 *
 *   fmf关键字:特定指定该POJO的属性的修饰,fmf关键字将覆盖fmf变量。
 *
 *   fdt关键字:特定指定该POJO的属性的默认类型,fdt关键字将覆盖fdt变量。
 *
 *
 * POJO属性定义方式:
 *     属性名:属性类型:属性描述:属性初始值
 *   属性类型声明在属性名后第一个“:”后面,若为空,属性类型为fdt关键字或fdt变量的值;
 *   属性描述不是必须的,出现在属性名后第二个“:”后面,将作为属性的注释;
 *   属性初始值出现在属性名后第三个“:”后面。
 *     
 */

bean {
  src = demo; // POJO源文件夹是工程下的demo目录
  pkg = com.admin; // POJO的package是com.admin
  User:用户实体类{
    pkg:.user; // User类的package是com.admin.user。
    fl:[
      id:int:编号:-1, // 用户编号类型int,初始值为-1
      name::用户姓名,
      userName::用户名,
      email::电子邮箱,
      pwd::登陆密码,
      mobilephone::手机号码,
      telephone::电话号码,
      portrait::用户头像,
      regTime::注册时间,
      activate::是否激活:N, // 初始值为N,Y表示已经激活,N表示没有激活
      activatedTime::激活时间,
      status::有效状态:Y,
    ];
  }
  Resource:资源实体类{
    pkg:.resource;
    fl:[
      id::资源编号,
      url::请求url,
      name::资源名称,
      actionClass:Class<?>:处理请求的类,
      method:java.lang.reflect.Method:处理请求的方法,
    ];
  }
  Role:角色实体类{
    pkg:.auth;
    fl:[id::编号,
      name::名称,
      status::有效状态:Y, // 初始值为Y,Y表示有效,N表示无效
    ];
  }
  UserGroup:用户组实体类{
    pkg:.auth;
    fl:[
      id::编号,
      name::名称,
      status::有效状态:Y, // 初始值为Y,Y表示有效,N表示无效
    ];
  }
  ResourceRoleMapping:角色与资源的映射{
    pkg:.auth;
    fl:[
      id::编号,
      resourceId::资源编号,
      roleId::角色编号,
    ];
  }
  RoleUserMapping:角色与用户的映射{
    pkg:.auth;
    fl:[
      id::编号,
      roleId::角色编号,
      userId::人员编号,
    ];
  }
  RoleGroupMapping:角色与组的映射{
    pkg:.auth;
    fl:[
      id::编号,
      roleId::角色编号,
      groupId::组编号,
    ];
  }
  GroupUserMapping:用户组与用户的映射{
    pkg:.auth;
    fl:[
      id::编号,
      groupId::组编号,
      userId::人员编号,
    ];
  }
  UserOperation:用户操作记录实体类{
    pkg:.record;
    fl:[
      id::记录编号,
      userId::用户编号:-1,
      userName::用户名,
      time::记录时间,
      host::用户IP,
      url::访问的URL,
      action::操作对象,
      actionState::操作结果或状态,
      sessionId::浏览器sessionid,
    ];
  }
  UserLogin:用户登录记录实体类{
    pkg:.record;  
    fl:[
      id::记录编号,
      userId::用户编号:-1,
      time::登陆时间,
      userName::用户名,
      host::用户IP地址,
    ];
  }
  UserDownload:用户下载记录实体类{
    pkg:.record;
    fl:[
      id::记录编号,
      userId::用户编号:-1,
      userName::用户名,
      time::下载时间:,
      fileName::下载文件,
    ];
  }
}
  
  
/**
 * mapping模块,描述POJO业务实体之间的关系。
 *
 * 一对多或多对一关系定义方式:
 *     fb:POJO; tb:POJO; ff:属性; tf:属性; }
 *   fb关键字:From Bean,关系的主POJO。
 *   tb关键字:To Bean,被关系的POJO。
 *   ff关键字:From Field,关系的主属性。
 *   tf关键字:To Field,被关系属性。
 *
 * 多对多关系定义方式:
 *     fb:POJO; tb:POJO; ff:属性; tf:属性; mb:映射实体类; fm:属性映射}
 *   fb关键字:From Bean,关系的主POJO。
 *   tb关键字:To Bean,被关系的POJO。
 *   ff关键字:From Field,关系的主属性。
 *   tf关键字:To Field,被关系属性。
 *   mb关键字:Mapping Bean,映射实体类。
 *   fm关键字:File Mapping,包含映射两个属性,用“-”隔开,如属性A-属性B,
 *            ff关键字代表的属性与属性A的关系属于主外键关系,tf关键字代
 *            表的属性与属性B的关系也属于主外键关系。属性A与属性B必须都
 *            属于映射实体类的属性。
 *     
 */

mapping {
  { fb:User;     tb:*; ff:id; tf:userId; }
  { fb:UserGroup;tb:*; ff:id; tf:groupId; }
  { fb:Role;     tb:*; ff:id; tf:roleId; }
  { fb:Resource; tb:*; ff:id; tf:resourceId; }
    
  { fb:User;     tb:UserGroup; ff:id; tf:id; mb:*; fm:userId-groupId;  }
    
  { fb:User;     tb:Role;      ff:id; tf:id; mb:*; fm:userId-roleId;   }
    
  { fb:UserGroup;tb:Role;      ff:id; tf:id; mb:*; fm:groupId-roleId;  }
    
  { fb:Resource; tb:Role;      ff:id; tf:id; mb:*; fm:resourceId-roleId; }
}
  
/**
 *
 * 以下变量主要用于table模块和dao模块,这些变量通常声明在模块之外。
 *
 *  pojo变量:POJO容器,告诉SPED所有模块的作用域是哪些POJO类,pojo变量值可以是类全名,
 *           代表一个确定的POJO,也可以是包名,代表该包下的所有POJO,
 *           如“pojo = com.admin.user.User,com.admin.record;”代表com.admin.user.User
 *           和com.admin.record包下的所有POJO类。
 *           当bean模块执行完后,bean模块中定义的所有POJO会自动导入到pojo变量中来。
 *
 *    db变量:DataBase,数据库,缺省为mysql,支持oracle、sqlite、sqlserver等主流数据库。
 *
 *   ins变量:Include Super,是否包含POJO父类的属性,缺省为false,当ins为true时,数据表
 *           和DAO方法会包括父类属性。
 *
 *   anp变量:Annotation Prior,注释优先,缺省为false,当anp为true,并且POJO中存在Table、
 *           Column等Annotation时,表名和字段名将会优先使用注释中的声明。
 *
 *   igf变量:Ignore Field,被忽略的属性,有些POJO的属性不会作为数据表的字段,igf的作用就
 *           是忽略这些字段。
 *
 *   fcm变量:Field Column Mapping,属性和数据表字段名的映射,缺省为*(*C_&name-u),即所
 *           有类的所有属性对应的数据表字段名为“C_属性名大写”。
 *
 *   ctm变量:Class Table Mapping,POJO和数据表名的映射,缺省为*T_&name-u,即所有的类的
 *           数据表名为“T_类名大写”。
 *
 *   osf变量:Object Source Folder,POJO的源文件夹,缺省为项目下的src目录。osf的值应当与
 *           bean模块中的src变量的值保持一致,bean模块中的src作用是告诉生成的POJO代码应当
 *           放到哪里,而osf是告诉dao模块在哪里可以找到POJO的源文件。
 *
 *   tsf变量:Generate To Source Folder,存放DAO,Proxy等源文件夹,缺省为项目下的src目录。
 *           告诉dao模块将生成的DAO,Proxy等源代码放到哪里。
 *
 *   gpx变量:Generate Proxy,是否生成DAO代理,缺省为true。
 *
 *   gif变量:Generate Interface,是否生成DAO接口,缺省值为true,gif的值会参考gpx值,若gpx
 *           变量为true,那么gif无论怎么设置都是为true,因为SPED DAO采用接口方式实现代理,
 *           这是代理模式的最佳实践。
 *
 *   owb变量:Object Write Back,是否可以将代码回写到POJO中,缺省为true,在没有特殊情况下,
 *           SPED强烈建议该值为true。 
 *
 *    cc变量:Connection Code,数据库连接(Connection)代码,table模块用该代码建立JDBC连接,
 *           创建数据表,dao模块用该代码作为DAO的Connection。
 *
 *   mod变量:Model,DAO方法的参数模式,缺省为2,mod = 1,DAO方法带有在执行完后是否关闭的
 *           Connection的询问参数close,mod = 2,DAO方法执行完将清理数据集并立即关闭
 *           Connection,mod = 3与mod = 2相似,只是DAO中没有setConnection方法,mod = 4,则
 *           将Connection和close都作为DAO方法的参数。
 *
 * 
 */

db = sqlite; // 使用嵌入式数据库SQLite
ctm = %user%:demo_user_&name-l, // 类全名带user字样的POJO数据表为“demo_user_类名小写”,下同
      %resource%:demo_res_&name-l,
      %auth%:demo_auth_&name-l,
      %record%:demo_record_&name-l;
fcm = *(*c_&name-l); // 所有POJO的所有属性的字段名为“c_属性名小写”
cover = true// 新的源代码是否覆盖旧的源代码,缺省为false
osf = demo;
tsf = demo;
cc = config.DemoUtil.getConnection();
igf = Resource:[method,actionClass];
  
  
/**
 * table模块,数据库数据字典描述,用于创建POJO对应的数据表。
 *
 * table声明的主要方式为:
 *     属性{ l:长度; c:字段约束; obj:POJO作用域;}
 *   l关键字:Length,属性对应字段长度,对需要进行长度设置的字段有效。
 *   c关键字:Constraint,字段约束,如c:PRIMARY KEY NOT NULL。
 * obj关键字:POJO Object,POJO作用域,表示只针对哪些POJO,obj关键字也可以用于其他模块。
 *     
 */

table{
  psql = true// 是否打印创建数据表的SQL,缺省为true
  drop = true// 是否删除同名数据表,缺省为false
  *{ l:100; } // 所有字段长度为100
  id{ l:100; c:PRIMARY KEY; } // id的字段作为数据表的主键
  fileName,url{ l:2000; } // fileName和url的字段长度为2000
}

  
/**
 *
 * dao模块,生成POJO相关的JDBC程序,包括DAO接口,DAO实现,DAO代理,DAO工厂等。
 * 
 * DAO方法描述方式:
 *     属性{ md:方法代号; }
 *
 * 
 * DAO方法声明用到的主要关键字:
 *    md关键字:Method,DAO方法代号,详情参见下面DAO方法代号。
 *
 *    ct关键字:Combination Type,属性的组合方式,分别为s(single)和m(multiplex),m表
 *             示DAO方法描述头部的属性形成组合参数生成一个DAO方法,
 *             如[userName,password]{ md:f; ct:m; },
 *             这个描述将会生成findComByUserNamePassword方法,常用于根据用户名和密码
 *             进行登陆的DAO方法。
 *
 *   obc关键字:Order By Config,描述查询DAO方法中SQL语句的order by。
 *    mt关键字:Match Type,SQL语句中字段与值的关系,缺省为“=”,mt关键字设置成“>”、
 *             “<”、“!=”、“like”或者它们的组合。
 *   
 *   rel关键字:Relationship,SQL语句where条件的字段与字段之间的关系,缺省为AND,rel关键字
 *             可以设置成“OR”或者“AND”和“OR”的组合。
 *  注意:SPED不推荐使用mt、rel、obc关键字,因为使用这些关键字会降低DAO方法的通用性。
 * 
 *
 * dao模块内部用到的主要变量:
 *    en变量:Enable,用于是否启用该模块,缺省为true,若为false则模块被忽略。
 *   dft变量:Dao Factory,Dao工厂类全名,若该类不存在,SPED根据dft变量自动创建该类,若存在,
 *            SPED将新的工厂方法代码追加到该类的源文件中。
 *
 *   pkf变量:Primary Key Field,主键属性,指定POJO中的主键属性,pkf声明的属性用于POJO根据
 *            主键的增、删、改、查,某些不能很好地支持分页查询数据库中,用pkf声明的变量做
 *            分页查询,如SQL Server。
 *
 * DAO方法代号:
 *   f方法:Find,查询并返回单一POJO对象,一般用于通过主键或联合主键查询的DAO方法,
 *          如public User findById(int id)。
 *
 *   g方法:Get,查询并返回POJO的数组对象,如public UserAction[] getByUserId(int userId)。
 *
 * all方法:Get All,并返回POJO的所有对象,如public User[] getAll()。
 *  ga方法:Get By Array,通过数组作为参数,查询满足条件的所有对象,
 *          如public User[] getById(int[] ids)。
 *
 *   d方法:Delete,删除POJO对象数据,如public boolean deleteById(int id)。
 *
 *  da方法:Delete By Array,以数组作为参数,删除满足条件的所有POJO数据,
 *          如public boolean deleteById(int[] ids)。
 *
 *   u方法:Update,以一个POJO对象作为参数,并根据该POJO对象的某些属性值作为条件进行更新,
 *          如public boolean updateById(User user)。
 *
 *  bu方法:Batch Update,批量更新,以POJO对象数组作为参数,根据POJO对象的某些属性值作为条件,
 *          对数组中的每个POJO对象进行数据更新,如public boolean updateById(User[] users)。
 *
 *  fc方法:Count By Field,用POJO某些属性值作为参数,查询返回满足条件的数据记录数,
 *          如public int countByStatus(String status)。
 *
 *   c方法:Count,获取POJO数据的总记录数,如public int count()。
 *
 *   i方法:Insert,将一个POJO对象数据保存到数据库,如public boolean insert(User user)。
 *
 *  bi方法:Batch Insert,批量保存,将POJO数组对象数据保存到数据库,
 *          如public boolean insert(User[] users)。
 *
 *  si方法:Step Insert,分步提交的方式批量保存POJO数组数据,适用于大数据量的保存,
 *          如public boolean insert(User[] users, int stepCount)。
 *
 *  ji方法:JSON Insert,将JSON保存到数据库,如public boolean insert(String userJSON)。
 *
 * jsi方法:JSON Step Insert,分步提交的方式批量保存JSON到数据库,
 *          如public boolean insert(String userJSON, int stepCount)。
 *
 *   e方法:Execute,执行没有数据集返回的SQL语句,如public boolean execute(String sql)。
 *
 * sql方法:Get Execute SQL,执行有数据集返回的SQL,如public User[] getSQL(String sql);
 *
 *   m方法:Get To Map,执行SQL语句,若有数据集返回,将动态解析数据集,将解析到的数据存放到
 *          List<Map<String, Object>>对象中,该方法适用于任意的自定义SQL,
 *          如public List<Map<String, Object>> getToMap(String sql)。
 *
 *  fp方法:Paging By Field,根据某些属性进行分页查询,
 *          如public User[] pagingByStatus(String status, int pageSize, int pageIndex)。
 *
 *   p方法:Paging,分页查询POJO所有数据,public User[] paging(int pageSize, int pageIndex)。
 *        
 *      
 */
  
dao {
  pkf = *id; // pkf变量,所有POJO的主键属性是id(没有id属性的POJO例外)。
  dft = com.admin.factory.DAOFactory; // dft变量,声明工厂类
  { md:c,p,i,bi,m,e; } // 每个POJO都生成代号为c、p、i、bi、m、e对应的DAO方法
  id{ md:ga,da,d,bu,u,f; } // 具有id属性的POJO都生成代号为ga、da、d、bu、u、f对应的DAO方法
  %Id{ md:g,ga,fp,fc; } // 具有属性名以Id结尾的属性的POJO都生成代号为g、ga、fp、fc对应的DAO方法
  status{ md:g; } // 具有status属性的POJO都生成代号为g对应的DAO方法
}

 

0 0