JAVA自定义注解实现SQL语句自动生成DEMO(2)

该博客介绍了如何使用JAVA自定义注解实现SQL语句的自动生成,特别是插入语句。通过传入预先定义的对象,可以方便地获取带值的INSERT SQL。文中提供了一个测试代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一篇:http://blog.youkuaiyun.com/uckyk/article/details/76619013

SqlUtil增添了一个新功能,就是自动生成sql时候,传入已经定义好的对象,即可获得inser语句(带值)


上代码!

package com.ucky.annotation.hibernate;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 生成建表语句
 */
public class SqlUtil {
    /*
    * 生成创建table语句
    * */
    public static String create(Class<?> clazz) {
        StringBuilder sb = new StringBuilder();
        String tableName = getTableName(clazz);
        if (null == tableName || "".equals(tableName)) {
            return null;
        }
        sb.append("CREATE TABLE ").append(tableName).append("(");
        Map<String, String> columnMap = getColumn(clazz);
        for (Map.Entry<String, String> entry : columnMap.entrySet()) {
            sb.append(entry.getKey());
            sb.append(" ");
            sb.append(entry.getValue());
            sb.append(",");
        }
        sb.deleteCharAt(sb.length() - 1);
        sb.append(")");
        return sb.toString();
    }

    /*
    * 生成插入语句
    * */
    public static String insert(Class<?> clazz) {
        StringBuilder sb = new StringBuilder();
        String tableName = getTableName(clazz);
        sb.append("INSERT INTO ").append(tableName).append(" (");
        Map<String, String> columnMap = getColumn(clazz);
        for (Map.Entry<String, String> entry : columnMap.entrySet()) {
            sb.append(entry.getKey());
            sb.append(",");
        }
        sb.deleteCharAt(sb.length() - 1);
        sb.append(") ").append("VALUES").append("(");
        for (int i = 0; i < columnMap.size(); i++) {
            sb.append("?").append(",");
        }
        sb.deleteCharAt(sb.length() - 1);
        sb.append(")");
        return sb.toString();
    }

    public static String delete() {
        return null;
    }



    /*
    * 获取表名称
    * */
    public static String getTableName(Class<?> clazz) {
        //判断是否为Table注释类型是方法返回true,否则返回false
        if (clazz.isAnnotationPresent(Table.class)) {
            //获取注解信息
            Table table = clazz.getAnnotation(Table.class);
            if(!"".equals(table.name())){
                return table.name();
            }
        }
        return null;
    }

    /*
    * 获取字段信息的Map
    * */
    public static Map<String, String> getColumn(Class<?> clazz) {
        Map<String, String> columns = new HashMap<String, String>();
        //通过反射取得所有Field,因为table那里是注解指定的注解,类型,column是对应方法上的所以不能class.isAnnotationPresent直接判断
        Field[] fields = clazz.getDeclaredFields();
        if (fields != null) {
            String columnName, type;
            Column column;
            for (int i$ = 0; i$ < fields.length; i$++) {
                //判断当前field是否为Column注解
                if (fields[i$].isAnnotationPresent(Column.class)) {
                    //获取注解对象
                    column = fields[i$].getAnnotation(Column.class);
                    columnName = column.name();
                    if("".equals(columnName)){
                        throw new RuntimeException("未找到对应字段名:" + i$);
                    }
                    //根据不同类型生成不同的SQL
                    if (int.class.isAssignableFrom(fields[i$].getType())) {
                        type = "int";
                    } else if (String.class.isAssignableFrom(fields[i$].getType())) {
                        type = "String";
                    } else if (Date.class.isAssignableFrom(fields[i$].getType())) {
                        type = "Date";
                    } else {
                        throw new RuntimeException("不支持数据类型:" + fields[i$].getType().getSimpleName());
                    }
                    type += (column.isNull() ? " " : " NOT NULL");
                    columns.put(columnName, type);
                } else if (fields[i$].isAnnotationPresent(PrimaryKey.class)) {
                    PrimaryKey primaryKey = fields[i$].getAnnotation(PrimaryKey.class);
                    //将一个类的成员变量置为private,其实我也不知道啥意思,有知道的指点一下 ,谢谢!
                    fields[i$].setAccessible(true);
                    columnName =  primaryKey.name();
                    if("".equals(columnName)){
                        throw new RuntimeException("未找到对应主键名" );
                    }
                    type = "INT PRIMARY KEY AUTO_INCREMENT";
                    columns.put(columnName, type);
                }
            }
        }
        return columns;
    }

    public static <T> String insert(Class<T> clazz , T entity){
        Field[] fields = entity.getClass().getDeclaredFields();
        String sql = insert(clazz);
        for(int i$ = 0; i$<fields.length; i$++){
            //获取字段信息名
            String columnValue = fields[i$].getName();
            columnValue = columnValue.substring(0,1).toUpperCase() + columnValue.substring(1);
            try {
                Method method = entity.getClass().getMethod("get" + columnValue);
                String value = (String)method.invoke(entity).toString();
                sql = sql.replaceFirst("\\?",value);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return sql;
    }
}


代码主要添加最后下面那些,方法有一些骚骚的,自己构造出来了一个getXxxx方法,然后repalceFirst取代,其他部分代码,在上面链接里面,

测试代码:


public class test {
    public static void main(String[] args){
        System.out.println(SqlUtil.create(Person.class));
        System.out.println(SqlUtil.insert(Person.class));

        Person p =new Person();
        p.setId(1);
        p.setName("111");
       System.out.println(SqlUtil.insert(Person.class,p));
    }
}


结果如下:

CREATE TABLE person(name String NOT NULL,id INT PRIMARY KEY AUTO_INCREMENT)
INSERT INTO person (name,id) VALUES(?,?)
INSERT INTO person (name,id) VALUES(1,111)


啦啦啦啦啦啦~~~~~~解决了,如果大神们有更好的方法解决 还望赐教!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值