JDBC连接数据库步骤

JDBC连接数据库步骤描述:

一、JDBC连接简要步骤:

1.加载驱动器、2.创建connection对象、3.创建Statement对象、4.Statement(executeQuery方法)执行sql语句、5.创建处理结果集对象ResultSet、6.处理异常,关闭所有JDBC对象资源(注意关闭顺序与声明顺序相反,先关结果集对象、后关statement对象、最后关connection对象)。

二、JDBC连接准备:

首先准备JDBC所需的四个参数(user,password,url,driverClass)

(1)user用户名

(2)password密码

(3)URL定义了连接数据库时的协议、子协议、数据源标识,它们之间用冒号隔开。 书写形式: 协议:子协议:数据源标识

  • 协议:在JDBC中总是以jdbc开始
  • 子协议:是桥连接的驱动程序或是数据库管理系统名称。
  • 数据源标识:标记找到数据库来源的地址与连接端口。

        例如:(MySql的连接URL)
        jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF8 ;
        解释:"jdbc(这是协议以jdbc开头):mysql(这是子协议,数据库管理系统称)://localhost(数据库来源地址):3306(目标端口)/test(要查询的表)?",而"useUnicode=true&characterEncoding=UTF8";添加这个是为了防止乱码,指定使用Unicode字符集 ,且使用UTF-8来编辑。

(4)driverClass连接数据库所需的驱动。

(5)JDBC的url实现负载均衡,多节点部署数据库的url拼写方式:

dbc:oracle:thin:@

(description=(TRANSPORT_CONNECT_TIMEOUT=1)

(address_list=(load_balance=off)(failover=on)

(address=(protocol=tcp)(host=RAC1-vip)(port=1521))

(address=(protocol=tcp)(host=RAC2-vip)(port=1521))

(address=(protocol=tcp)(host=RAC3-vip)(port=1521)))

(connect_data=(service_name=orcl)(failover_mode=(type=select)(method=basic)))

)

解释:LOAD_BALANCE=OFF,客户端进程首先会尝试连接RAC1-vip,如果连不上,则会尝试RAC2-vip,如果再连不上就尝试RAC3-vip。如果设置为ON则会随机的选择一个做均衡负载。LOAD_BALANCE=on负载均衡,FAILOVER = on 失败自动切换,这两个参数是搭配在一起的。

三、JDBC连接代码实现:

1、加载JDBC驱动程序:

        在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机),有三种方法,此处通过java.lang.Class类的静态方法forName(String className)实现。成功加载后,会将Driver类的实例注册到DriverManager类中。

try{//加载MySql的驱动类    
         Class.forName("com.mysql.jdbc.Driver") ;    
    }catch(ClassNotFoundException e){    
         System.out.println("找不到驱动程序类 ,加载驱动失败!");    
         e.printStackTrace() ;    
    }

2、创建数据库的连接

  • 要连接数据库,需要向java.sql.DriverManager请求并获得Connection对象,该对象就代表一个数据库的连接。
  • 使用DriverManager的getConnectin(String url , String username , String password )方法传入指定的欲连接的数据库的路径、数据库的用户名和密码来获得。
//连接MySql数据库,用户名和密码都是root    
     String url = "jdbc:mysql://localhost:3306/test" ;     
     String username = "root" ;    
     String password = "root" ;    
     try{    
          Connection con = DriverManager.getConnection(url , username , password ) ;    
     }catch(SQLException se){    
          System.out.println("数据库连接失败!");    
          se.printStackTrace() ;    
     }

3.创建一个Statement对象

要执行SQL语句,必须先获得java.sql.Statement实例。

Statement实例分为以下3 种类型:

  • 执行静态SQL语句。通常通过Statement实例实现。
  • 执行动态SQL语句。通常通过PreparedStatement实例实现。
  • 执行数据库存储过程。通常通过CallableStatement实例实现。

具体的实现方式:

//Connection接口下的方法:Statement createStatement()
Statement stmt=conn.createStatement();
PreparedStatement pstmt = conn.PreparedStatement() ;
CallableStatement cstmt =  conn.prepareCall("{CALL demoSp(? , ?)}") ;

其中PreparedStatement最常用,他们的区别如下:

    1、statement每次执行sql语句,数据库都要执行sql语句的编译,而PreparedStatement可以使用占位符,预编译处理大量相似sql语句,比Statement效率高。
    2、使用 Statement 对象。在对数据库只执行一次性存取时用 Statement 对象进行处理。因为PreparedStatement 对象的开销比Statement大,对于一次性操作并不会带来额外的好处。
    3、执行许多SQL语句的JDBC程序产生大量的Statement和PreparedStatement对象。通常认为PreparedStatement对象比Statement对象更有效,特别是如果带有不同参数的同一SQL语句被多次执行的时候。PreparedStatement对象允许数据库预编译SQL语句,这样在随后的运行中可以节省时间并增加代码的可读性。
    4、 PreparedStatement 减少编译次数。提高了安全性(阻止了SQL注入)
    5、PreparedStatement 可以实现操作Blob类型、Clob类型的数据

详细见:(20条消息) preparedStatement和Statement区别_minose的博客-CSDN博客_preparedstatement和statement的区别

4、Statement(executeQuery方法)执行SQL语句

Statement接口提供了三种执行SQL语句的方法:executeQuery 、executeUpdate和execute

  • ResultSet executeQuery(String sqlString):执行查询数据库的SQL语句,返回一个结果集(ResultSet)对象。
  • int executeUpdate(String sqlString):用于执行INSERT、UPDATE或 DELETE语句以及SQL DDL语句,如:CREATE TABLE和DROP TABLE等
  • execute(sqlString):用于执行返回多个结果集、多个更新计数或二者组合的语句。
boolean flag = stmt.execute(String sql) ;----执行SQL语句,如果返回值是结果集则为true,否则为false
ResultSet rs = stmt.executeQuery("SELECT * FROM ...") ;----执行SQL语句,返回值为ResultSet
int rows = stmt.executeUpdate("INSERT INTO ...") ;----执行SQL语句,返回值为所影响的行数

5、遍历结果集

根据返回结果分为两种情况:

(1)执行更新返回的是本次操作影响到的记录数。

(2)执行查询返回的结果是一个ResultSet对象。

  • ResultSet包含符合SQL语句中条件的所有行,并且它通过一套get方法提供了对这些行中数据的访问。

        ResultSet接口下常见的方法:

 	beforeFirst()----将游标移动到ResultSet中第一条记录(的前面)
    afterLast()----将游标移动到ResultSet中最后一条记录(的后面)
    absolute(intcolumn)----将游标移动到相对于第一行的指定行,负数则为相对于最后一条记录
    previous()----将游标上移一行
    next()----将游标下移一行
    ResultSet.TYPE_SCROLL_SENSITIVE----结果集可以滚动
    ResultSet.CONCUR_READ_ONLY ----结果集只读,不能修改
  • 使用结果集(ResultSet)对象的访问方法获取数据,ResultSet对象的getXxxx方法,取决于数据库中表的字段的类型,例如:varchar2 对应方法是getString ,如果是 integer 对应方法是getInt/getLong
 While(rs.next()){
 	rs.getInt(columnIndex);  //通过列的序号来获取字段的值
 	rs.getString(columnName);//通过列的名字来获取字段的值
}

6、处理异常,关闭JDBC对象资源

操作完成以后要把所有JDBC对象全都关闭,以释放JDBC资源,关闭顺序和声明顺序相反:

  1. 先关闭requestSet结果集
  2. 再关闭preparedStatement对象
  3. 最后关闭connection连接对象
if(rs !=null){   // 关闭结果集    
   try {
      rs.close();
   } catch (SQLException e) {
      e.printStackTrace();
   }
}    

if(stmt !=null){   // 关闭statement声明    
   try {
      stmt.close();
   } catch (SQLException e) {
      e.printStackTrace();
   }
}

if(conn !=null){  // 关闭连接对象    
   try {
      conn.close();
   } catch (SQLException e) {
      e.printStackTrace();
   }
}

JDBC利用反射连接数据库代码实例:

基本原理;保存数据时,把需要保存的对象的属性值全部取出来再拼凑sql语句。查询时,将查询到的数据全部包装成一个java对象。

  1、首先数据库的有一个表

        假设数据库名称为:mysql_test_jdbcinstance,里面有一个表userinfo。如图:

JDBC连接数据库步骤_第1张图片

2、创建对应的pojo对象类:

package com.test.workTest.JdbcClassInstance;

/**
 * 1.数据库表对应的表的对象类
 */
public class UserInfo {
    private int id;
    private String name;
    private String pwd;
    private int age;

    @Override
    public String toString() {
        return "UserInfo [id=" + id + ", name=" + name + ", pwd=" + pwd + ", age="
                + age + "]";
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

}

3、编写获得数据库连接的工厂类:

package com.test.workTest.JdbcClassInstance;
import java.sql.Connection;
import java.sql.DriverManager;
/**
 * 2.获得数据库连接的工厂类:
 */
public class ConnectDBFactory {
    public static Connection getDBConnection() {
        Connection conn = null;
        try {
            /**
             * 你自己的数据库参数,详见本博客上面描述
             */
            Class.forName("com.mysql.jdbc.Driver");
            String url = "jdbc:mysql://localhost:3306/mysql_test_jdbcinstance";
            String user = "root";
            String password = "***";
            conn = DriverManager.getConnection(url, user, password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conn;
    }
}

4、编写操作数据库的dao类

package com.test.workTest.JdbcClassInstance;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

/**
 * 3.操作数据库的dao类
 */
public class TableSqlDao {
    /**
     * 解析出保存对象的sql语句
     * @param object:需要保存的对象
     * @return:保存对象的sql语句
     */
    public static String getSaveObjectSql(Object object) {
        // 定义一个sql字符串
        String sql = "insert into ";
        // 得到对象的类
        Class c = object.getClass();
        // 得到对象中所有的方法
        Method[] methods = c.getMethods();
        // 得到对象中所有的属性
        Field[] fields = c.getFields();
        // 得到对象类的名字
        String cName = c.getName();
        // 从类的名字中解析出表名
        String tableName = cName.substring(cName.lastIndexOf(".") + 1,
                cName.length());
        sql += tableName + "(";
        List mList = new ArrayList();
        List vList = new ArrayList();
        for (Method method : methods) {
            String mName = method.getName();
            if (mName.startsWith("get") && !mName.startsWith("getClass")) {
                String fieldName = mName.substring(3, mName.length());
                mList.add(fieldName);
                System.out.println("字段名字----->" + fieldName);
                try {
                    Object value = method.invoke(object, null);
                    System.out.println("执行方法返回的值:" + value);
                    if (value instanceof String) {
                        vList.add("\"" + value + "\"");
                        System.out.println("字段值------>" + value);
                    } else {
                        vList.add(value);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        for (int i = 0; i < mList.size(); i++) {
            if (i < mList.size() - 1) {
                sql += mList.get(i) + ",";
            } else {
                sql += mList.get(i) + ") values(";
            }
        }
        for (int i = 0; i < vList.size(); i++) {
            if (i < vList.size() - 1) {
                sql += vList.get(i) + ",";
            } else {
                sql += vList.get(i) + ")";
            }
        }
        return sql;
    }

    public static List getDatasFromDB(String tableName, int Id) {
        return null;
    }

    /**
     * 将对象保存到数据库中
     * @param object:需要保存的对象
     * @return:方法执行的结果;1:表示成功,0:表示失败
     */
    public int saveObject(Object object) {
        Connection con = ConnectDBFactory.getDBConnection();
        String sql = getSaveObjectSql(object);
        PreparedStatement psmt = null;
        try {
            // Statement statement=(Statement) con.createStatement();
            psmt = con.prepareStatement(sql);
            psmt.executeUpdate();
            return 1;
        } catch (SQLException e) {
            e.printStackTrace();
            return 0;
        } finally {
            if(psmt !=null){   // 关闭statement声明
                try {
                    psmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if(con !=null){  // 关闭连接对象
                try {
                    con.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    /**
     * 从数据库中取得对象
     * @param:对象所属的类
     * @param:对象的id
     * @return:需要查找的对象
     */
    public Object getObject(String className, int Id) throws SQLException {
        // 得到表名字
        String tableName = className.substring(className.lastIndexOf(".") + 1,
                className.length());
        // 根据类名来创建Class对象
        Class c = null;
        try {
            c = Class.forName(className);

        } catch (ClassNotFoundException e1) {

            e1.printStackTrace();
        }
        // 拼凑查询sql语句
        String sql = "select * from " + tableName + " where Id=" + Id;
        System.out.println("查找sql语句:" + sql);
        // 获得数据库链接
        Connection con = ConnectDBFactory.getDBConnection();
        // 创建类的实例
        Object obj = null;
        Statement stm = null;
        // 得到执行查寻语句返回的结果集
        ResultSet set = null;
        // 得到对象的方法数组
        Method[] methods = null;
        try {
            stm = con.createStatement();
            set = stm.executeQuery(sql);
            methods = c.getMethods();
            // 遍历结果集
            while (set.next()) {
                obj = c.newInstance();
                // 遍历对象的方法
                for (Method method : methods) {
                    String methodName = method.getName();
                    // 如果对象的方法以set开头
                    if (methodName.startsWith("set")) {
                        // 根据方法名字得到数据表格中字段的名字
                        String columnName = methodName.substring(3,
                                methodName.length());
                        // 得到方法的参数类型
                        Class[] parmts = method.getParameterTypes();
                        if (parmts[0] == String.class) {
                            // 如果参数为String类型,则从结果集中按照列名取得对应的值,并且执行改set方法
                            method.invoke(obj, set.getString(columnName));
                        }
                        if (parmts[0] == int.class) {
                            method.invoke(obj, set.getInt(columnName));
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(set !=null){   // 关闭结果集
                try {
                    set.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if(stm !=null){   // 关闭statement声明
                try {
                    stm.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(con !=null){  // 关闭连接对象
                try {
                    con.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return obj;
    }
}

5、测试类测试效果:

package com.test.workTest.JdbcClassInstance;

import java.sql.SQLException;

/**
 * 测试类
 */
public class SqlSpellTest {
    public static void main(String args[]) throws SQLException {
        //获得TableSqlDao对象
        TableSqlDao session = new TableSqlDao();
        //创建一个UserInfo对象
        UserInfo user = new UserInfo();
        //设置对象的属性
        user.setId(1);//每次执行都需要改下ID,因为数据库ID字段唯一
        user.setAge(24);
        user.setPwd("123654");
        user.setName("oneGoodMan");
        //将对象保存到数据库中
        int sql = session.saveObject(user);
        System.out.println("保存对象的sql语句:" + sql);
        //查找对象,这个形参className需要带上你自己pojo类的包地址
        UserInfo userInfo = (UserInfo) session.getObject(
                "com.test.workTest.JdbcClassInstance.UserInfo", 1);
        System.out.println("获取到的信息:" + userInfo);

    }
}

你可能感兴趣的:(java基础,java,面试,sql,数据库)