对Jdbc的一些简单的总结

开篇

总所周知,jdbc是Java DataBase Connectivity(Java语言连接数据库),有一套标准的连接数据库规范规范,其中java连接mysql的驱动名称就叫做mysql-connector-java。

简单的连接和使用

如果是连接高版本的mysql,需要在jdbc-url后面加一些如下内容

?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&characterEncoding=UTF-8&generateSimpleParameterMetadata=true

generateSimpleParameterMetadata=true,这个是用来获取元数据需要的一个参数,做一个简单说明,大概的元数据分为

  1. 由Connection对象的getMetaData()方法获取的是DatabaseMetaData对象。
  2. 由PreparedStatement对象的getParameterMetaData ()方法获取的是ParameterMetaData对象。
  3. 由ResultSet对象的getMetaData()方法获取的是ResultSetMetaData对象。
    后面的使用再举例说明
    一般来说,需要加载所需要的驱动、获取连接、创建对应执行sql是statement,如果有查询返回值则获取结果集resultset。
static String url;
    static String user;
    static String password;
    static String driver;
    static public Connection connection;
    static {
        //使用Properties文件用来存放配置文件
        Properties properties = new Properties();
        //加载配置文件
        String file1 = JDBCUtil.class.getClassLoader().getResource("jdbc.properties").getFile();
        try {
            properties.load(new FileInputStream(file1));
        } catch (IOException e) {
            e.printStackTrace();
        }
        url=properties.getProperty("url");
        user=properties.getProperty("user");
        password=properties.getProperty("password");
        driver=properties.getProperty("driver");
    }
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url,user,password);
    }
    public static void closeResource(Connection connection, Statement statement){
        if (connection!=null){
            try {
                connection.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if (statement!=null){
            try {
                statement.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }

    }
    public static void closeResource(Connection connection, Statement statement, ResultSet resultSet){
        closeResource(connection,statement);
        if (resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }

关闭资源的时候需要从下到上依次关闭。

一个简单的查询案例

sql表

DROP TABLE IF EXISTS `employee`;
CREATE TABLE `employee`  (
  `id` int(0) NOT NULL,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `d_id` int(0) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of employee
-- ----------------------------
INSERT INTO `employee` VALUES (1, 'ye', 1);
INSERT INTO `employee` VALUES (2, 'zs', 2);
INSERT INTO `employee` VALUES (3, 'ls', 3);
INSERT INTO `employee` VALUES (4, 'ww', 1);

SET FOREIGN_KEY_CHECKS = 1;

测试案例

  @Test
    public void test01() throws SQLException {
        Connection connection = getConnection();
        Statement statement = connection.createStatement();
        ResultSet resultSet = statement.executeQuery("select * from employee");
        while (resultSet.next()){
            Object object1 = resultSet.getObject(1);
            Object object2 = resultSet.getObject(2);
            Object object3 = resultSet.getObject(3);
            System.out.println(object1+" "+object2+" "+object3);
        }
        closeResource(connection,statement,resultSet);
    }

测试结果
在这里插入图片描述
如果这样写显然不太灵活,很多地方就写死了这里查询就仅仅限制了只有三条数据的时候,这时候就需要用到元数据信息了
这里举一个简单例子 metaData 类的简单应用,代码如下

  @Test
    public void test02() throws SQLException {
        Connection connection = getConnection();
        Statement statement = connection.createStatement();
        ResultSet resultSet = statement.executeQuery("select * from employee");
        //这个就是查询后的数据元数据信息
        ResultSetMetaData metaData = resultSet.getMetaData();
        //获取一共有多少条数据
        int columnCount = metaData.getColumnCount();
        List<String> colunNames=new ArrayList<>();
        for (int i=1;i<=columnCount;i++){
            String columnName = metaData.getColumnName(i);
            colunNames.add(columnName);
            String columnTypeName = metaData.getColumnTypeName(i);
            System.out.println(columnName+" "+columnTypeName);
        }
        System.out.println(colunNames);
    }

结果,这样就获取到了数据库的信息和字段类型。
在这里插入图片描述

如果我想自己封装一个简单的orm对象关系映射的工具类该如何解决?

这里就不做过多解析了,关键还是metaData元数据信息类的使用和对象类的反射的应用,我下面给一个我的实现例子。

public static <T> List<T> excuteQuery(String sql, Class<T> t, Object... s) throws SQLException {
        Connection connection = getConnection();
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        int i = 1;
        for (Object o : s) {
            preparedStatement.setObject(i, o);
            i++;
        }
        ResultSet resultSet = preparedStatement.executeQuery();
        ArrayList<T> ts = new ArrayList<T>();
        while (resultSet.next()) {
            ts.add(ClassUtil.fillBean(resultSet, t));
        }
        closeResource(connection, preparedStatement, resultSet);
        return ts;
    }

fillBean工具类的方法

  public static <T> T fillBean(ResultSet resultSet,Class<T> tClass) throws SQLException {
        //新建tClass对象
        T t=null;
        try {
            Constructor<T> constructor = tClass.getConstructor();
             t = constructor.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }catch (NoSuchMethodException e){
            e.printStackTrace();
        }
        //获取java对象中的fileds对象
        Field[] declaredFields = tClass.getDeclaredFields();
        Method method=null;
        ResultSetMetaData metaData = resultSet.getMetaData();
        String fileName;
        Class<?> type;
        String methodName;
        for (Field f:declaredFields){
            fileName = f.getName();
            type=f.getType();

            methodName= StringUtil.setterName(fileName);
            try {
                method=tClass.getMethod(methodName,type);

                method.invoke(t,type.cast(resultSet.getObject(fileName)));
            } catch (NoSuchMethodException e) {
                System.err.println("没有找到"+fileName+"属性的setter方法");
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }

        }
        return t;
    }

其实这样写还是有很多的不足,需要考虑的数据库类型和字段类型的映射其实没有做好,还有很多需要优化的东西,当然这仅仅是提供以一个简单的思路而已。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值