JDBC基础
一、什么是java的JDBC
jdbc是java中用于连接数据库的一系列接口,这些接口的实现类需要各个数据库厂商自己去定义。在连接数据库时,需要通过java的反射将具体的驱动添加到jvm里去。
二、JDBC的使用
1、添加驱动,将驱动反射到jvm
2、使用DriverManager,创建连接,生成Connection
3、通过Connection选择合适的statement
4、通过statement执行sql语句,操作结果集。
以sqlserver为例的JDBC调用代码:
package produce; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.sql.Types; import javax.management.Query; import org.json.JSONObject; import org.junit.After; import org.junit.Before; import org.junit.Test; public class ProduceTest { /* * 数据库连接信息 */ String driverName = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; String dbURL = "jdbc:sqlserver://127.0.0.1:1433;DatabaseName=custom"; String userName = "sa"; String userPwd = "root"; /* * 通用实例 */ Connection dbConn = null; Statement stat = null; PreparedStatement preparedStatement = null; CallableStatement callableStatement = null; ResultSet rs = null; /** * 连接数据库 */ @Before public void befor() { try { /* * 加载驱动 */ Class.forName(driverName); System.out.println("加载驱动成功!"); } catch (Exception e) { e.printStackTrace(); System.out.println("加载驱动失败!"); } try { /* * 创建连接 */ dbConn = DriverManager.getConnection(dbURL, userName, userPwd); System.out.println("连接数据库成功!"); } catch (Exception e) { e.printStackTrace(); System.out.print("SQL Server连接失败!"); } } /** * 执行查询 */ @Test public void Query() { try { stat = dbConn.createStatement(); String sql = "select * from emp"; rs = stat.executeQuery(sql); while (rs.next()) { int id = rs.getInt(1); System.out.println(id); } } catch (SQLException e) { e.printStackTrace(); System.out.println("查询失败!"); } } @After public void after() { if (dbConn != null) { try { dbConn.close(); System.out.println("数据库连接已断开!"); } catch (SQLException e) { System.out.println("SQL Server关闭连接失败!"); e.printStackTrace(); } } } }
三、三种statement的区别
jdbc提供了三中statement可供选择,它们的继承结构如上图。其中Statement只能执行静态的sql语句;PreparedStatement可以执行预编译的sql,参数动态的传递,并且可以防止sql注入;CallableStatement是为存储过程调用提供的。
1、Statement提供相应的执行sql的方法
获取方式:Statement createStatement()
boolean execute(String sql),执行给定语句,不返回结果。
ResultSet executeQuery(String sql),执行给定语句,返回ResultSet。
int executeUpdate(String sql),执行给定语句,受影响的行数。
2、PreparedStatement提供的相关方法
获取方式:PreparedStatementprepareStatement(String sql)
booleanexecute(),执行此 PreparedStatement对象中的SQL语句,这可能是任何类型的SQL语句。
ResultSetexecuteQuery(),执行此 PreparedStatement对象中的SQL查询,并返回查询 PreparedStatement的 ResultSet对象。
intexecuteUpdate(),执行在该SQL语句PreparedStatement对象,它必须是一个SQL数据操纵语言(DML)语句,如INSERT , UPDATE或DELETE ; 或不返回任何内容的SQL语句,例如DDL语句。返回受影响的行数。
示例:
/** * 查询示例,使用PreparedStatement查询emp表 */ @Test public void preparedStatementquery(){ String sql = "select * from emp where age=?;"; try { preparedStatement = dbConn.prepareStatement(sql); preparedStatement.setInt(1, 23); rs = preparedStatement.executeQuery(); while(rs.next()){ System.out.println(rs.getString(1)); System.out.println(rs.getString(2)); System.out.println(rs.getInt(3)); System.out.println(rs.getString(4)); // System.out.println("id:"+rs.getString("id")); // System.out.println("name:"+rs.getString("name")); // System.out.println("address:"+rs.getString("address")); System.out.println("---------------------------------------------------"); } System.out.println("查询完成!"); } catch (SQLException e) { e.printStackTrace(); System.out.println("结果集操作失败!"); } }
3、CallableStatement提供的相关方法
继承于PreparedStatement的CallableStatement接口,并没有新增执行方法。主要为存储过程添加了注册返回参数、返回值类型的方法,以及获取返回参数和返回值的方法。
存储过程:
create procedure get_emps_by_age( @age int = 5, @count int output ) as begin select @count=count(*) from emp where age=@age select * from emp where age=23 select * from emp where age=@age if @count>0 begin return 1 end else begin return 0 end end go
代码:
/** * 调用存储过程,设置输入输出参数,接收返回值,多个结果集 * */ @Test public void procedureNoArgumentWithResultSet(){ //没有参数时,可使用exec,不加{},即: exec add_emp_copy //直接写存储过程名调用:add_emp_copy //使用call时必须加(),即使没参数 //=前面的?是返回值,即是存储过程里return的值 String sql = "{?=call get_emps_by_age(?,?)}"; try { callableStatement = dbConn.prepareCall(sql); callableStatement.registerOutParameter(1, Types.INTEGER);//返回值类型 callableStatement.setInt(2, 22);//设置输入参数 callableStatement.registerOutParameter(3, Types.INTEGER);//设置输出参数类型 rs = callableStatement.executeQuery();//获取结果集 while(rs.next()) { System.out.println(rs.getString(1)); System.out.println(rs.getString(2)); System.out.println(rs.getString(3)); System.out.println(rs.getDate(6)); System.out.println("---------------------------------------------------"); } if(callableStatement.getMoreResults()) {//该方法检测是否还有多余的结果集,并自动跳到下一个结果集 rs = callableStatement.getResultSet(); while(rs.next()) { System.out.println(rs.getString(1)); System.out.println(rs.getString(2)); System.out.println(rs.getString(3)); System.out.println(rs.getDate(6)); System.out.println("---------------------------------------------------"); } } int returnArgument = callableStatement.getInt(1);//获取返回值 int backArgument = callableStatement.getInt(3);//获取返回参数值 System.out.println("返回值:"+returnArgument); System.out.println("返回参数值:"+backArgument); System.out.println("调用完成!"); } catch (SQLException e) { e.printStackTrace(); System.out.println("调用失败失败!"); } }
四、关于多个结果集的处理方式
在上例存储过程中,返回了多个结果集,使用getMoreResults()方法,可以判读statement中是否还有结果集,并指向下一个结果集。然后使用getResultSet()方法过去结果集。
这两个方法都是定义在Statement接口中的。
五、导包
jdbc的相关包是maven库中没有的,可以手动添加到项目里,也可以将jdbc的jar包导入到本地库中。
pom文件:
<dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>sqljdbc4</artifactId> <version>4.0</version> </dependency>
下载好相应的jar包,jar名字既是-Dfile参数。
使用cmd进入jar所在目录,输入以下命令
命令:
mvn install:install-file -Dfile=sqljdbc42.jar -Dpackaging=jar -DgroupId=com.microsoft.sqlserver -DartifactId=sqljdbc4 -Dversion=4.0
参数分别是文件名,包类型,以及pom的group、artifact、version。