JDBC是什么?
JDBC(Java数据库连接)是一组用于执行SQL语句的Java API,Java只提供接口,具体的数据库驱动程序类是由各数据库厂商去实现。我们只需使用JDBC接口中提供的方法就能对多种关系数据库提供统一访问,是非常典型的面向接口编程。如果使用的是标准SQL语句,就能做到不修改代码中的SQL语句,实现跨数据库,非常方便。
JDBC常用类与接口
DriverManager:用于管理JDBC数据库jar包的驱动类,主要方法:getConnection(),返回Connection对象。Connection:代表和数据库建立连接的对象。要访问数据库就必须先获得该对象。主要有以下三个方法:
- createStatement():返回Statement对象;
- prepareStatement():返回PreparedStatement对象,PreparedStatement能对SQL语句进行预编译;
- prepareCall():返回CallableStatement对象,该对象用于调用存储过程。
Statement:用于执行SQL语句。主要方法如下:
- executeQuery(String sql):执行select语句,返回ResultSet(结果集)对象;
- executeUpdate(String sql):执行insert、update、delete语句,返回受影响的行数;
- execute(String sql):可以执行任何SQL语句。如果结果是ResultSet对象则返回true,是其他的就返回false。
PreparedStatement(预编译SQL执行对象)
- 允许预编译SQL语句,使用时只需设置参数,无需重新编译SQL语句,因此性能比较快。预编译语句设置参数方法:setXxx(int parameterIndex, Xxx value),根据传入的参数类型采用不同的setXxx();
- 该对象是Statement的子接口,三大方法和Statement对象一致。但预编译对象是先设置好参数,之后直接调用方法,无需传入sql语句;
- PreparedStatement在Java8中增加了executeLargeUpdate()方法,当受影响的行数超过Integer.MAX_VALUE时,使用该方法效率会更高;
- 使用预编译对象可以避免SQL注入,而且减少sql字符串拼接,所以应该作为使用首选。
ResultSet(结果集对象)
ResultSet除了具有存储查询结果功能,同时还具有操纵数据的功能。
ResultSet对象具有指向其当前数据行的光标,等同于记录指针,光标第一次是置于第一行之前。ResultSet中的方法大致分为几种:
- 获取该行数据:getString("列名")、getXxx(int index),(列索引从1开始);
- 移动光标:next()、previous()、absolute()等方法,可移动则返回true,否则false;
- 判断光标位置:isFirst()、isLast()等方法;
- 操作当前行的数据:deleteRow()、insertRow()、updateRow()....。
- 除了以上方法,在Statement对象中可以传入ResultSet字段变量来决定结果集是否可回滚和不可回滚。
以上类和接口中的方法只提供了一小部分,还有许多方法这里就不一一详述,但会在后续的使用案例中运用到。
关于JDBC相关类的使用,没什么难点,不需要花太多时间理解,当它是一个工具类就可以了。但是SQL语句中最基础的增删改查语句必须会,不然无法和数据库交互。虽然有的已经封装好了,但只有知道了怎么使用,才好去做修改。下面提供几个如何连接数据库的案例,具体代码的注释也提供了。
JDBC访问数据库流程
- 建立程序和数据库之间的连接---->执行SQL语句---->处理执行结果
- 加载数据库驱动jar包:使用Class.forName()方法,Class.forName()会初始化驱动类,驱动类开始注册;
- 建立连接:使用DriverManager.getConnnection()方法返回Connection对象;
- 执行数据库操作:使用Connection的方法获取Statement对象,用Statement对象执行sql语句;
- 获取执行结果:查询语句返回ResultSet(结果集),其他操作语句返回影响行数。
JDBC连接数据库案例
//1.常规JDBC连接方式,参数写死在代码中。
public class JdbcUtils {
private static String Driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
private static String url = "jdbc:sqlserver://localhost:1433;DatabaseName=TestDB";
private static String user = "sa";
private static String password = "1234";
private static Connection conn = null;
public JdbcUtils() {}
//静态代码块加载驱动类,仅执行一次
static {
try {
Class.forName(Driver);
System.out.println("成功加载驱动类……");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//获取Connection对象
public static Connection getConnection() {
if(conn == null) {
try {
conn = DriverManager.getConnection(url,user,password);
} catch (SQLException e) {
e.printStackTrace();
}
}
System.out.println("获取Connection连接对象成功!");
return conn;
}
}
//2.通过Properties类加载JDBC,参数写在外部文件中
public class JdbcUtils2 {
private static Properties prop = new Properties();
private static FileInputStream fis = null;
private static Connection con = null;
//静态代码块加载驱动类,仅执行一次
static {
try {
fis = new FileInputStream("JdbcJar/jdbcProp.txt");//属性文件是放在项目文件夹下的
prop.load(fis);
Class.forName(prop.getProperty("driver"));
System.out.println("数据库驱动类已加载……");
} catch (Exception e) {
e.printStackTrace();
}
}
//获取Connection对象
public static Connection getConnection() {
if(con == null) {
try {
con = DriverManager.getConnection(prop.getProperty("url"), prop);
} catch (SQLException e) {
e.printStackTrace();
}
}
System.out.println("已成功连接数据库,并返回连接对象~");
return con;
}
}
//3.使用URLClassLoader类来加载JDBC,无需导入Jar包到项目中
public class JdbcUtils3 {
private static Connection con = null;
private static Properties prop = new Properties();
public static Connection getConnection() throws Exception {
URL[] urls = new URL[]{ new URL("file:///E:/sqljdbc4.jar") };//定位Jar包
URLClassLoader ucl = new URLClassLoader(urls);
try {
//加载Jar包驱动类,和Class.forName()作用相同
Class cla = ucl.loadClass("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Driver driver = (Driver)cla.newInstance();//通过反射实例化驱动类对象
FileInputStream fis = new FileInputStream("F://jdbcProp.txt");
prop.load(fis);//载入属性文件
//返回数据库连接对象赋值给con对象
con = driver.connect(prop.getProperty("url"), prop);
System.out.println("获得数据库连接对象!");
} catch (Exception e) {
e.printStackTrace();
}
return con;
}
}
属性文件是以Key-Value形式来存储值,但getConnection方法只会自动获取user和password关键字,如果账号密码使用别的key,则需要使用getProperty(String key)来获取值。
- 使用说明:常规方式和使用Properties类差别不大,只是参数存放的位置不同。但使用时项目需要导入数据库的jar包,不然Class.forName()没法找到驱动类。
- 而通过URLClassLoader可以在运行时获取jar包,然后再加载驱动类。所以jar包可以通过很多来源加载,无需提前导入。当然该类的作用不仅仅于此,但在此处仅提供一个思路。
由于Statement、PreparedStatement和ResultSet的运用案例代码比较多,所以放在下一章中,地址:JDBC执行增删改查操作案例