jdbc使用基本步骤
public class JDBCDemo {
public static void main(String[] args) throws Exception {
//0、导入驱动jar包
//1、注册驱动 MySQL5之后不需要自行注册,底层使用的是DriverManager创建的
Class.forName("com.mysql.jdbc.Driver");
//2、获取连接
String url = "jdbc:mysql://127.0.0.1:3306/test";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, username, password);
//3、定义sql
String sql = "update emp set salary = 30000 where id = 1";
//4、获取执行sql的对象Statement
Statement stat = conn.createStatement();
//5、执行sql
int count = stat.executeUpdate(sql); //返回值为表中受影响的行数
//6、处理结果
System.out.println(count);
//7、释放资源,按创建顺序逆向释放对象
stat.close();
conn.close();
}
}
jdbc API详解
DriverManager
DriverManager(驱动管理类)作用:
注册驱动
forName("");
MySQL5之后不需要自行注册,底层使用的是DriverManager创建的
获取数据库连接
getConnection(url, username, password);
url(连接路径)
语法格式:jdbc:mysql://ip地址(域名):端口号/数据库名称?参数键值对1&参数键值对2...
例:jdbc:mysql://127.0.0.1:3306/test
注:
如果连接的是本机mysql服务器,且默认端口为3306,则url路径可简写为
jdbc:mysql:///数据库名称?参数键值对
通过配置useSSL参数,禁用安全连接方式,解决警告提示
Connection
获取执行SQL对象
普通执行SQL对象
Statement createStatement();
预编译SQL的执行SQL对象:防止SQL注入
PrepareStatement prepareStatement(sql);
执行存储过程的对象(不常用)
CallableStatement prepareCall(sql);
事务管理
Connection接口中定义了3个对应的方法用户事务管理
setAutoCommit(boolean autoCommit); //true为自动提交事务,false为手动提交事务(即开启事务)
commit(); //提交事务
rollback(); //回滚事务
通过Java中的try-catch捕获异常
//开启事务
conn.setAutoCommit(false);
try {
//5、执行sql
int count1 = stat.executeUpdate(sql1); //返回值为表中受影响的行数
int count2 = stat.executeUpdate(sql2);
//6、处理结果
System.out.println(count1);
System.out.println(count2);
//提交事务
conn.commit();
} catch (Exception throwables) {
//回滚事务
conn.rollback();
throwables.printStackTrace();
}
Statement
Statement作用:执行SQL语句
DML(增删改)、DDL(增删改查)、DQL(查)
/** executeUpdate
* 参数:sql语句
* return:1、DML语句影响的行数;
* 2、DDL语句执行成功后也能返回0
* 执行DML(增删改)、DDL(增删改查)语句
*/
int executeUpdate(sql);
/** executeQuery
* 参数:sql语句
* return:ResultSet结果集对象
* 执行DQL(查)语句
*/
ResultSet executeQuery(sql);
ResultSet
ResultSet作用:封装了DQL查询语句的结果
ResultSet stmt.excuteQuery(sql); //执行DQL语句,返回ResultSet对象
ResultSet中的方法:
boolean next()
操作:将参数从当前位置向前移动一行
作用:判断当前行是否为有效行
返回值:true--有效行,当前行有数据
false--无效行,当前行没有数据
xxx getXxx(参数)
获取数据
xxx:数据类型,如:int getInt(参数),String getString(参数)
参数:int:列的编号,从1开始
String:列的名称
使用:
//6、处理结果
//光标向下移动,判断当前行是否为有效行
while (rs.next()){
//获取数据 getXxx();
int id = rs.getInt(1);
String name = rs.getString(2);
double money = rs.getDouble(3);
System.out.println(id);
System.out.println(name);
System.out.println(money);
}
PreparedStatement
PreparedStatement作用:预编译SQL并执行SQL语句,防止SQL注入
SQL注入示例:
String name = "sdfjiscisdn";
String pwd = "' or '1' = '1"; //使用特殊字符串完成SQL注入
//定义sql
String sql = "select * from account where name = '"+name+"' and password = '"+pwd+"' ";
/*
执行的SQL语句为:
select * from account where name = 'sdfjiscisdn' and password = '' or '1' = '1'
其中password = '' or '1' = '1'是由password原有的''与pwd传入的' or '1' = '1拼接而成,查询结果一定为true
*/
1、获取PreparedStatement对象
//定义sql
String sql = "select * from account where name = ? and password = ? ";
//获取pstmt
PreparedStatement pstmt = conn.prepareStatement(sql);
2、设置参数值
PreparedStatement对象:SetXxx(参数1,参数2):给?赋值
Xxx:数据类型,如SetInt(参数1,参数2)
参数:
参数1:?的位置编号,从1开始
参数2:?的值
3、执行SQL
不需要再传递sql,因为再获取PreparedStatement对象时已经传递了sql语句
executeUpdate();
executeQuery();
报错处理
报错:
java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0).
![](https://i-blog.csdnimg.cn/blog_migrate/51c951b4f39e6cb2b46c450bd0a7e35c.png)
解决方法:
(我遇到的)
定义的sql语句中的name和password后的代替符?不应该用单引号包裹;
![](https://i-blog.csdnimg.cn/blog_migrate/3b5356ef9bd347b216159373ae291f69.png)
(网上常见的)
sql语句中中英文符号输错,如:,或?写成了中文的
执行executeUpdate() 或 executeQuery() 语句时提供了sql参数
修改sql语句后:
![](https://i-blog.csdnimg.cn/blog_migrate/fd42e9c73fc56283f493e65aa054df12.png)
PreparedStatement防止SQL注入原理:
PreparedStatement对象在将用户输入的表单数据提交给sql语句时,会对用户输入的特殊字符进行转义,如:将 ' 变为 /' ,从而保证不会应为字符串拼接导致查询出错。
PreparedStatement好处:
预编译SQL语句,性能更高;
将敏感词转义,防止SQL注入,更安全
注:
1、 PreparedStatement预编译功能默认关闭,须在url语句后添加指令开启,开启指令为:useServerPrepStmts=true
2、若sql模板一样,PreparedStatement预编译只会执行一次,第二次执行不需要重复检查编译,提高了效率
数据库连接池
数据库连接池简介
数据库连接池是一个容器,用于分配、管理数据库连接(Connection)
数据库连接池允许重复使用一个现有的数据库连接,而不是每次使用后就close掉,等需要访问时在重新建立连接(速度慢)
释放空闲时间大于最大空闲时间的数据库连接,避免因没有释放数据库连接而引起的数据库连接遗漏
数据库连接池的优点:
资源重用
提升系统响应速度
避免数据库连接遗漏
数据库连接池的实现
标准接口:DataSource
sun公司提供接口,第三方公司实现
功能:获取连接
Connection getConnection();
常见的数据库连接池
DBCP、C3P0、Druid(这里着重介绍Druid(德鲁伊))
Druid
Alibaba开源的数据库连接池项目
是Java语言最好的数据库连接池之一