JDBC的应用,一次代码抄袭行为的收获。(内容包含:Class.forName(),Statement,ResultSet ,DatabaseMetaData )等部份知识点)

本文深入探讨了数据库连接、SQL语句执行及事务处理的原理与实践,包括Class.forName方法的作用、Statement对象的使用、自动提交模式的设置与数据库连接的管理。详细解释了如何利用JDBC技术实现数据库的高效操作。
摘要由CSDN通过智能技术生成
    protected static String dbClassName = "net.sourceforge.jtds.jdbc.Driver";
    protected static String dbUrl = "jdbc:jtds:sqlserver://localhost:1433/"
            + "db_database28;SelectMethod=Cursor";
    protected static String dbUser = "sa";
    protected static String dbPwd = "123456";
    protected static String second = null;
    
    public static Connection conn = null;
    static {
        try {
            if (conn == null) {
                //构造了一个com.mysql.jdbc.Driver实例
                Class.forName(dbClassName).newInstance();//Class.forName(xxx.xx.xx);的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段
                conn = DriverManager.getConnection(dbUrl, dbUser, dbPwd);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(null,
                    "请将SQL Server 2000的JDBC驱动包复制到lib文件夹中。");
            System.exit(-1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

1:jdbc方式链接数据库时会经常看到这句代码:Class.forName(String className)(初始化参数指定的类,并且返回此类对应的Class 对象)

Class A=Class.forName("java.lang.Thread"),返回 java.lang.Thread 类对应的Class对象,即调用forName("X") 将导致名为 X 的类被初始化,而在代码中作用,如注释所言,至于newInstance( )静态方法则是用来实例化对象以便操作。因为单单使用Class.forName( )是动态加载类是没有用的,其最终目的是为了实例化对象。

 public static int restoreOrBackup(String sql) throws Exception {
        int rs = 0;
        if (conn != null) {
            conn.close();
        }
        // 连接到系统数据库
        conn = DriverManager.getConnection(
                "jdbc:jtds:sqlserver://localhost:1433/master", dbUser,
                dbPwd);
        Statement stmt = conn.createStatement();//创建一个Statement对象将SQL语句发送到数据库。
        // 定义单用户连接模式的SQL语句
        String single = "alter database db_database28 set single_user"
                + " with rollback immediate " + sql;
        // 执行数据库备份或恢复的SQL语句
        rs = stmt.executeUpdate(single);//返回更新的条数
        stmt.close();
        conn.close(); // 关闭数据库连接
        // 恢复原有数据库连接
        conn = DriverManager.getConnection(dbUrl, dbUser, dbPwd);
        return rs;
    }
2.:Statement 用于执行静态 SQL 语句并返回它所生成结果的对象。

在默认情况下,同一时间每个 Statement 对象在只能打开一个 ResultSet 对象。因此,如果读取一个 ResultSet 对象与读取另一个交叉,则这两个对象必须是由不同的 Statement 对象生成的。如果存在某个语句的打开的当前 ResultSet 对象,则 Statement 接口中的所有执行方法都会隐式关闭它。

Statement 接口提供了三种执行 SQL 语句的方法:executeQuery、executeUpdate 和execute。使用哪一个方法由 SQL 语句所产生的内容决定。

方法 executeQuery 用于产生单个结果集的语句,例如 SELECT 语句。

方法 executeUpdate 用于执行 INSERT、UPDATE 或 DELETE 语句以及 SQLDDL(数据定义语言)语句,例如 CREATE TABLE 和 DROP TABLE。INSERT、UPDATE 或 DELETE语句的效果是修改表中零行或多行中的一列或多列。executeUpdate 的返回值是一个整数,指示受影响的行数(即更新计数)。对于CREATE TABLE 或 DROP TABLE 等不操作行的语句,executeUpdate 的返回值总为零。

方法 execute用于执行返回多个结果集、多个更新计数或二者组合的语句。参数是包含 SQL 语句的 String 。因为多数程序员不会需要该高级功能,所以本概述后面将在单独一节中对其进行介绍。如果第一个结果为一个结果集,则为 true。否则为 false

执行语句的所有方法都将关闭所调用的 Statement 对象的当前打开结果集(如果存在)。这意味着在重新执行 Statement对象之前,需要完成对当前 ResultSet 对象的处理。
应注意,继承了 Statement 接口中所有方法的 PreparedStatement 接口都有自己的executeQuery、executeUpdate 和 execute 方法。Statement 对象本身不包含 SQL语句,因而必须给 Statement.execute 方法提供 SQL 语句作为参数。PreparedStatement 对象并 不将SQL 语句作为参数提供给这些方法,因为它们已经包含预编译 SQL 语句。CallableStatement 对象继承这些方法的PreparedStatement 形式。对于这些方法的 PreparedStatement 或 CallableStatement版本,使用查询参数将抛出 SQLException。


 public static boolean insertRukuInfo(TbRukuMain ruMain) {
        try {
            boolean autoCommit = conn.getAutoCommit();//检索此 Connection 对象的当前自动提交模式。 
            conn.setAutoCommit(false);//涉及事务处理的时候可以将setAutoCommit(false);  事务完后commit一下就 
            // 添加入库主表记录
            insert("insert into tb_ruku_main values('" + ruMain.getRkId()
                    + "','" + ruMain.getPzs() + "'," + ruMain.getJe()
                    + ",'" + ruMain.getYsjl() + "','"
                    + ruMain.getGysname() + "','" + ruMain.getRkdate()
                    + "','" + ruMain.getCzy() + "','" + ruMain.getJsr()
                    + "','" + ruMain.getJsfs() + "')");
            Set<TbRukuDetail> rkDetails = ruMain.getTabRukuDetails();
            for (Iterator<TbRukuDetail> iter = rkDetails.iterator();iter.hasNext();) 
            {
                TbRukuDetail details = iter.next();
                // 添加入库详细表记录
                insert("insert into tb_ruku_detail values('"
                        + ruMain.getRkId() + "','"
                        + details.getTabSpinfo() + "'," + details.getDj()
                        + "," + details.getSl() + ")");
                // 添加或修改库存表记录
                Item item = new Item();
                item.setId(details.getTabSpinfo());
                TbSpinfo spInfo = getSpInfo(item);
                if (spInfo.getId() != null && !spInfo.getId().isEmpty()) {
                    TbKucun kucun = getKucun(item);
                    if (kucun.getId() == null || kucun.getId().isEmpty()) {
                        insert("insert into tb_kucun values('"
                                + spInfo.getId() + "','"
                                + spInfo.getSpname() + "','"
                                + spInfo.getJc() + "','" + spInfo.getCd()
                                + "','" + spInfo.getGg() + "','"
                                + spInfo.getBz() + "','" + spInfo.getDw()
                                + "'," + details.getDj() + ","
                                + details.getSl() + ")");
                    } else {
                        int sl = kucun.getKcsl() + details.getSl();
                        update("update tb_kucun set kcsl=" + sl + ",dj="
                                + details.getDj() + " where id='"
                                + kucun.getId() + "'");
                    }
                }
            }
            conn.commit();//使自从上一次提交/回滚以来进行的所有更改成为持久更改,并释放此 Connection 对象当前保存的所有数据库锁定。
            conn.setAutoCommit(autoCommit);
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
setAutoCommit将此连接的自动提交模式设置为给定状态。如果连接处于自动提交模式下,则将执行其所有 SQL 语句,并将这些语句作为单独的事务提交。否则,其 SQL语句将成组地进入通过调用 commit 方法或 rollback 方法终止的事务中。默认情况下,新的连接处于自动提交模式下。 提交发生在语句完成或执行下一条语句时,以先发生的情况为准。在语句返回 ResultSet 对象的情况下,该语句在已检索完最后一行 ResultSet 对象或已关闭 ResultSet 对象时完成。在更复杂的情况下,单个语句可以返回多个结果和输出参数值。在这些情况下,提交发生在检索到所有结果和输出参数值后。 true 表示启用自动提交模式;为 false 表示禁用该模式 一般来说不用setAutoCommit(true);   因为大部分的驱动默认是true;   当你涉及事务处理的时候可以将setAutoCommit(false);   然后在你事务完后commit一下就行了。如果sqlManager.setAutoCommit(false);的话,则在语句正常执行完毕后需要用sqlManager.commit()手动提交,如果在执行语句时出错的可以调用sqlManager.rollback()来回滚。

getAutoCommit()检索此 Connection 对象的当前自动提交模式。 返回:此 Connection 对象的自动提交模式的当前状态

commit()使自从上一次提交/回滚以来进行的所有更改成为持久更改,并释放此 Connection 对象当前保存的所有数据库锁定。此方法应该只在已禁用自动提交模式时使用。

public static List findForList(String sql) {
        List<List> list = new ArrayList<List>();
        ResultSet rs = findForResultSet(sql);
        try {
            ResultSetMetaData metaData = rs.getMetaData();// 有关 ResultSet 中列的名称和类型的信息。
            /* ResultSet 对象是 JDBC 中最重要的单个对象。从本质上讲,它是对一个一般宽度和未知长度的表的一种抽象。
             * 几乎所有的方法和查询都将数据作为 ResultSet 返回。ResultSet 包含任意数量的命名列,您可以按名称访问这些列。它还包含一个或多个行,您可以按顺序自上而下逐一访问。在您使用 ResultSet 之前,必须查询它包含多少个列。此信息存储在 ResultSetMetaData 对象中。
             */
            int colCount = metaData.getColumnCount();
            while (rs.next()) {
                List<String> row = new ArrayList<String>();
                for (int i = 1; i <= colCount; i++) {
                    String str = rs.getString(i);
                    if (str != null && !str.isEmpty())
                        str = str.trim();
                    row.add(str);
                }
                list.add(row);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }
DatabaseMetaData 有关整个数据库的信息:表名、表的索引、数据库产品的名称和版本、数据库支持的操作。 ResultSet 关于某个表的信息或一个查询的结果。您必须逐行访问数据行,但是您可以任何顺序访问列。 ResultSetMetaData 有关 ResultSet 中列的名称和类型的信息。 尽管每个对象都有大量的方法让您获得数据库元素的极为详细的信息,但在每个对象中都有几种主要的方法使您可获得数据的最重要信息。然而,如果您希望看到比此处更多的信息,建议您学习文档以获得其余方法的说明。
ResultSet 对象是 JDBC 中最重要的单个对象。从本质上讲,它是对一个一般宽度和未知长度的表的一种抽象。几乎所有的方法和查询都将数据作为 ResultSet 返回。ResultSet 包含任意数量的命名列,您可以按名称访问这些列。它还包含一个或多个行,您可以按顺序自上而下逐一访问。在您使用 ResultSet 之前,必须查询它包含多少个列。此信息存储在 ResultSetMetaData 对象中。
当您获得一个 ResultSet 时,它正好指向第一行之前的位置。您可以使用 next() 方法得到其他每一行,当没有更多行时,该方法会返回 false。由于从数据库中获取数据可能会导致错误,您必须始终将结果集处理语句包括在一个 try 块中。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值