zl程序教程

您现在的位置是:首页 >  Java

当前栏目

Java小技能:Java Data Base Connectivity

2023-02-18 16:46:10 时间

引言

JDBC是一种用来在Java程序中执行SQL的API,它为java连接数据库提供了一组接口和类,可以为多种关系数据库提供统一访问。

SUN公司只是在JDBC当中定义了具体的接口,而JDBC接口的具体的实现是由数据库提供厂商去写具体的实现, 比如说Connection对象,不同的数据库的实现方式是不同的。

I. 预备知识

1.1 JDBC

JDBC有一组应用程序的API,用来开发java连接数据库的应用程序;jdbc驱动api提供给数据库厂商,数据库厂商负责实现底层的编码。

1.2 对象关系映射(ORM)

使用传统的JDBC的项目已经越来越少了,曾经的model1和model2已经被MVC给代替了。如果用传统的JDBC写项目你不得不去管理你的数据连接、事物等。而用ORM框架一般程序员只用关心执行SQL和处理结果集就行了。比如SpringJdbcTemplateHibernateHibernateTemplate提供了一套对dao操作的模版,对JDBC进行了轻量级封装。开发人员只需配置好数据源事物之后,开发仅需要提供SQL、处理SQL执行后的结果,其他的事情都交给框架去完成了。

ORM(Object Relational Mapping)框架采用元数据来描述对象与关系映射的细节,元数据一般采用XML格式,并且存放在专门的对象一映射文件中。 只要提供了持久化类与表的映射关系,ORM框架在运行时就能参照映射文件的信息,把对象持久化到数据库中。 当前ORM框架主要有五种:Hibernate(Nhibernate)iBatismybatisEclipseLinkJFinal

JPA全称Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中,是一个ORM规范,Hibernate是JPA的具体实现。

1.3 Java对象持久化(Java Data Object)

JDO(Java Data Object )是Java对象持久化的规范,用于存取某种数据仓库中对象的标准化API。

JPA可以依靠JDBC对JDO进行对象持久化,而ORM只是JPA当中的一个规范,我们常见的Hibernate、Mybatis和TopLink都是ORM的具体实现。

1.4 传统的JDBC

完成一次查询操作,java和数据库的交互操作:

  • 准备JDBC驱动
  • 加载驱动
  • 获取连接
  • 预编译SQL
  • 执行SQL
  • 处理结果集
  • 依次释放连接

II JDBC使用步骤

连接数据库的过程:JDBC Api ->driver;

2.1 准备连接数据库的相关数据

  1. 获得当前数据库连接的用户名和密码
  2. 获得数据库服务器的地址(ip)
  3. 获得数据库连接的端口号: oracle默认的是1521,mysql默认端口号是3306。
  4. 数据库的实例sid,即数据库名称。
  5. 获得连接字符串:url=jdbc:oracle:thin:@ip:port:sidurl=jdbc:mysql:@ip:port:sid
  6. 获得对应数据库的驱动:classes12.jar或ojdbc14.jar

2.2 书写jdbc程序步骤

  • 加载oracle驱动:导入oracle数据库的驱动oracle.jdbc.OracleDriver或者oracle.jdbc.driver.OracleDriver
class.forname("oracle.jdbc.OracleDriver");//通过反射加载驱动程序,在内存中创建oracleDriver的实例

  • 通过驱动管理器获得连接对象
Connection conn=DriverManager.getConnection()url,user,password;;//通过驱动管理器获得连接对象

  • 创建statement或preparestatement对象

生成statement实现类对象来编译sql,并将sql语句输送到数据库

// 方式一
Statement stmt=conn.createStatemenr();
//方式二
PreparedStatement pstmt=conn.prepareStatement(sql);//sql字符型不用加分号来结束
  • 执行sql,接收返回结果
//方式一:
ResultSet rs=stmt.executeQuery(sql);;

//方式二:
ResultSet rs=pstmt.executeQuery();

  • 循环遍历结果集
while(rs.next()){
 int empno=rs.getInt(String columnName);

}
  • 在finally中关闭资源
if(rs!=null){rs.close();}

if(pstmt!=null){pstmt.close();}

if(conn!=null){rconnclose();}

  1. prepareCall(String sql); 用于调用存储过程
  2. conn.setAutoCommit(false); 设置当前jdbc的事物处理为手动
conn.rollback();

conn.commit();

2.3 代码示例

package com.iosre.jdbc;
 
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
 
public class JDBCDemp {
 
 public static void main(String[] args) {
  jdbcTest(5438,"hello");
 }
 
 public static void jdbcTest(int id,String name){
  String url="jdbc:oracle:thin:@localhost:1521:XE";
  String user="hello";
  String password="123456";
  //String sql="delete from emp where empno="+id;
  String sql = "insert into emp(empno,ename) values("+id+",'"+name+"')";
  System.out.println(sql);
  Connection  conn=null;
  PreparedStatement pstmt=null;
  ResultSet rs =null;
  //1.通过反射加载驱动程序,驱动程序的类名,在内存中创建驱动程序的对象
  //oracle.jdbc.OracleDriver  
  //或者  oracle.jdbc.driver.OracleDriver
  try {
   Class.forName("oracle.jdbc.OracleDriver");
   //new oracle.jdbc.OracleDriver();
   conn = DriverManager.getConnection(url, user, password);
   //生成statement对象编译SQL
   //pstmt = conn.prepareStatement("select * from emp");
   
   Statement stmt = conn.createStatement();
   //执行SQL
   //rs = stmt.executeQuery("select * from emp");
   int num = stmt.executeUpdate(sql);
   
   if(num>0){
    System.out.println("删除成功");
   }
   /*while(rs.next()){
    //int empno = rs.getInt("empno");
    int empno = rs.getInt(1);
    String ename = rs.getString(2);
    System.out.println(ename);
   }*/
   
  } catch (ClassNotFoundException e) {
   
   e.printStackTrace();
  } catch (SQLException e) {
   
   e.printStackTrace();
  }finally{
   try {
    if(rs!=null){rs.close();}
    if(pstmt!=null){pstmt.close();}
    if(conn!=null){conn.close();}
   
    } catch (SQLException e) {
     
     e.printStackTrace();
    }
   }
 }
}

2.4 封装jdbc代码

package com.zhongx.jdbc;
 
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
 
public class ConnectionUtil {
 private static String url;
 private static  String user;
 private static String password;
 private static String driver;
 private static Properties prop = new Properties();
 //通过配置文件读取数据库 连接信息 
 //加载驱动创建对应驱动实例
 static{
  try {
   InputStream is = new FileInputStream("src/com/zhongx/jdbc/db.properties");
   prop.load(is);
   url = prop.getProperty("url");
   user = prop.getProperty("user");
   password = prop.getProperty("password");
   driver = prop.getProperty("driver");
   Class.forName(driver);
   
  } catch (FileNotFoundException e) {
   
   e.printStackTrace();
  } catch (IOException e) {
   
   e.printStackTrace();
  } catch (ClassNotFoundException e) {
   
   e.printStackTrace();
  }
 }
 
 public static Connection getConnection() throws SQLException{
  return DriverManager.getConnection(url, user, password);
 }
 public static void close(Connection conn,Statement stmt,ResultSet rs) throws SQLException{
  if(rs!=null){rs.close();}
  if(stmt!=null){stmt.close();}
  if(conn!=null){conn.close();}
 }
}

注释版本

//driverClass=com.mysql.jdbc.Driver
  //1.获取Driver实现类的对象
//  Class clazz = Class.forName("com.mysql.jdbc.Driver");
  //1.读取配置文件信息
  InputStream is = ConnectionTest.class.getClassLoader().getResourceAsStream("jdbc.properties");
  Properties pros = new Properties();
  pros.load(is);
  String user = pros.getProperty("user");
  String password = pros.getProperty("password");
  String url = pros.getProperty("url");
  String driverClass = pros.getProperty("driverClass");
  //2.加载驱动
  Class.forName(driverClass);
  //3.获取连接
  Connection conn = DriverManager.getConnection(url, user, password);

2.5 预编译sql

预编译sql会将sql语句预先编译号,执行的时候直接传递参数,不需要再次编译。

PreparedStatement是Statement的子接口,它与Statement的区别有:

  1. 程序的可读性和可维护性更好
  2. 更安全
  3. 执行效率高
  • PreparedStatement 允许数据库预编译sql语句,这样在随后的运行中可以节省时间,并增加了查询的可读性;
  • Statement每次执行sql语句相关的数据库都要执行sql语句的编译。

III JDBC涉及的类和接口

java.sql.Connection 接口

  • createStatement() 获得Statement
  • prepareStatement(String sql) 获得preparedStatement
  • prepareCall(String sql) 调用存储过程

java.sql.DriverManager 类

  • getConnection(String url, String user, String password)

java.sql.Statement 接口

  • executeQuery(String sql) 执行DQL语句
  • executeUpdate(String sql) 执行DML语句
  • executeBatch() 批处理执行SQL

java.sql.PreparedStatement 接口

  • setXXX方法 :用来动态传参

java.sql.ResultSet 接口

  • next() 默认ResultSet对象指向记录的光标在第一条的前面
  • getXXX(String/int) 获得对应字段的值
  • getInt() 接收整数类型
  • getDouble() 接收浮点数据
  • getString()接收字符串类型
  • sql.Date getDate() 接收Date类型数据字段

see also

gzh: iOS逆向