zoukankan      html  css  js  c++  java
  • java 的数据库操作--JDBC

    一、java与数据库的交互

      1、jdbc:java data base connectivity,java数据库连接。java的JDBC操作主要通过操作两个类进行连接操作:Connection 和 Statement。

      2、java 连接数据库的一般步骤:

        A、加载驱动,通过Class.forName(className)手动显示加载对应的驱动类,因为初始时jdbc的驱动类不会自动加载。

        B、创建连接对象Connection

        C、创建Statement对象

        D、利用Statemet执行sql语句

        E、处理结果集

      具体上代码吧:

    public void doJdbc(){
    		Connection conn = null;
    		Statement stmt = null;
    		ResultSet rs = null;
    		try{
    			//1,加载驱动
    			Class.forName("com.mysql.jdbc.Driver");
    			//创建数据库连接对象
                  //这里需要知道数据库的路径和用户名以及密码 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/atm","root","root"); //创建一个可向数据库发送SQL命令并返回结果的传送对象Statement stmt = conn.createStatement(); //将sql命令通过传送对象Statement传送到数据库执行,并返回结果 String sql = "select * from tableName"; rs = stmt.excuteQuery(sql);//excuteQuery()方法用于执行查询语句,返回结果表 //处理结果集 while(rs.next()){ String code = rs.getString("code"); int password = rs.getDouble("money"); //根据游标获取 // String code = rs.getString(1); // String password = rs.getInt(2); // double money = rs.getDouble(3); System.out.println(code + password + money); } }catch(Exception e){
                
              }finally{
                //关闭操作,省略
              }
    }

      (这个模式,其实就是设计模式中的命令模式吧!)

    二、Connection Statement 和Result的关系

      1、首先,Connection是一个连接(类比IO中的流),是一个数据库通道,利用Connection,便可操作与某个数据库的交互了;Statement其实就是一个命令模式中的一个Command,它负责将sql命令运输给数据库让数据库执行sql命令,并返回一个结果集Result对象,所以,Statement是主要和数据库进行交互的对象,下面的讨论将会重点讨论Statement的相关用法

      2、多个Connection?多个Statement?在利用JDBC连接数据时,如果是单线程的环境,一般只需要一个Connection即可满足操作条件。但是,如果需要同时执行多个sql命令,不能用同一个statement,例如下面的例子:

    //jdbc操作说明方法一
    	public void methodTest(){
    		Connection conn = null;
    		Statement stmt = null;
    		ResultSet rs1 = null;
    		ResultSet rs2 = null;
    		try{
    			String sql1 = "select id from user where id>5";
    		Class.forName("com.mysql.jdbc.Driver");
    		conn = DriverManager.getConnection("jdbcRul","username","userpass");
    		stmt = conn.createStatement();
    		rs1 = stmt.executeQuery(sql);
    		int id = 0;
    		while (rs1.next()){
    			//这里会出错,原因是一个stmt关联一个result,当stmt重复执行sql时会覆盖原来的结果!
    			rs2 = stmt.executeQuery("select * from otherTable where userId='" + id + "'");
    		}
    	  }catch (Exception e) {
    		// TODO: handle exception
    		}finally{
                //关闭操作,省略
              }
    }

      在上面的代码中,尽管rs1和rs2代表不同的Result对象,但是,一个result对象对应着一个statemetn,一旦重新执行sql语句,原谅的result对象会被抹掉,因为它对应的statemet已经重新执行另外一个sql语句了。

      这时候,应该一个Result对象对应一个statement,避免覆盖情况。

      3、什么时候需要多个Connection?当不同线程之间提交数据时,需要不同的Connection,否则,会造成事务混乱。这个这里不重点讨论。

    三、jdbc与事务

      1、几个概念:事务回滚,保存点,事务提交的梳理:

        A、事务回滚:执行回滚操作会将操作回滚到指定的保存点;

        B、保存点:标记并保存着jdbc操作的一系列状态,每个保存点对应一个状态;

        C、事务提交:正式将所有操作的命令集提交给数据库,此时命令集操作正式生效。

      2、首先说保存点类(实际是个接口来)--SavePoint。保存点保存有某个sql执行前的一个状态;它通过connection.setSavePoint来获得;

        然后,在设置保存点后,如果执行过程知道某一个步骤发生了异常,可以回滚到异常发生前的那个执行状态,避免前面的执行业务失效(当然,这前提是失败的业务和前面成功执行的业务之间没有关系,否则,不能只是回滚部分,要回滚全部!),事务回滚调用connection.roolBack进行操作;

        在事务中,所有的sql命令集都不会自动提交,需要调用connection.commit进行提交。具体请看下面的代码:

    //事务说明方法
    	public void transaction(){
    		Connection conn = null;
    		Statement stmt1 = null;
    		Statement stmt2 = null;
    		Savepoint point = null;
    		try{
    			String sql1 = "update table1 set ...";
    			String sql2 = "update table2 set ...";
    			Class.forName("com.mysql.jdbc.Driver");
    			conn = DriverManager.getConnection("jdbcRul","username","userpass");
    			//如果要自己控制事务,需要将默认提交设置为false
    			conn.setAutoCommit(false);
    			stmt1 = conn.createStatement();
    			stmt1.executeUpdate(sql1);
    			point = conn.setSavepoint();
    			stmt2.executeUpdate(sql2);
    			//需要显式提交
    			conn.commit();
    		}catch (SQLException e) {
    		// TODO: handle exception
    			//捕获到异常,进行事务回滚
    			try {
    				conn.rollback();//这是表示所有事务都回滚了,当然也可以只是回滚到某一点
    				//conn.rollback(point);//这个是对应回滚到stmt2执行前
    			} catch (SQLException e1) {
    				// TODO Auto-generated catch block
    				e1.printStackTrace();
    			}
    		} catch (ClassNotFoundException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}finally{
                //关闭操作,省略
              } }

      事务回滚其实要结合具体的业务进行考虑,所以很多时候是挺复杂的,所以这里不详细讨论如何进行事务设置,毕竟,我功力也没达到那个水平。

    四、使用jdbc与数据库交互时需要注意的是:使用完后,一定要记得关闭所有数据库相关对象!因为数据库连接其实也涉及到IO连接,所以,不关闭的话很容易造成内存泄露。关闭的顺序是:先Result,然后Statement,最后Connection,而且必须写在finally 块里面。

      

  • 相关阅读:
    ubuntu下cmake自动化编译的一个例子
    KL变换和PCA的数学推导
    tensorflow c++ API加载.pb模型文件并预测图片
    tensorflow c++接口的编译安装与一些问题记录
    深度增强学习--总结下吧
    深度增强学习--DPPO
    深度增强学习--DDPG
    深度增强学习--A3C
    tomcat远程调试
    springboot问题记录
  • 原文地址:https://www.cnblogs.com/lcplcpjava/p/6582091.html
Copyright © 2011-2022 走看看