javajdbc预编译res
㈠ 彻底搞懂JDBC的运行过程
前几天笔者发布了博客,手写mybatis彻底搞懂框架原理。为了帮助初学者更好理解mybatis框架,这次讲解一下java的JDBC的运行过程。
JDBC的作用
JDBC的全称是Java DataBase Connection,也就是Java数据库连接,我们可以用它来操作关系型数据库。JDBC接口及相关类在java.sql包和javax.sql包里。我们可以用它来连接数据库,执行SQL查询,存储过程,并处理返回的结果。
JDBC接口让Java程序和JDBC驱动实现了松耦合,使得切换不同的数据库变得更加简单。
JDBC的连接步骤
执行一次JDBC连接,分六个步骤进行:
1. 导入包
在程序中包含数据库编程所需的JDBC类。大多数情况下,使用 import java.sql.* 就足够了
2. 注册JDBC驱动程序
需要初始化驱动程序,这样就可以打开与数据库的通信。
3. 打开一个连接
使用DriverManager.getConnection()方法来创建一个Connection对象,它代表一个数据库的物理连接。
4. 执行一个查询
需要使用一个类型为Statement或PreparedStatement的对象(两者区别看后文),并提交一个SQL语句到数据库执行查询。
5. 从结果集中提取数据
这一步中演示如何从数据库中获取查询结果的数据。使用ResultSet.getXXX()方法来检索的数据结果
6. 清理环境资源
在使用JDBC与数据交互操作数据库中的数据后,应该明确地关闭所有的数据库资源以减少资源的浪费。本文使用了try with resources方式关闭资源,这是JDK7的语法糖,读者可自行搜索。
完整代码如下。
JDBC的最佳实践
JDBC是如何实现Java程序和JDBC驱动的松耦合?
JDBC API使用Java的反射机制来实现Java程序和JDBC驱动的松耦合。看一下上文的JDBC示例,你会发现所有操作都是通过JDBC接口完成的,而驱动只有在通过Class.forName反射机制来加载的时候才会出现。
这是Java核心库里反射机制的最佳实践之一,它使得应用程序和驱动程序之间进行了隔离,让迁移数据库的工作变得更简单。
Statement和PreparedStatement区别
预编译
创建时的区别:
执行时的区别:
由上可以看出,PreparedStatement有预编译的过程,已经绑定sql,之后无论执行多少次,都不会再去进行编译,而Statement 不同,如果执行多次,则相应的就要编译多少次sql,所以从这点看,PreparedStatement的效率会比Statement要高一些。PreparedStatement是预编译的,所以可以有效的防止SQL注入等问题
占位符
PrepareStatement可以替换变量在SQL语句中可以包含?,可以用?替换成变量。
而Statement只能用字符串拼接。
JDBC的ResultSet
在查询数据库后会返回一个ResultSet,它就像是查询结果集的一张数据表。
ResultSet对象维护了一个游标,指向当前的数据行。开始的时候这个游标指向的是第一行。如果调用了ResultSet的next()方法游标会下移一行,如果没有更多的数据了,next()方法会返回false。可以在for循环中用它来遍历数据集。
默认的ResultSet是不能更新的,游标也只能往下移。也就是说你只能从第一行到最后一行遍历一遍。不过也可以创建可以回滚或者可更新的ResultSet,像下面这样。
当生成ResultSet的Statement对象要关闭或者重新执行或是获取下一个ResultSet的时候,ResultSet对象也会自动关闭。
可以通过ResultSet的getter方法,传入列名或者从1开始的序号来获取列数据。
ResultSet的不同类型
根据创建Statement时输入参数的不同,会对应不同类型的ResultSet。如果你看下Connection的方法,你会发现createStatement和prepareStatement方法重载了,以支持不同的ResultSet和并发类型。
ResultSet对象有三种类型。
ResultSet有两种并发类型。
㈡ 在java中如何实现预编译
/*
* ProCompile.java *预处理要编译的文件,删除多余的空白,注释,换行,回车等
* Created on 2007年9月18日, 下午8:58 */ package javacompile; import java.io.*;
import java.util.regex.*;
import javax.swing.JOptionPane; /** * @com.junjian.sun public class PerCompile { File f = null;
String fileString = null;
Pattern p = null;
Matcher m = null;
String regex; //正则表达式 //初始化p
public PerCompile() {
regex ="(//.+)" + //(//.+) 对应单行注释
//"|(/\\*(.+\\n)+\\*/)"+ // 想对应多行注释... "|(\\r\\n)" + "|(\\n)"+//(\\r\\n)|(\\n)对应换行
"|(\\B\\s+)" ; // 空白符
String ss;
f = new File(new JOptionPane()
.showInputDialog("请输入文件所在路径~"));
try {
BufferedReader bf = new BufferedReader(new FileReader(f));
ss = bf.readLine()+"\n";
fileString = ss; //如果没有这两句,ss的开头会有“null”
while((ss = bf.readLine())!= null){
fileString += ss+"\n"; bf.close();
} catch (IOException ex) {
ex.printStackTrace(); p = Pattern.compile(regex);
m = p.matcher(fileString); //执行替换所有多余空行,空白符,注释
void Dels(){
System.out.println("before: "+fileString);
if(m.find()) System.out.println("find!!");
System.out.println(m.replaceAll("")); } }
-
㈢ java jdbc 预编译语句和普通语句的区别
应该指的是Statement和PreparedStatement把。
如果你的查询语句很少用的话, 用Statement,
如果你的查询语句常用的话, 就用PreparedStatement。
㈣ java jdbc中Statement,ResultSet,PreparedStatement中各代表什么意思
区别:
Statement执行一条sql就得编译一次,PrepareStatement只编译一次;常用后者原因在于参数设置非常方便;执行一条sql就得编译一次,后者只编译一次;还有就是sql放置的位置不同;常用后者原因在于参数设置非常方便;
一般我们使用PreparedStatement代替Statement,因为:
一.代码的可读性和可维护性.
虽然用PreparedStatement来代替Statement会使代码多出几行,但这样的代码无论从可读性还是可维护性上来说.都比直接用Statement的代码高很多档次:
stmt.executeUpdate("insertintotb_name(col1,col2,col2,col4)values('"+var1+"','"+var2+"',"+var3+",'"+var4+"')");
perstmt=con.prepareStatement("insertintotb_name(col1,col2,col2,col4)values(?,?,?,?)");
perstmt.setString(1,var1);
perstmt.setString(2,var2);
perstmt.setString(3,var3);
perstmt.setString(4,var4);
perstmt.executeUpdate();
二.PreparedStatement尽最大可能提高性能.
每一种数据库都会尽最大努力对预编译语句提供最大的性能优化.因为预编译语句有可能被重复调用.所以语句在被DB的编译器编译后的执行代码被缓存下来,那么 下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中(相当于一个涵数)就会得到执行.这并不是说只有一个 Connection中多次执行的预编译语句被缓存,而是对于整个DB中,只要预编译的语句语法和缓存中匹配.那么在任何时候就可以不需要再次编译而可以 直接执行.而statement的语句中,即使是相同一操作,而由于每次操作的数据不同所以使整个语句相匹配的机会极小,几乎不太可能匹配
三.最重要的一点是极大地提高了安全性.
使用预编译语句.你传入的任何内容就不会和原来的语句发生任何匹配的关系.只要全使用预编译语句,你就用不着对传入的数据做任何过虑.而如果使用普通的statement,有可能要对drop,;等做费尽心机的判断和过虑.
至于ResultSet,ResultSet 包含符合 SQL 语句中条件的所有行,并且它通过一套 get 方法(这些 get 方法可以访问当前行中的不同列)提供了对这些行中数据的访问,例如:
java.sql.Statementstmt=conn.createStatement();
ResultSetr=stmt.executeQuery("SELECTa,b,cFROMTable1");
while(r.next())
{
//打印当前行的值。
inti=r.getInt("a");
Strings=r.getString("b");
floatf=r.getFloat("c");
System.out.println("ROW="+i+""+s+""+f);
}
㈤ jdbc预编译 如何执行null值
传过来的值为null,那么get之后的值也为null,不用关心的吧!
㈥ jdbc预编译语句的问题
缺少预编译语句参数int resultSetType , int resultSetConcurrency
可以分别设置为ResultSet.TYPE_SCROLL_INSENSITIVE , ResultSet.CONCUR_READ_ONLY
㈦ java中连接数据库里的数据源驱动器和jdbc驱动器是一回事吗,还是说数据源驱动器是运行数据库,jdbc是连接的
通过JAVA的内置的JDBC访问数据库,统称JDBC方法。驱动就有很多种,基本每一种DB,都有一个驱动,有的还有多种驱动。
下面是Oracle的更新例子
Connection conn=null;
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
String url="jdbc:oracle:thin:@192.168.1.111:1521:XE";
String user="user1", pwd="user1";
conn=DriverManager.getConnection(url, user, pwd);
String sql = "UPDATE family SET income=?,pay=?,time=?,note=? WHERE fnumber=?";
PreparedStatement pstmt1 = conn.prepareStatement(sql);
pstmt1.setString(1, income);
pstmt1.setString(2, pay);
pstmt1.setString(3, time);
pstmt1.setString(4, note);
pstmt1.setString(5, fnumber);
pstmt1.executeUpdate();
return "修改成功";
}catch(Exception e){
e.printStackTrace();
return "修改失败" ;
}finally{
if(conn!=null){
try{
conn.close();
}catch(Exception e){
}
}
}
㈧ java jdbc中Statement,ResultSet,PreparedStatement中各代表什么意思
Statement接口:用于执行不带参数的简单SQL语句。创建Statement实例对象后可以调用JDBC提供的3种执行SQL语句的方法:(1)executeUpdate()方法,一般用于执行SQL的INSERT,DELETE,UPDATE语句(2)executeQuery()方法,一般用于执行SQL的SELECT语句,因为它的返回值是执行SQL语句后产生的一个ResultSet接口的实例(结果集)(3)execute()方法,即一般它执行的SQL语句既有查询又有更新值,约等于executeUpdate()和executeQuery()两个方法的合辑。PreparedStatement接口:它与Statement的主要区别(1)它包含的SQL语句是预编译的,所以当多次执行一条SQL语句时用它会更快(2)在设置参数是可以用“?”代替。如:PreparedStatementpstmt=conn.preparedStatement(insertintotestvalues(?,?));pstmt.setString(1,'gg');pstmt.setString(2,'123');ResultSet接口:包含了Statement和PreparedStatement的executeQuery方法中SELECT的结果集。相当于用它来读取数据库里每列的值。㈨ java jdbc中事务可以预编译传参数吗
1)加载数据库驱动
通常我们使用Class类的forName()静态方法来加载驱动(由各个数据库厂商自己实现)
Class.forName("com.mysql.jdbc.Driver");
Class.forName("oracle.jdbc.driver.OracleDriver");
"com.mysql.jdbc.Driver"、"oracle.jdbc.driver.OracleDriver"代表了数据库驱动类对应的字符串
2)通过DriverManager获取数据库连接
DriverManager.getConnection(Stringurl,Stringuser,Stringpass);
2.1)url:数据库连接字符串
2.1.1)Mysql
jdbc:mysql://hostname:port/databasename
2.1.2)Oracle
jdbc:oracle:thin:@hostname:port:databasename
2.2)user:数据库的系统用户名
2.3)pass:数据库的系统密码
3)通过Connection对象创建Statement对象,Connection创建Statement对象的方法有如下3个
3.1)createStatement(Stringsql):创建基本的Statement对象
3.2)prepareStatement(Stringsql):根据传入的SQL语句创建预编译的Statement对象
3.3)prepareCall(Stringsql):根据传入的SQL语句创建CallableStatement对象
4)使用Statement执行SQL语句
所有的Statement都有如下3个方法来执行SQL语句
4.1)execute():可以执行任何SQL语句,但比较麻烦
4.2)executeUpdate():主要用于执行DML和DDL语句。执行DML语句返回受SQL影响的行数,执行DDL语句返回0
4.3)executeQuery():只能执行查询语句,执行后返回代表查询结果的ResultSet对象
5)操作结果集
如果执行的SQL语句是查询语句,则执行结果将返回一个ResultSet对象,该对象里保存了SQL语句查询的结果。程序可以通过操作该ResultSet对象来取出查询结果。ResultSet对象主要提供了如
下方法
5.1)移动记录指针的方法
5.1.1)next()
5.1.2)previous()
5.1.3)first()
5.1.4)last()
5.1.5)beforeFirst()
5.1.6)afterLast()
5.1.7)absolute()
5.2)获取指针指向的某行的"特定的列值"
5.2.1)getInt()
5.2.2)getString()
...
该方法既可以使用列索引作为参数,也可以使用列名作为参数
6)回收数据库资源
包括关闭ResultSet、Statement、Connection等资源
