1 数据库驱动
驱动:声卡、显卡、数据库
我们的程序会通过数据库驱动同数据库打交道;
2 数据库驱动
sun公司为了简化开发者(对数据库的统一)的操作,提供了一个(java操作数据库的 )规范,就是JDBC,这些规范的实现由具体的厂家去做
对于开发人员来说,我们只需要掌握jdbc的操作即可
开发所需要的jar包:可以去maven官网下载
java.sql
javax.sql
还需要导入数据库驱动包
3 第一个jdbc程序
1、创建一个maven项目
先创建数据库
CREATE DATABASE `jdbcStudy` CHARACTER SET utf8 COLLATE utf8_general_ci;
USE `jdbcStudy`;
CREATE TABLE `users`(
`id` INT PRIMARY KEY,
`NAME` VARCHAR(40),
`PASSWORD` VARCHAR(40),
`email` VARCHAR(60),
birthday DATE
);
INSERT INTO `users`(`id`,`NAME`,`PASSWORD`,`email`,`birthday`)
VALUES(1,'zhangsan',123456,'zs@sina.com','1980-12-04'),
(2,'lisi',123456,'lisi@sina.com','1981-12-04'),
(3,'wangwu',123456,'wangwu@sina.com','1979-12-04')
导入数据库驱动
代码如下:
package com.chen;
import java.sql.*;
//我的第一个jdbc程序
public class test01 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// 1 加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 2 用户信息和url
String url="jdbc:mysql://localhost:3306/jdbcStudy?useUnicode=true&characterEncoding=utf8&useSSL=true";
String username="root";
String password="123456";
// 3 链接成功
Connection connection = DriverManager.getConnection(url, username, password);
// 4 执行sql的对象
Statement statement = connection.createStatement();
// 5 执行sql的对象去执行sql,存在结果就返回结果
String sql=" SELECT * FROM users";
ResultSet resultSet = statement.executeQuery(sql);
while(resultSet.next()){
System.out.println("id="+resultSet.getObject("id"));
System.out.println("name="+resultSet.getObject("NAME"));
System.out.println("passwd="+resultSet.getObject("PASSWORD"));
System.out.println("email="+resultSet.getObject("email"));
System.out.println("birthday="+resultSet.getObject("birthday"));
}
// 6 释放连接
resultSet.close();
statement.close();
connection.close();
}
}
执行结果:
步骤:
- 加载驱动
- 连接数据库 DriverManager
- 获取执行SQL的对象 Statement
- 获得返回结果集
- 释放连接
// DRIVER Class.forName("com.mysql.jdbc.Driver");
// URL
String url="jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true";
mysql默认端口3306。
// statement
编写sql: String sql=" SELECT * FROM users";
statement.executeQuery() -- 查询操作,返回resultset statement.executeUpdate() -- 修改、删除、增加操作,返回执行的行数 statement.execute() -- 可执行所有的sql语句,效率较低 statement.executeBatch() -- 可执行多条sql语句
// resultSet:封装了所有的查询结果
返回指定类型的数据
-
resultSet.getObject() resultSet.getDate()resultSet.getInt() resultSet.getString()........
resultSet.beforeFirst(); --移动到最前面 resultSet.next(); --移动到下一个 resultSet.afterLast(); --移动到最后面
// 释放资源
resultSet.close(); statement.close(); connection.close();
4 statement对象
java中的statement对象用于向数据库发送sql语句,想完成对数据库的增删改查,只需要提供这个对象向数据库发送sql语句即可。
查询操作:返回查询结果
ResultSet resultSet = statement.executeQuery("select * from users");
System.out.println("id="+resultSet.getObject("id"));
增加操作:返回影响行数
int i = statement.executeUpdate("insert into users(id,NAME,PASSWORD) values(1,'cxl','123456')");
if(i>0) System.out.println("增加成功");
删除操作:返回影响行数
int i = statement.executeUpdate("delete from users where id = 1");
if(i>0) System.out.println("删除成功");
修改操作:返回影响行数
int i =statement.executeUpdate("update users set NAME='cxl' where id=1");
if(i>0) System.out.println("修改成功");
使用工具类的方式,可以使得程序的耦合性降低,方便开发和提高性能。代码如下:
工具类:
package com.jdbc.util;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class jdbcutil {
private static String driver=null;
private static String url=null;
private static String username=null;
private static String password=null;
static {
// 获取配置文件
InputStream in = jdbcutil.class.getClassLoader().getResourceAsStream("connect.properties");
Properties properties = new Properties();
try {
// 加载配置文件
properties.load(in);
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
// 加载驱动
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
}
}
// 获取连接
public static Connection getConnect() throws SQLException {
return DriverManager.getConnection(url, username, password);
}
// 释放连接
public static void res(Connection connection,Statement statement, ResultSet resultSet){
if(resultSet!=null){
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}}
if(statement!=null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
插入:
package com.jdbc;
import com.jdbc.util.jdbcutil;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class insert {
public static void main(String[] args) {
Connection connect=null;
Statement statement=null;
ResultSet resultSet=null;
// 获取连接
try {
connect = jdbcutil.getConnect();
statement = connect.createStatement();
int i = statement.executeUpdate("INSERT INTO `users`(`id`,`NAME`,`PASSWORD`,`email`,`birthday`)\n" +
"VALUES(4,'zhangsan2',123456,'zs2@sina.com','1980-12-04')");
while(i>0){
System.out.println("插入成功");
break;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
jdbcutil.res( connect,statement,resultSet);
}
}
}
删除:
package com.jdbc;
import com.jdbc.util.jdbcutil;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class delete {
public static void main(String[] args) {
Connection connect=null;
Statement statement=null;
ResultSet resultSet=null;
try {
connect = jdbcutil.getConnect();
statement = connect.createStatement();
int i = statement.executeUpdate("delete from users where id = 4");
while(i>0){
System.out.println("删除成功");
break;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
//释放连接
finally {
jdbcutil.res( connect,statement,resultSet);
}
}
}
修改:
package com.jdbc;
import com.jdbc.util.jdbcutil;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class update {
public static void main(String[] args) {
Connection connect =null;
Statement statement=null;
ResultSet resultSet=null;
try {
connect = jdbcutil.getConnect();
statement = connect.createStatement();
int i=statement.executeUpdate("UPDATE users SET `NAME`='chen',PASSWORD='12121',email='cxl@qq.com',birthday='1999-12-11' WHERE id = 1");
while (i>0){
System.out.println("修改成功");
break;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
finally {
jdbcutil.res( connect,statement,resultSet);
}
}
}
查询:
package com.jdbc;
import com.jdbc.util.jdbcutil;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class query {
public static void main(String[] args) {
Connection connect =null;
Statement statement=null;
ResultSet resultSet=null;
try {
connect = jdbcutil.getConnect();
statement= connect.createStatement();
resultSet = statement.executeQuery("select * from users where id = 1");
while(resultSet.next()){
System.out.println(resultSet.getObject("NAME"));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
finally {
jdbcutil.res( connect,statement,resultSet);
}
}
}
sql注入的问题:
sql存在漏洞,会被攻击导致数据泄露。(数据会被拼接or)
例如:正常输入用户名密码状态下的代码,正常输出结果
package com.jdbc;
import com.jdbc.util.jdbcutil;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class sql_injection {
public static void main(String[] args) {
login("lisi","123456");
}
public static void login(String username,String password){
Connection connect =null;
Statement statement=null;
ResultSet resultSet=null;
try {
connect = jdbcutil.getConnect();
statement = connect.createStatement();
resultSet = statement.executeQuery("select * from users where `NAME`='" + username + "' and PASSWORD='" + password + "'");
while (resultSet.next()){
System.out.println(resultSet.getObject("birthday"));
break;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
jdbcutil.res(connect,statement,resultSet);
}
}
}
非正常状态下输入:没有正确输入用户名密码
package com.jdbc;
import com.jdbc.util.jdbcutil;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class sql_injection {
public static void main(String[] args) {
login("'or' 1=1","'or' 1=1");
}
public static void login(String username,String password){
Connection connect =null;
Statement statement=null;
ResultSet resultSet=null;
try {
connect = jdbcutil.getConnect();
statement = connect.createStatement();
resultSet = statement.executeQuery("select * from users where `NAME`='" + username + "' and PASSWORD='" + password + "'");
while (resultSet.next()){
System.out.println(resultSet.getObject("birthday"));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
jdbcutil.res(connect,statement,resultSet);
}
}
}
结果:表中的所有数据都可以被非法访问,这就是sql注入的危害
5 preparedstatement对象
preparedstatement可以防止sql注入,效率更高。
使用preparedstatement解决sql注入问题,代码如下:
package com.jdbc;
import com.jdbc.util.jdbcutil;
import java.sql.*;
public class sql_injection {
public static void main(String[] args) {
// login("'or' 1=1","'or' 1=1");
login("lisi","123456");
}
public static void login(String username,String password){
Connection connect =null;
PreparedStatement statement=null;
ResultSet resultSet=null;
try {
connect = jdbcutil.getConnect();
String sql="select * from users where `NAME`=? and PASSWORD=?";
statement = connect.prepareStatement(sql);
statement.setString(1,username);
statement.setString(2,password);
resultSet = statement.executeQuery();
while (resultSet.next()){
System.out.println(resultSet.getObject("birthday"));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
jdbcutil.res(connect,statement,resultSet);
}
}
/*
public static void main(String[] args) {
login("'or' 1=1","'or' 1=1");
}
public static void login(String username,String password){
Connection connect =null;
Statement statement=null;
ResultSet resultSet=null;
try {
connect = jdbcutil.getConnect();
statement = connect.createStatement();
resultSet = statement.executeQuery("select * from users where `NAME`='" + username + "' and PASSWORD='" + password + "'");
while (resultSet.next()){
System.out.println(resultSet.getObject("birthday"));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
jdbcutil.res(connect,statement,resultSet);
}
}*/
}
java处理事务:
- 开启事务
- 一组业务执行完毕,提交事务
- 在catch语句中定义回滚语句,但默认会回滚
package com.jdbc;
import com.jdbc.util.jdbcutil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class transactionTest {
public static void main(String[] args) {
Connection connect =null;
PreparedStatement preparedStatement=null;
ResultSet resultSet=null;
try {
connect = jdbcutil.getConnect();
//关闭自动提交事务,自动开启事务
connect.setAutoCommit(false);
// 定义张三转账500块钱
String sql1="update account set money=money - 500 where name = '张三'";
// 预处理sql
preparedStatement = connect.prepareStatement(sql1);
// 执行sql
preparedStatement.executeUpdate();
// 定义李四收取500块钱
String sql2="update account set money=money + 500 where name = '李四'";
// 预处理sql
preparedStatement = connect.prepareStatement(sql2);
// 执行sql
preparedStatement.executeUpdate();
// 提交事务
connect.commit();
System.out.println("success");
} catch (SQLException throwables) {
try {
// 默认会回滚,这里为了更加清晰的解读,手动添加回滚
connect.rollback();
} catch (SQLException e) {
e.printStackTrace();
}
throwables.printStackTrace();
}finally {
// 释放连接
jdbcutil.res(connect,preparedStatement,resultSet);
}
}
}