jdbc学习中出现的问题(自用)

以下问题为自己编程过程中遇到的问题,如果各路神通觉得我出现的问题比较低级。可以给出解决意见,但不要乱喷。心灵脆弱禁不起打击,本博作为我编程路上跳坑记录,学会之后会过来填平。但不知道什么时候才能学会。

1、针对一张表查询一条数据的通用方法

实体类

package com.company.preparedstatement.crud;

public class course {
    public String CId;
    public String Cname;
    public String TId;

    public course() {
    }

    public course(String CId, String cname, String TId) {
        this.CId = CId;
        Cname = cname;
        this.TId = TId;
    }

    public String getCId() {
        return CId;
    }

    public void setCId(String CId) {
        this.CId = CId;
    }

    public String getCname() {
        return Cname;
    }

    public void setCname(String cname) {
        Cname = cname;
    }

    public String getTId() {
        return TId;
    }

    public void setTId(String TId) {
        this.TId = TId;
    }

    @Override
    public String toString() {
        return "course{" +
                "CId='" + CId + '\'' +
                ", Cname='" + Cname + '\'' +
                ", TId='" + TId + '\'' +
                '}';
    }
}

工具类

package com.company.preparedstatement.Utils;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JDBCUtils {
    public static Connection getConnection() throws IOException, ClassNotFoundException, SQLException {
        //1、获取
        InputStream is = ClassLoader.getSystemClassLoader().getSystemResourceAsStream("db.properties");
        Properties properties = new Properties();
        properties.load(is);
        String driverClass = properties.getProperty("driverClass");
        String url = properties.getProperty("url");
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");
        Class.forName(driverClass);
        Connection connection = DriverManager.getConnection(url, user, password);
        is.close();
        return connection;
    }

    /*
    * 关闭连接和Statement的操作
    * */
    public static void closeResource(Connection connection, PreparedStatement preparedStatement){
        try {
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            preparedStatement.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    public static void closeResource(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet){
        try {
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            preparedStatement.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            resultSet.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

db.properties

driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbc
user=root
password=123456

查询一张表数据的方法

@org.junit.Test
package com.company.preparedstatement.crud;

import com.company.preparedstatement.Utils.JDBCUtils;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;

public class Test {
    //针对一张表查询一条数据的通用方法
    public course test4(String sql,Object... args) {

        Connection connection = null;
        PreparedStatement ps = null;
        ResultSet resultSet = null;
        try {
            //创建连接
            connection = JDBCUtils.getConnection();
            //获取对象
            ps = connection.prepareStatement(sql);
            //获取占位符对应的值
            for(int i = 0;i < args.length;i++){
                ps.setObject(i+1,args[i]);
            }

            //执行返回结果集
            resultSet = ps.executeQuery();

            //获取结果集的元数据:ResultSetMetaData
            ResultSetMetaData metaData = resultSet.getMetaData();

            //获取字段值个数
            int columnCount = metaData.getColumnCount();

            //判断有没有返回值
            if(resultSet.next()){
                //创建一个对象
                course cs = new course();
                //处理一行数据中的每一个列
                for(int i = 0;i < columnCount;i++){
                    //获取列值
                    Object columValue = resultSet.getObject(i + 1);

                    //获取每个列的列名
                    String columName = metaData.getColumnName(i + 1);

                    //给对象中的给对象中columName属性用set方法赋值为columvalue:通过反射实现
                    //通过反射获取属性
                    Field field = course.class.getDeclaredField(columName);
                    //属性值可能是私有的,设置一下
                    field.setAccessible(true);
                    //给对象的属性赋值
                    field.set(cs,columValue);
                }
                //返回对象
                return cs;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            JDBCUtils.closeResource(connection,ps,resultSet);
            return null;
        }
    }
}

测试方法

public void test44(){
    String sql = "select * from course where CId=?";
    course course = test4(sql, "01");
    System.out.println(course);
}

出现的问题:

try中包含的代码可以顺利的执行,也能成功的向创建的对象中添加相应的数据,但到return的时候无论如何都会返回null。程序返回多条数据的时候只执行一次循环就会return null结束程序。

代码存在缺陷:

假如try中顺利执行也成功return就无法继续执行下面的代码关闭资源,程序硬伤

大发现

//cs.getClass()和course.class return出的内容不同!!!!
Field declaredField = cs.getClass().getDeclaredField(columName);

cs.getClass():可以返回一条数据

course.class :直接return null

oh,my god!一定是我太无知了

emmmmmmm他们又返回一样的值了,我真的不懂这是什么魔鬼操作!!!

2、数据库事务回滚

package com.company.trans;

import com.company.Utils.JDBCUtils;
import org.junit.Test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class TransactionTest {
    /**
     * 针对于数据表user_table
     *
     * */
    @Test
    public void testUpdate()
    {
        String sql1 = "update sc set score = score - 10 where SId = ?";
        String sql2 = "update sc set score = score + 10 where SId = ?";

        update(sql1,"06");
        System.out.println(10/0);
        update(sql2,"07");
        System.out.println("分数交换成功!");
    }
    //=================没有考虑数据库事务情况下的分数同时增加缩小的操作===================
    //增删改通用操作
    public void update(String sql,Object... agrs) {

        Connection connection = null;
        PreparedStatement ps = null;
        try {
            //1.获取数据库连接
            connection = JDBCUtils.getConnection();
            //2.预编译sql语句,返回PrepareStatement的实例
            ps = connection.prepareStatement(sql);
            //3.添加占位符
            for(int i = 0;i < agrs.length;i++){
                ps.setObject(i + 1,agrs[i]);
            }
            //4.执行
            ps.execute();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //5.关闭资源
            JDBCUtils.closeResource(connection,ps);
        }
    }

    //=====================考虑数据库事务的的分数交换操作=====================
    public int update1(Connection connection,String sql,Object... agrs) {

        PreparedStatement ps = null;
        try {
            //2.预编译sql语句,返回PrepareStatement的实例
            ps = connection.prepareStatement(sql);
            //3.添加占位符
            for(int i = 0;i < agrs.length;i++){
                ps.setObject(i + 1,agrs[i]);
            }
            //4.执行
            ps.execute();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //5.关闭资源
            JDBCUtils.closeResource(null,ps);
        }
        return 0;
    }

    @Test
    public void updateTest(){
        Connection connection = null;
        try {
            connection = JDBCUtils.getConnection();
            //将数据库语句自动提交设置为false
            connection.setAutoCommit(false);
            String sql1 = "update examstudent set Grade = Grade - 10 where FlowID = ?";
            update1(connection,sql1,2);

            //设置异常
            //System.out.println(10/0);

            String sql2 = "update examstudent set Grade = Grade + 10 where FlowID = ?";
            update1(connection,sql2,3);
            //手动提交事务
            connection.commit();
        } catch (Exception e) {
            try {
                //出现异常
                connection.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            JDBCUtils.closeResource(connection,null);
        }

    }
}

存在问题,由于数据库关闭方法中的对象在不同的位置关闭,其中就有一方为null,有一个为null系统会报空指针异常

上一篇:数据清洗和准备--数据转换


下一篇:ucharts 柱状图y轴显示按小数分隔