jdbc快速入门:
1.注册驱动
Class.forname(“com.mysql.jdbc.Driver”);
2.获取连接
Connection con = DriverManager.getConnection(url,user,password);
3.创建statement对象
Statement st = con.createStatement();
4.发送sql并且执行
ResultSet rs = st.executeQuery();
5.遍历结果集
While(rs.next()){}
6.释放资源 放在finally中
public static void main(String[] args) {
//获取连接
Connection con = null;
//创建statement对象
Statement statement = null;
ResultSet rs = null;
try {
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test09", "root", "123");
statement = con.createStatement();
//发送并执行sql
String sql = "select * from user";
rs = statement.executeQuery(sql);
//遍历
while(rs.next()){
String id = rs.getString("id");
String name = rs.getString(2);
int age = rs.getInt(3);
System.out.println(id+"+++"+name+"++++"+age);
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//释放资源
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(statement!=null){
try {
statement.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(con!=null){
try {
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
DriverManager 驱动管理类
作用:Jdbc程序中的DriverManager用于加载驱动,并创建与数据库的链接
Class.forName("com.mysql.jdbc.Driver");
Connection 数据库连接类
JDBC程序中的Connection,它用于代表数据库的连接,Collection是数据库编程中最重要的一个对象,客户端与数据库所有交互都是通过connection对象完成的。
connection对象有如下2个应用:
(1)获得SQL的操作对象
创建连接之后,我们需要将sql语句发送给数据库去执行,而要将sql语句发送给数据库,必须使用connection对象创建的statement对象。
Connection.createStatement();简单发送sql的Statement对象;
connection.preparedStatement(sql);发送预编译的sql语句;
connection.callabledStatement();创建操作存储过程的statement对象。
(2)对数据库事务进行管理
connection.setAutoCommit(false);开始事务
Connection.commit();提交事务
Connection.rollback();事务回滚
Statement
1、Statement.executeQuery(sql)
参数:select 语句
返回值:ResultSet结果集
2、Statement.executeUpdate(sql)
参数:insert update delete
返回值:int 执行sql影响的行数
3、Statement.execute(Sql)
参数:任意的sql
返回值:boolean类型
true:该sql语句 是select查询语句 使用getResultSet()获取结果集
false:该sql语句 是insert update delete 使用getUpdateCount()获取影响的记录数
代码优化:
Jdbc.properties配置文件
package com.hxc.jdbc;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class JbdcUtils {
public static String driverClass="";
public static String url = "";
public static String user = "";
public static String password = "";
static{
//首先创建一个Properties对象
try {
Properties properties = new Properties();
//直接加载properties文件
properties.load(new FileInputStream("src/com/hxc/jdbc/jdbc.properties"));
//获取properties文件中的参数
driverClass = properties.getProperty("driverClass");
url = properties.getProperty("url");
user = properties.getProperty("user");
password = properties.getProperty("password");
//注册驱动
Class.forName(driverClass);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static Connection getConnection(){
Connection con = null;
try {
//2.获取连接
con = DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return con;
}
public static void release(ResultSet rs,Statement st,Connection con){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(st!=null){
try {
st.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Test
public void test(){
//获取连接
Connection connection = null;
//创建statement对象
Statement statement = null;
try {
//通过工具类获取连接
connection = JbdcUtils.getConnection();
statement = connection.createStatement();
//发送sql
String sql = "insert into user values('001','孙七',27)";
int update = statement.executeUpdate(sql);
System.out.println("插入了"+update+"条数据");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//释放资源
JbdcUtils.release(null, statement, connection);
}
}
sql 注入问题
sql注入:由于没有对用户输入进行充分检查,而SQL又是拼接而成,在用户输入参数时,在参数中添加一些SQL 关键字,达到改变SQL运行结果的目的,也可以完成恶意攻击。
例:
String sql = "select count(*) from user where name = ' "+username+" ' and password = ' "+password+" ' ";
用户名为 admin’ -- ,密码为 1234
select count(*) from user where name = 'admin' -- and password = '1234'
PreparedStatement解决sql注入
PreparedStatement是Statement的子接口,它的实例对象可以通过调用Connection.preparedStatement(sql)方法获得
举例:
select *from user where username='zhangsan' and password = '123456';
使用?进行占位
select *from user where username=? and password = ?;
步骤一:conn.prepareStatement(sql); -----需要你事先传递sql。如果sql需要参数,使用?进行占位。
步骤二:设置参数(执行sql之前):prepStmt.setXXX(int index, 要放入的值) -----根据不同类型的数据进行方法的选择。第一个参数表示的是?出现的位置,从1开始计数,有几个问号,就需要传递几个参数。
步骤三、执行,不需要在传递sql了。
prepStmt.executeQuery();---执行select
prepStmt.executeUpdate();---执行insert,delete,update
原理:
PreparedStatement 解决SQL注入原理,运行在SQL中参数以?占位符的方式表示
select * from user where username = ? and password = ? ;
将带有?的SQL 发送给数据库完成编译 (不能执行的SQL 带有?的SQL 进行编译 叫做预编译),在SQL编译后发现缺少两个参数
PreparedStatement 可以将? 代替参数 发送给数据库服务器,因为SQL已经编译过,参数中特殊字符不会当做特殊字符编译,无法达到SQL注入的目的
PreparedStatement优点:
相对于Statement对象而言:
1、PreperedStatement可以避免SQL注入的问题。
2、Statement对象每次执行SQL语句时,都会对其进行编译。当相同的SQL语句被执行被执行多次时,Statement对象就会使数据库频繁编译相同的SQL语句,从而降低数据库的效率。
PreparedStatement对象可对SQL语句进行预编译。也就是说,当相同的SQL语句再次执行时,数据库只需使用缓冲区中的数据,而不需要对SQL语句在次编译,从而提高访问效率。
3、并且PreperedStatement对于sql中的参数,允许使用占位符的形式进行替换,简化sql语句的编写。可读性变强。