JDBC基础
1. JDBC:Java DataBase Connectivity (Java连接数据库的标准,SUN制定的))
JDBC和数据库的驱动是什么关系?JDBC是规范,抽象层,数据库驱动是具体的实现。
JDBC规范由一些抽象类和接口组成,一般放在java.sql.*或javax.sql.*包中(JDK中带)
2. JDBC编码的步骤:把数据库的驱动加入到构建路径中
a) 加载驱动程序并注册驱动。
b) 获取与数据库的连接。
c) 得到代表SQL语句的对象,并发送SQL给数据库。
d) 如果有查询结果得到封装了查询结果的对象。
e) 遍历结果
f) 释放占用的资源
3. JDBC常用的接口和类的详细讲解
a) DriverManager:注册驱动,得到数据库的连接。两种驱动注册方式:
第一种:注册驱动:DriverManager.registDriver(new com.mysql.jdbc.Driver)(不建议使用)
原因:1. 严重依赖具体的数据库驱动
2. 会导致驱动注册2遍。
第二种:使用Class.forname(“com.mysql.jdbc.DriverMange”);
b) Connection:所有与数据库交互都必须建立在连接的基础上。常用的三种连接方式:
1) static Connection getConnection(String url,String user,String password):
uri:数据库的连接串
mysql的连接串:mysql:jdbc:mysql://localhost:3306/day14数据库名或者jdbc:mysql:///day14(连接本地默认端口上的mysql数据库)
user:数据库的用户名
password:数据库的密码
2) static Connection getConnection(String url,Properties info):使用Properties的设置连接用户名和密码,用户名是user,密码是:password
3) static Connection getConnection(String url):以网页请求的方式。在数据库的连接串后加上?user=xxxx&password=xxxx;
c) Statement:代表这SQL语句的对象。常用的方法如下:
1) ResultSet executeQuery(String sql):sql是DQL语句,是查询语句
2) int executeUpdate(String sql):sql是DML语句。或者是没有返回结果的DDL也可以。返回值,代表着语句影响到的行数。
3) boolean execute(String sql):sql可以是任何的sql语句。如果有结果集返回,返回true。否则返回false。
d) ResultSet:代表查询语句返回的对象,里面是一个存放查询结果的集合。常用方法如下:
1) boolean next():下移一行
2) boolean previous():上移一行
3) void absolute(int row):第一行的记录就是1,指定移动的行数
4) void beforeFirst():移动到第一行的前面
5) void afterLast():移动到最后一行的后面
4. SQL的注入:是用户利用某些系统没有对输入数据进行充分的检查,从而进行恶意破坏的行为。导致验证密码输错等也可以直接访问。
5. PreparedStatement:尽量使用它,替代了Statement
作用:
a) 预编译SQL语句,数据库执行效率高
b) 防止SQL注入
c) 支持参数占位符”?”。即语句中的参数使用?,代替,再使用方法对每个?进行赋值。
6. 批处理:当需要想数据库发送一批SQL语句执行时,应避免想数据库一条条的发送执行,而应采用JDBC的批处理,提升执行效率。两种方式
a) 当执行不同的语句时,使用Statement。代码如下:
public void test1() { Connection conn = null; Statement stmt = null; ResultSet rs = null; try { conn = JdbcUtil.getConnection(); stmt = conn.createStatement(); String sql1 = "insert into t3 (id,content) values (1,'aaa1')"; String sql2 = "insert into t3 (id,content) values (2,'aaa2')"; String sql3 = "delete from t3 where id=1"; stmt.addBatch(sql1); stmt.addBatch(sql2); stmt.addBatch(sql3); // 影响的行数 int[] ii = stmt.executeBatch(); for (int i : ii) { System.out.println(i); } } catch (Exception e) { e.printStackTrace(); } finally { JdbcUtil.releses(rs, stmt, conn); } } |
b) 当执行相同语句时,可以使用PreparedStatment
public void test2() { Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { conn = JdbcUtil.getConnection(); for (int i = 0; i < 100; i++) { stmt = conn .prepareStatement("insert into customer values (?,?,?,?,?,?,?,?,?)"); stmt.setString(1, UUID.randomUUID().toString()); stmt.setString(2, "name" + i); stmt.setString(3, i % 2 == 0 ? "0" : "1"); stmt.setString(4, "1990-10-29"); stmt.setString(5, "12345" + i); stmt.setString(6, i + "[email protected]"); stmt.setString(7, i % 2 == 0 ? "饮茶" : "看电影"); stmt.setString(8, i % 2 == 0 ? "VIP" : "普通用户"); stmt.setString(9, "连连看" + i); stmt.addBatch(); stmt.executeUpdate(); } } catch (Exception e) { e.printStackTrace(); } finally { JdbcUtil.releses(rs, stmt, conn); } } |
7. 大文本(Clob)数据存取
a) 将本地大数据文本设置到数据库中。
String path = classLoader();
File f = new File(path);
PreparedStatement.setCharacterStream(index, reader, length);
//注意length长度须设置,并且设置为int型,利用File获取String path = classLoader();
String path = classLoader();
b) 将数据库中的大文本读取到硬盘
reader = resultSet. getCharacterStream(i);
reader = resultSet.getClob(i).getCharacterStream();
string s = resultSet.getString(i);
8. 大二进制数据(Blob)的存取
a) 将本地的二进制资源数据存储到数据库中
PreparedStatement. setBinaryStream(i, inputStream, length);
b) 将数据库中的二进制资源数据读取到硬盘
InputStream in = resultSet.getBinaryStream(i);
InputStream in = resultSet.getBlob(i).getBinaryStream();
9. 获取数据库自动生成的主键,使用PreparedStatement的getGeneratedKeys()方法
10. 调用存储过程。对于数据库中的存储过程,我们在程序中如何调用。
例如:存储过程是:
delimiter $$
CREATE PROCEDURE spDemo2(IN inputParam VARCHAR(255), INOUT inOutParam
varchar(255))
BEGIN SELECT CONCAT('welcome---', inputParam) into
inOutParam; END $$
delimiter ;
调用过程是:
Connection conn = null; CallableStatement stmt = null; ResultSet rs = null; try { conn = JdbcUtil.getConnection(); stmt = conn.prepareCall("{call demoSp(?,?)}"); stmt.setString(1, "上海"); stmt.registerOutParameter(2, Types.VARCHAR); stmt.execute(); String value = stmt.getString(2); System.out.println(value); } catch (Exception e) { e.printStackTrace(); } finally { JdbcUtil.releses(rs, stmt, conn); } |