<原创>用Java枚举类定义表,并且生成查询语句。
如何定义一个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的框架。 --------------------编程问答-------------------- 送分都没人要? --------------------编程问答-------------------- 接分,平时写代码我最喜欢用枚举了,能让代码清晰很多 --------------------编程问答-------------------- --------------------编程问答-------------------- --------------------编程问答-------------------- 支持J王,我也写过类似的东东,用枚举果然更加强大清晰,期待J王的ORM框架。 --------------------编程问答-------------------- 我也实现过,并且还实现了内存对象用sql语句查询和一些不同数据库版本的字段类型和sql语句的匹配等,现在在考虑通过io操作动态异步更新库表结构,以及优化这种形式的内存记录集的索引。 --------------------编程问答-------------------- 支持,但是为啥ORM都是针对数据库表的呢?
我觉得针对大型项目应该更进一步,把项目从这个层面分为两层,一边负责UI,一边负责业务模型的提供,UI组的开发不能直接接触数据库表,甚至连这个表在java中的映射也不能操作,只能调用封装出来的API。
尤其对于银行业务,UI组得到一个API,做业务开发的时候先根据卡号,客户号,证件号之类的线索获取到一个客户对象,这个客户对象是个树型结构,依次可以迭代所有卡片,账户,交易等等,至于他们之间的关联和逻辑由业务模型组完成,UI组只需要拿来用。
客户对象不仅仅操作表,更主要的是和银行后端纷繁复杂的交易接口前置对接,把这些进行ORM映射,实施cache,集群负载,统一接口方式。
从另外一个角度来说,业务模型组的成果可以被这个银行的多个项目组共享,管理上,业务模型的开发独立成一个项目,业务模型从客户对象开始,很多访问可以被cache,整体业务规则一致,避免两个业务系统在同一个业务流程上执行了不同的业务规则。
哎,,,上来发发牢骚,项目的利润空间太小了,被业务压的闯不过气来,根本没办法实施这个想法! --------------------编程问答-------------------- 这应该写到博客里。。。 --------------------编程问答-------------------- --------------------编程问答--------------------
想法很好!
这样定义UI控件也可以啊,只是UI层和持久层之间还有个业务层比较难处理。 --------------------编程问答-------------------- 挺好,勋章哥,你好~ --------------------编程问答-------------------- 支持~这个可以有,正好解决的我一个需求 --------------------编程问答-------------------- --------------------编程问答--------------------
兄弟,啥需求啊?说来听听 --------------------编程问答-------------------- 这样何苦?用注解很容易实现,而且来的方便。你只需要对需要的对象的属性做注解,并且用反射解析出注解生成SQL会更好。不过也顶一下吧 --------------------编程问答-------------------- 看不出你这个有什么优势,劣势倒有一大堆!建议使用楼上的方法,使用 Annotation --------------------编程问答-------------------- 感谢楼主分享,学习了 --------------------编程问答--------------------
不要光说不练,贴代码看看! --------------------编程问答--------------------
别装B,贴代码! --------------------编程问答--------------------
JPA 自己去看! --------------------编程问答--------------------
这里不是非技术区,我没必要跟你在这装!
另外,在技术区请注意您的言行! --------------------编程问答--------------------
看过了,那只是一套标准而已,要庞大的容器支持,这个只用Java 5自带的特性解决一些小范围的问题。 --------------------编程问答-------------------- 在下只对技术感兴趣,用注解写是挺方便。不过反射的太多了,速度真有点……
--------------------编程问答--------------------
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";
}
不错不错! 用注释的话自己写起来也比较麻烦 --------------------编程问答-------------------- 又见极品,java之王。。。。。。。PS下:(king_of_dotnet)点耐特之王,是他的小号,自问自答自顶,这样的无耻作风,佩服! --------------------编程问答-------------------- 感觉注解annotation更好。 --------------------编程问答-------------------- 正好自己刚刚自学完枚举。
按照楼主的方法,自己练习了一下。写了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
所以得处理一下才行
总之,楼主让我看了眼界,又温习了一下枚举。 --------------------编程问答--------------------
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;
}
}
--------------------编程问答-------------------- 支持一下,我是从C#版的链接跳过来的。
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='张三'
PS:为什么你们的sql语句是大括号create table Student{},难道有了新的标准? --------------------编程问答-------------------- 来学习的! --------------------编程问答-------------------- JF走人,楼主好淫 --------------------编程问答--------------------
所以说还得动手做
看了半天一直到你这楼才提到楼主代码里的 class name 问题
--------------------编程问答-------------------- 看不懂枚举,下来真要好好学习了 --------------------编程问答-------------------- 稍微改了一下,通用于所有实现了 Field 接口的 enum 类型:
// Student.class.getName()
改成
Student.class.getSimpleName()
--------------------编程问答-------------------- 试问:
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)
如果增加一个字段后,是改代码重新编译好呢,还是只改一下配置文件比较好? --------------------编程问答--------------------
无论哪种都可以通过程序自动完成,开发工作量差不多,当然前提是要对元数据有修改的需求 --------------------编程问答-------------------- 重新学习了Enum,理解更深,记得更牢了
补充:Java , Java SE