JDBC实现原理流程图如下
1,首先要导入jar包.使用mysql就导入mysql包,oracle就导入oracle包
以下是数据库驱动包的下载地址:
MySQL:http://central.maven.org/maven2/mysql/mysql-connector-java/
oracle:https://www.oracle.com/technetwork/cn/database/features/jdbc/index-093096-zhs.html
2,编写JAVA代码,以MySQL为例
(1)查询语句select执行过程
大致步骤:
1,注册数据库驱动
2,获取数据库连接
3,获取sql语句执行平台
4,执行sql语句
5,执行查询语句时获取结果集
6,关流
方法 | 返回值 | 描述 |
---|---|---|
Class.forName(“com.mysql.jdbc.Driver”); | Class | 注册mysql驱动 |
DriverManager.getConnection(String url,String user, Stringpwd) | Connection | 获取数据库连接 |
connection.createStatement() | Statement | 获取sql语句执行平台 |
statement.executeQuery(String sql) | ResultSet | 执行查询语句获取一个查询结果集 |
statement.executeUpdate(String sql) | int | 执行增删改语句,返回影响行数 |
resultSet.next() | boolean | 遍历结果集时判断下一个是否还有数据 |
resultSet.getObject(String columnLabel) | Object | 获取当前行指定列名的数据 |
resultSet.getObject(int columnIndex) | Object | 获取当前行第index列的数据 |
resultSet.getXXX() | XXX | 根据设定的类型获取相应类型的数据,比如geiInt获取int数据,getString获取String数据 |
public static void main(String[] args) throws ClassNotFoundException, SQLException {
/**
* 1,注册数据库驱动.就这么一句话。MySQL驱动在com.mysql.jdbc.Driver中
* oracle驱动在oracle.jdbc.OracleDriver中
*/
Class.forName("com.mysql.jdbc.Driver");
/**
* 2,获取数据库连接.需要连接的url,user和pwd
* mysql--jdbc:mysql://地址/数据库名称
* oracle--jdbc:oracle:thin:@地址:1521:实例(一般是orcl)
*/
String url = "jdbc:mysql://localhost:3306/demo";
String user = "root";
String pwd = "root";
//使用DriverManager.getConnection(url,user,pwd);方法来获取数据库连接
Connection connection = DriverManager.getConnection(url, user, pwd);
/**
* 3,获取数据库语句执行平台connection.createStatement()得到一个
* Statement对象,然后在使用执行方法来执行数据库
* ResultSet executeQuery(String sql);执行查询语句
* int executeUpdate(String sql);执行更新语句
* 查询语句执行然后会返回一个ResultSet对象,里面包含着查询结果
* 更新语句执行后会返回一个int值,用来表示更新了多少行
*/
Statement statement = connection.createStatement();
String sql = "select * from user";
//这样就执行完了这句查询语句。接着在遍历结果集就能获取查询到的数据
ResultSet resultSet = statement.executeQuery(sql);
/**
* 4,用while遍历结果集,resultSet.next()判断是否还有数据
* resultSet.getObject(int columnIndex);//获取第index列的数据,类似根据设定的来获取
* resultSet.getObject(String columnLabel);//获取列名为columnLabel的数据,类似根据设定的来获取
* 如果要获取一个字符串就getString();获取整数就是getInt();
*
*/
while (resultSet.next()){
String username = resultSet.getString("username");
String pawd = resultSet.getString(3);
System.out.println(username+"="+pawd);
}
/**
* 最后关流。后得到的先关闭
*/
resultSet.close();
statement.close();
connection.close();
}
表数据如下:
执行上述查询过程后结果如下:
(2)增删改语句执行过程
在获取连接和sql语句执行平台后使用executeUpdate(String sql)来执行增删改语句
操作前表数据
/**
* 执行增删改语句
*/
//更改
String updateSql = "update user set pwd='456789' where username='zhangsan'";
statement.executeUpdate(updateSql);
//插入
String insertSql = "insert into user(username,pwd) values('lisi','123456')";
statement.executeUpdate(insertSql);
//删除
String deleteSql = "delete from user where username='wangba'";
statement.executeUpdate(deleteSql);
预编译sql执行平台prepareStatement(String sql);将sql事先编译并缓存好在需要的时候直接使用。比起statement每次执行sql语句时都要重新编译来的更快些。
方法 | 返回值 | 描述 |
---|---|---|
connection.prepareStatement(String sql) | PreparedStatement | 获取预编译sql语句执行平台,先把sql实现编译好。执行的时候在使用 |
preparedStatement.executeQuery() | ResultSet | 执行预编译好的查询语句获取一个查询结果的结果集 |
preparedStatement.executeUpdate() | int | 执行预编译好的增删改语句,返回影响的行数 |
preparedStatement.setXXX(int parameterIndex,xxx) | void | 对相应index位置上的占位符参数设置值,设置String就setString() |
1,预编译sql使用步骤
前后步骤还是一致的,在使用上的区别就是获取sql执行平台的时候使用 connection.prepareStatement(String sql) 这个方法,并且要把你执行的sql放进去。然后再用
executeQuery和executeUpdate来执行sql语句。其中预编译语句可以使用占位符,即你要在sql的where条件附上位置的值时使用。比如
select * from user where username=?
上面这句sql的"?“就是占位符。事先占好一个位置然后在需要的地方使preparedStatement.setXXX(int parameterIndex,xxx)来给它赋值,比如执行preparedStatement.setString(1,“zhangsan”).上面那句sql就变成了select * from user where username=“zhangsan”,如果有两个”?“就按”?“出现的顺序来赋值,第一个”?"的index是1后面依次累加
select * from user where username=? and pwd=?
preparedStatement.setString(1,“zhangsan”)
preparedStatement.setString(2,“123456”)
–>sql:select * from user where username=“zhangsan” and pwd=“123456”
之后的结果集处理过程是一样的
(1)预编译查询
//1,注册驱动获取链接---
Connection connection = DriverManager.getConnection(url, user, pwd);
/**
* 预编译sql执行平台prepareStatement(String sql);
* 将sql事先编译并缓存好在需要的时候直接使用。比起statement每次执行
* sql语句时都要重新编译来的更快些。
*/
String sql = "select * from user where username=?";
//使用预编译sql来执行查询语句
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//预编译可以设置占位符参数。普通的编译平台是没有占位符的
preparedStatement.setString(1,"zhangsan");
//执行查询sql
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()){
String username = resultSet.getString("username");
String pawd = resultSet.getString(3);
System.out.println(username+"="+pawd);
}
//关流...
(2)预编译增删改
/**
* 预编译执行增删改语句
*/
//更改
String updateSql = "update user set pwd='456789' where username='zhangsan'";
PreparedStatement updateStatement = connection.prepareStatement(updateSql);
updateStatement.executeUpdate();
//插入
String insertSql = "insert into user(username,pwd) values('lisi','123456')";
PreparedStatement insertStatement = connection.prepareStatement(insertSql);
insertStatement.executeUpdate();
//删除
String deleteSql = "delete from user where username='wangba'";
PreparedStatement deleteStatement = connection.prepareStatement(deleteSql);
deleteStatement.executeUpdate();
1,预编译具有占位符,能有效防止sql注入
(1)预编译具有占位符的功能。使用占位符来为where条件中未知的值赋值能够有效的防止sql注入
/**
* 预编译进行where条件拼接
*/
String sql = "select * from user where username=? and pwd = ?";
//预编译两条要创建两个预编译平台对象来执行sql
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,username);
preparedStatement.setString(2,pwd);
ResultSet resultSet = preparedStatement.executeQuery();
/**
* 普通编译平台进行条件拼接
*/
String sql = "select pwd from user where username='“+username+”' and pwd='"+pwd+"'";
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
上述两个编译平台中。我们给username赋值"zhangsan",pwd赋值"123456’ or ‘1’='1"
然后分别执行后结果如下:
预编译的sql–>
编译平台的sql–>select * from user where username=‘zhangsan’ and pwd=‘123456’ or ‘1’=‘1’:
可以发现普通编译平台用拼接的方式受到类似sql攻击时会永远查出数据。这样就会判断成登入成功。而预编译的不会。
(2)使用预编译执行频繁使用的sql语句可以提升效率