hibernate 里面通过注解,映射等手段,可以自动生成表,现在模拟实现。随便学学注解如何使用。
首先,我们要定义几个注解:
Table 用于定义表名字,类型使用Type
- import java.lang.annotation.ElementType;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.annotation.Target;
- @Target(ElementType.TYPE)
- @Retention(RetentionPolicy.RUNTIME)
- public @interface Table {
- // 表名
- String name() default "";
- }
Types,定义一下常用的类型,这里我写得比较乱,也可以使用 枚举 等其他方法,方便使用
- import java.util.HashMap;
- import java.util.Map;
- public class Types {
- // 自己定义的一些基本类型,和数据对应就行了,就是组成字符串
- // 这是临时的办法,需要大家从新设计
- public static final String VARCHAR = "VARCHAR";
- public static final String INT = "INT";
- public static final String BOOLEAN = "BOOLEAN";
- // 默认长度,和数据库对应
- public static final int STRING_LENGTH =32;
- public static final int INT_LENGTH = 10;
- // 将类型 已经默认长度,放入集合
- public static Map<String,Integer> map = new HashMap();
- static{
- map.put(VARCHAR, STRING_LENGTH);
- map.put(INT, INT_LENGTH);
- map.put(BOOLEAN, 0);
- }
- public static String getType(String type,int length){
- if(type == null){
- throw new RuntimeException("Not recognized the type :"+type);
- }
- // 防止boolean 这类型
- if( length > 0){
- return type+"("+length+")";
- }
- return type;
- }
- public static String getString(){
- return getStirng(VARCHAR, STRING_LENGTH);
- }
- public static String getString(int length){
- return getStirng(VARCHAR, length);
- }
- public static String getInt(){
- return getStirng(INT, INT_LENGTH);
- }
- public static String getInt(int length){
- return getStirng(INT, length);
- }
- public static String getBoolean(){
- return BOOLEAN;
- }
- private static String getStirng(String str,int length){
- return str+"("+length+")";
- }
- }
这是建表的一些约束条件,只写普通的,可以自己添加
- import java.lang.annotation.ElementType;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.annotation.Target;
- @Target(ElementType.FIELD)
- @Retention(RetentionPolicy.RUNTIME)
- public @interface Constraints{
- // 是否主键,是否为空 等
- boolean primaryKey() default false;
- boolean allowNull() default true;
- boolean unique() default false;
- }
Column 是 对映实体Bean
- import java.lang.annotation.ElementType;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.annotation.Target;
- @Target(ElementType.FIELD)
- @Retention(RetentionPolicy.RUNTIME)
- public @interface Column {
- // 名字
- String name() default "";
- // 长度
- int length() default 0;
- // 类型
- String type();
- // 约束,这里可以使用其他注解类型。
- Constraints constraints() default @Constraints;
- }
下面看我们的实体
- @Table(name="TestTable")
- @SuppressWarnings("unused")
- public class TestTable {
- // 指定了列名字,约束为 主键,长度 以及类型
- @Column(name="id",constraints=@Constraints(primaryKey=true),length=15, type = Types.INT)
- private int id;
- // 列名 类型,如果都没有,只能使用默认的,也可以在后面处理类 里面 定义
- @Column(name="name", type = Types.VARCHAR)
- private String name;
- @Column(type = Types.BOOLEAN)
- private Boolean sex;
- }
基本工作完成了,下面就是如果完成解析,获得我们需要的SQL:
- import java.lang.annotation.Annotation;
- import java.lang.reflect.Field;
- import java.util.ArrayList;
- import java.util.List;
- public class CrateTable {
- public static void main(String[] args) {
- // 类路径
- System.out.println(getCreateSQL("com.annotation.TestTable"));
- }
- @SuppressWarnings("unused")
- public static String getCreateSQL(String className){
- try {
- // 加载类
- Class<?> c = Class.forName(className);
- // 获得指定类型的注解对象
- Table table = c.getAnnotation(Table.class);
- if(table == null){
- System.out.println("No Table annotation in class "+ className);
- return null;
- }
- String tableName = table.name();
- if(tableName.length() == 0){
- // 如果没指定长度, 可以默认以类的名字 命名表名
- tableName = c.getName().toUpperCase();
- }
- List<String> columns = new ArrayList<String>();
- // 遍历所有字段
- for(Field field : c.getDeclaredFields()){
- String columnName = null;
- String columnType = null;
- // 获得每个字段上的注解信息,这里不需要继承的注解
- // 还有其他方法,具体可以去看API
- Annotation[] anns = field.getDeclaredAnnotations();
- if(anns.length == 0){
- // 如果该字段没有注解,表示这个字段,不需要生成
- continue;
- }else{
- // 获得该字段的注解信息,默认这设置的column注解信息
- Column col = (Column) anns[0];
- // 获得建表 语句 字符串
- String name = col.name();
- String type = col.type();
- Integer length = col.length();
- String constraint = getConstraints(col.constraints());
- if(name.length() == 0){
- // 获得默认字段名
- columnName = field.getName();
- }else{
- columnName = name;
- }
- if(type.length() == 0){
- // 获得默认类型
- columnType = field.getType().toString();
- }else{
- columnType = type;
- }
- if(length == 0){
- // 获取默认长度
- length = Types.map.get(type);
- if(length == null){
- throw new RuntimeException("Type cant't be solved :"+type);
- }
- }
- type = Types.getType(type,length);
- columns.add(columnName + " "+ type+constraint);
- }
- }
- if(columns.size() == 0){
- throw new RuntimeException("There is no field in "+className);
- }
- StringBuilder createCommand = new StringBuilder("CREATE TABLE "+tableName +" (");
- for(String column : columns){
- createCommand.append("\n "+column +" ,");
- }
- String createTable = createCommand.substring(0,createCommand.length()-1)+" \n );";
- return createTable;
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- return null;
- }
- /**
- * 获得约束条件
- * @param con
- * @return
- */
- private static String getConstraints(Constraints con){
- String constraints = "";
- if(!con.allowNull()){
- constraints += " NOT NULL";
- }
- if(con.primaryKey()){
- constraints += " PRIMARY KEY";
- }
- if(con.unique()){
- constraints += " UNIQUE ";
- }
- return constraints;
- }
- /**
- * 获得所需要的字段
- * @param fields
- * @return
- */
- public static List<Field> getNeedField(Field[] fields){
- List<Field> allFileds = new ArrayList<Field>();
- for(Field field : fields){
- // 获得每个字段上的注解信息,这里不需要继承的注解
- Annotation[] anns = field.getDeclaredAnnotations();
- if(anns.length != 0){
- // 如果该字段没有注解,表示这个字段,不需要生成
- allFileds.add(field);
- }
- }
- return allFileds;
- }
- }
上面用了一下反射的功能,有些比较死板,要灵活构建,需要从写。可以进行测试,获得的SQL,是否可以生成表,当然也可以移动到xml 配置文件里面,这里我暂时不写了,先看测试。
其实只需要打印出SQL,看看是否正确就行了。
下面的方法, 用了JDBC连接。详情请看:http://greemranqq.iteye.com/admin/blogs/1830200
- /**
- * 执行SQL
- * @param sql
- */
- public static void executeSql(String sql){
- conn = ConnectionUtil.getConnection();
- try {
- PreparedStatement ps = conn.prepareStatement(sql);
- ps.execute();
- } catch (SQLException e) {
- e.printStackTrace();
- }finally{
- ConnectionUtil.colse(conn);
- }
- }
- public static void main(String[] args) {
- String sql = CrateTable.getCreateSQL("com.annotation.TestTable");
- System.out.println(sql);
- executeSql(sql);
- }
相关推荐
java注解annotation
Java注解Annotation用起来很方便,也越来越流行,由于其简单、简练且易于使用等特点,很多开发工具都提供了注解功能,不好的地方就是代码入侵比较严重,所以使用的时候要有一定的选择性。 这篇文章将利用注解,来做...
主要介绍了java 注解annotation的使用以及反射如何获取注解的相关资料,需要的朋友可以参考下
JAVA注解(Annotation).doc JAVA注解(Annotation).doc
Java 注解(Annotation) - 请认准 ih0qtq
Java Annotation注解技术
新手学Java注解的最好资料,15分钟迅速开发
本文全面讲述了Java注解Annotation与Java自定义注解及相关内容,大家可以认真看看
Java基础复习笔记12Java自定义注解Annotation的使用
如果你想知道java annotation是什么?你可以看看
JPA、EJB、Spring零配置等等怎么使用相信各位读者都能掌握,这里主要是说如何自定义自己的注解,自己使用自定义的注解。
Java.Annotation注解.part4
annotation 注解 annotation的资料 JAVA注解 个人整理很有实用价值
Java 5 annotation 学习笔记Java 5 annotation 学习笔记Java 5 annotation 学习笔记
hibernate 注解 annotation 教程
Java.Annotation注解.part3
Java.Annotation注解.part2
Java.Annotation注解.part1
学习java自定义注解的小例子,处理运行时注解方法,可以结合博客学习,博客地址: http://blog.csdn.net/liuyonglei1314/article/details/59494503