如何定义一个Student表,包含姓名、年级、班级等数据?用枚举类可以写得一目了然!代码如下:enum Student {
    Name(Type.CHAR, 3),
    Grade(Type.NUMBER, 2),
    Class(Type.NUMBER, 2), 
    Lesson(Type.VARCHAR, 12),
    Score(Type.NUMBER, 2), ;    Type type;
    int length;    Student(Type _type, int _length) {
        type = _type;
        length = _length;
    }
}
其中的数据类型可以再定义一个枚举类:enum Type {
    CHAR, VARCHAR, NUMBER, SMALLINT;
}接着就是本文的重点了,生成SQL语句:public class NewTest {
    public static void main(String[] args) {
        String sql = "CREATE TABLE " + Student.class.getName() + "{\n";
        for (Student s : Student.values()) {
            sql += "\t" + s + " ";
            sql += s.type;
            sql += "(" + s.length + "),\n";
        }
        sql += "}";
        System.out.println(sql);
    }
}运行结果:
CREATE TABLE Student{
    Name CHAR(3),
    Grade NUMBER(2),
    Class NUMBER(2),
    Lesson VARCHAR(12),
    Score NUMBER(2),
}可以看出生成的CREATE最后多一个空格,我们可以进一步完善。
这里只是抛砖引玉,其实我们可以如法炮制,生成Insert,update等语句。还可以通过这样的方法我们可以自己写一个简单的类似ORM的框架。

解决方案 »

  1.   

    支持J王,我也写过类似的东东,用枚举果然更加强大清晰,期待J王的ORM框架。
      

  2.   

    我也实现过,并且还实现了内存对象用sql语句查询和一些不同数据库版本的字段类型和sql语句的匹配等,现在在考虑通过io操作动态异步更新库表结构,以及优化这种形式的内存记录集的索引。
      

  3.   

    支持,但是为啥ORM都是针对数据库表的呢?
    我觉得针对大型项目应该更进一步,把项目从这个层面分为两层,一边负责UI,一边负责业务模型的提供,UI组的开发不能直接接触数据库表,甚至连这个表在java中的映射也不能操作,只能调用封装出来的API。
    尤其对于银行业务,UI组得到一个API,做业务开发的时候先根据卡号,客户号,证件号之类的线索获取到一个客户对象,这个客户对象是个树型结构,依次可以迭代所有卡片,账户,交易等等,至于他们之间的关联和逻辑由业务模型组完成,UI组只需要拿来用。
    客户对象不仅仅操作表,更主要的是和银行后端纷繁复杂的交易接口前置对接,把这些进行ORM映射,实施cache,集群负载,统一接口方式。
    从另外一个角度来说,业务模型组的成果可以被这个银行的多个项目组共享,管理上,业务模型的开发独立成一个项目,业务模型从客户对象开始,很多访问可以被cache,整体业务规则一致,避免两个业务系统在同一个业务流程上执行了不同的业务规则。哎,,,上来发发牢骚,项目的利润空间太小了,被业务压的闯不过气来,根本没办法实施这个想法!
      

  4.   

    想法很好!这样定义UI控件也可以啊,只是UI层和持久层之间还有个业务层比较难处理。
      

  5.   

    这样何苦?用注解很容易实现,而且来的方便。你只需要对需要的对象的属性做注解,并且用反射解析出注解生成SQL会更好。不过也顶一下吧
      

  6.   

    看不出你这个有什么优势,劣势倒有一大堆!建议使用楼上的方法,使用 Annotation
      

  7.   


    看过了,那只是一套标准而已,要庞大的容器支持,这个只用Java 5自带的特性解决一些小范围的问题。
      

  8.   

    在下只对技术感兴趣,用注解写是挺方便。不过反射的太多了,速度真有点……public class NewTest {
    public static void main(String[] args) {
    System.out.println(getSql());
    } static String getSql() {
    StringBuilder sql = new StringBuilder();
    Student2 s = new Student2(); try {
    sql.append("CREATE TABLE " + Student2.class.getName() + "(\n");
    for (Field f : Student2.class.getDeclaredFields()) {
    sql.append('\t');
    sql.append(f.getName());
    sql.append(' ');
    sql.append(f.get(s)); MyAnnotation an = f.getAnnotation(MyAnnotation.class); if (an.num() > 0) {
    sql.append('(');
    sql.append(an.num());
    sql.append(')');
    } if (an.isPrimaryKey())
    sql.append(" PRIMARY KEY");
    else {
    sql.append(an.canNull() ? "" : " NOT");
    sql.append(" NULL");
    }
    sql.append(",\n"); }
    } catch (IllegalArgumentException ex) {
    ex.printStackTrace();
    } catch (IllegalAccessException ex) {
    ex.printStackTrace();
    }
    sql.append(')'); return (sql.toString());
    }
    }@Retention(RetentionPolicy.RUNTIME)
    @interface MyAnnotation {
    int num() default 0; boolean isPrimaryKey() default false; boolean canNull() default true;
    }class Student2 {
    @MyAnnotation(isPrimaryKey = true)
    String ID = "INT"; @MyAnnotation(num = 3, canNull = false)
    String Name = "CHAR"; @MyAnnotation(num = 2, canNull = false)
    String Grade = "NUMBER"; @MyAnnotation(num = 2, canNull = false)
    String Class = "NUMBER"; @MyAnnotation(num = 12)
    String Lesson = "VARCHAR"; @MyAnnotation(num = 2)
    String Score = "NUMBER";
    }
      

  9.   

    又见极品,java之王。PS下:(king_of_dotnet)点耐特之王,是他的小号,自问自答自顶,这样的无耻作风,佩服!
      

  10.   

    正好自己刚刚自学完枚举。
    按照楼主的方法,自己练习了一下。写了insert,delete,update方法package com.sun.demo;public class Test { /**
     * @param args
     */
    public static void main(String[] args) {
    // 定义className变量取得Student类名
    String className = Student.class.getName();
    className = className.substring(className.lastIndexOf(".")+1);
    System.out.println(create(className));
    System.out.println(insert(className,"张三",98,"初一二班"));
    System.out.println(update(className,"张三",98,"初一二班"));
    System.out.println(delete(className,"张三"));
    }
    //创建student表,字段是name,score,class
    public static String create(String className){
    String sql = "create table " + className+"{\n";
    for(Student s:Student.values()){
    sql += s.name()+" "+s.type+"("+s.len+"),\n";
    }
    sql +="}";
    return sql;
    }
    //向student表插入数据
    public static String insert(String className,String name,int score,String c){
    String sql = "insert into " + className+" (";
    for(Student s:Student.values()){
    sql += s.name()+",";
    }
    sql = sql.substring(0,sql.length()-1);
    sql += ") valuse("+name+","+score+","+c;
    sql += ");";
    return sql;
    }

    //按照班级修改学生姓名和成绩
    public static String update(String className,String name,int score,String c){
    String sql = "update " + className+" set(";
    sql += Student.Name +"='" + name +"',";
    sql += Student.Score +"='" + score +"'";
    sql += " where "+Student.Class+"='"+c+"');";
    return sql;
    }

    //按照名字删除学生信息
    public static String delete(String className,String name){
    String sql = "delete " + className+" where ";
    sql += Student.Name +"='" +name+"'";
    return sql;
    }
    }运行结果:create table Student{
    Name CHAR(2),
    Score NUMBER(2),
    Class CHAR(5),
    }
    insert into Student (Name,Score,Class) valuse(张三,98,初一二班);
    update Student set(Name='张三',Score='98' where Class='初一二班');
    delete Student where Name='张三'自己偷了一下懒,自己的Student枚举类没定义那么多package com.sun.demo;public enum Student {
    Name(Type.CHAR,2),Score(Type.NUMBER,2),Class(Type.CHAR,5);
    private Student(Type _type,int length){
    this.type = _type;
    this.len = length;
    }
    Type type;
    int len;
    }
    自己在练习中发现,如果定义了包。反射出来的类名是com.sun.demo.Student
    所以得处理一下才行
    总之,楼主让我看了眼界,又温习了一下枚举。
      

  11.   

    insert方法忘了加引号了。。补一下
    package com.sun.demo;public class Test { /**
     * @param args
     */
    public static void main(String[] args) {
    // 定义className变量取得Student类名
    String className = Student.class.getName();
    className = className.substring(className.lastIndexOf(".")+1);
    System.out.println(create(className));
    System.out.println(insert(className,"张三",98,"初一二班"));
    System.out.println(update(className,"张三",98,"初一二班"));
    System.out.println(delete(className,"张三"));
    }
    //创建student表,字段是name,score,class
    public static String create(String className){
    String sql = "create table " + className+"{\n";
    for(Student s:Student.values()){
    sql += s.name()+" "+s.type+"("+s.len+"),\n";
    }
    sql +="}";
    return sql;
    }
    //向student表插入数据
    public static String insert(String className,String name,int score,String c){
    String sql = "insert into " + className+" (";
    for(Student s:Student.values()){
    sql += s.name()+",";
    }
    sql = sql.substring(0,sql.length()-1);
    sql += ") valuse('"+name+"','"+score+"','"+c+"'";
    sql += ");";
    return sql;
    }

    //按照班级修改学生姓名和成绩
    public static String update(String className,String name,int score,String c){
    String sql = "update " + className+" set(";
    sql += Student.Name +"='" + name +"',";
    sql += Student.Score +"='" + score +"'";
    sql += " where "+Student.Class+"='"+c+"');";
    return sql;
    }

    //按照名字删除学生信息
    public static String delete(String className,String name){
    String sql = "delete " + className+" where ";
    sql += Student.Name +"='" +name+"'";
    return sql;
    }
    }create table Student{
    Name CHAR(2),
    Score NUMBER(2),
    Class CHAR(5),
    }
    insert into Student (Name,Score,Class) valuse('张三','98','初一二班');
    update Student set(Name='张三',Score='98' where Class='初一二班');
    delete Student where Name='张三'
      

  12.   

    支持一下,我是从C#版的链接跳过来的。
    PS:为什么你们的sql语句是大括号create table Student{},难道有了新的标准?
      

  13.   


    所以说还得动手做看了半天一直到你这楼才提到楼主代码里的 class name 问题
    // Student.class.getName()改成Student.class.getSimpleName()
      

  14.   

    稍微改了一下,通用于所有实现了 Field 接口的 enum 类型:
    public interface Field {
      
      public Type getType();
      
      public int getLength();
    }public enum Type {
      
      CHAR,
      VARCHAR,
      NUMBER,
      SMALLINT,
      ;
    }public enum Student implements Field {  Name  (Type.CHAR, 3),
      Grade (Type.NUMBER, 2),
      Class (Type.NUMBER, 2), 
      Lesson (Type.VARCHAR, 12),
      Score (Type.NUMBER, 2), 
      ;  private final Type type;
      private final int length;
      
      Student(Type type, int length) {
        
        this.type = type;
        this.length = length;
      }
      
      @Override
      public Type getType() {
        
        return type;
      }  @Override
      public int getLength() {
        
        return length;
      }
    }public class SQLGen {
      
      public static void main(String[] args) {
        
        System.out.println(createTable(Student.class));
      }
      
      public static <E extends Enum & Field> String createTable(Class<E> type) {
        
        if( type == null )
          throw new NullPointerException();
        
        StringBuilder builder = new StringBuilder();
        
        builder.append("CREATE TABLE ")
               .append(type.getSimpleName())
               .append("{\n");
        for(E field : Arrays.asList(type.getEnumConstants())) {
        
          builder.append("\t").append(field).append(" ")
                 .append(field.getType()).append("(")
                 .append(field.getLength()).append("),\n");
        }
        
        return builder.append("}").toString();
      }
    }
    run:
    CREATE TABLE Student{
    Name CHAR(3),
    Grade NUMBER(2),
    Class NUMBER(2),
    Lesson VARCHAR(12),
    Score NUMBER(2),
    }
    BUILD SUCCESSFUL (total time: 0 seconds)