jdbc数据库操作任意表,解决实体类驼峰命名与数据库下划线命名不一致的问题

1 篇文章 0 订阅

 一个可以查询任何表的java底层代码

public class SQLBase<T> {

    //jdbc驱动,我的是mysql 5.5.10的。mysql8以上的有变化
    private String driver="com.mysql.jdbc.Driver";

    //连接数据库的地址
    private String url="jdbc:mysql://localhost:3307/zhsh?useUnicode=true&characterEncoding=utf-8";

    //用户名
    private String name="root";

    //密码
    private String pass="qinjuan1112";

    //反射用的一个类型:例如如果T是User他就是User类,T 是Person他就是Person类;对应数据库返回结果对应的实体类。
    private Class<T> clazz;

    public SQLBase() {
        //构造函数,创建这个类的对象的时候,确定 T 的类型
        clazz = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }

    //工具类:获取连接
    private Connection getConnection(){
        Connection connection = null;
        try {
            Class.forName(driver);
            connection = DriverManager.getConnection(url,name,pass);
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        return connection;
    }

    //工具类:关闭需要关闭的连接
    private void closeAll(Connection connection, PreparedStatement preparedStatement){
        try {
            connection.close();
            preparedStatement.close();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    private void closeAll(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet){
        try {
            connection.close();
            preparedStatement.close();
            resultSet.close();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    //工具类:属性名转化。把数据库里有斜划线的列名转化成骆驼命名法的格式。
    private String getDbName(String columnName){
        char[] chars = columnName.toCharArray();
        StringBuffer s = new StringBuffer();
        for (int i = 0 ; i < chars.length ; i++){
            if(chars[i] == '_'){
                s.append(String.valueOf(chars[i+1]).toUpperCase());
                i++;
            }else {
                s.append(String.valueOf(chars[i]));
            }
        }
        return  s.toString();
    }

    //增,删,改 操作
    //这里用预编译编写。所以需要传递一个sql语句和对应的参数,参数都放在一个Object数组里
    protected int sqlDML(String sql,Object[] objects){
        Connection connection = null;

        //预编译对象
        PreparedStatement preparedStatement = null;

        //获取结果..增删改只返回执行sql语句影响的数据库相应表的行数。所以只返回一个整型。
        int ret = 0;
        try {
            //获取连接
            connection = getConnection();

            //向数据库传递预编译sql语句
            preparedStatement = connection.prepareStatement(sql);

            //向数据库传递预编译sql语句的参数。
            if(objects != null){
                for (int i = 0; i < objects.length; i++) {
                    preparedStatement.setObject(i+1, objects[i]);
                }
            }

            //获取结果..增删改只返回执行sql语句影响的数据库相应表的行数。所以只返回一个整型。
            ret = preparedStatement.executeUpdate();
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }finally{
            closeAll(connection, preparedStatement);
        }
        //返回结果
        return ret;
    }

    //查询操作
    protected List<T> sqlQuery(String sql, Object[] objects){
        Connection connection = null;
        PreparedStatement preparedStatement = null;

        //接收结果集
        ResultSet resultSet = null;
        List<T> list = new ArrayList<T>();
        try {
            connection = getConnection();
            preparedStatement = connection.prepareStatement(sql);
            if(objects != null){
                for (int i = 0; i < objects.length; i++) {
                    preparedStatement.setObject(i+1, objects[i]);
                }
            }
            //接收返回的结果集
            resultSet = preparedStatement.executeQuery();

            //这个对象可以获取返回结果集的一些基本信息
            ResultSetMetaData rsmd = resultSet.getMetaData();

            //获取列的个数
            int columuCount = rsmd.getColumnCount();
            while (resultSet.next()){

                //创建 T 对象
                T t = clazz.newInstance();


                for(int i = 1;i<=columuCount;i++){

                    //获取与该列名称对应的属性对象
                    Field field = clazz.getDeclaredField(getDbName(rsmd.getColumnName(i)));

                    //把私有属性暂时强制改成公有的
                    field.setAccessible(true);

                    //为对象 t 的 field 属性赋 resultSet.getObject(i)值
                    field.set(t,resultSet.getObject(i));
                }
                //把对象 t 添加到容器里
                list.add(t);
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }finally{
            closeAll(connection, preparedStatement, resultSet);
        }
        return list;
    }



}

测试类:用的时候必须继承SQLBase类才可以用。

public class Test extends SQLBase<Account>{
    public static void main(String[] args) {
        Test test = new Test();
        List<Account> accounts = test.sqlQuery("select * from account where account_id > ?",new Object[]{3});
        for (Account a: accounts   ) {
            System.out.println(a);
        }
    }
}

 

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值