JDBC
1.JDBC介绍
- jdbc概念:(java数据库连接)是一种用于执行sql语言的java API,可以为多重关系型数据库提供统一访问,它是由一组java语言编写的类和接口组成的
- jdbc的本质:其实是java官方提供的一套规范(接口),用于帮助开发人员快速实现不同关系型数据库的连接
2.JDBC的快速入门
- 导入jar包
- 注册驱动
- 获取数据库连接
- 获取执行对象
- 执行sql语言并返回结果
- 处理结果
- 释放资源
public class JDBCDemo01 {
public static void main(String[] args) throws Exception{
//1注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2获取数据库连接
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db_jdbc", "root", "root");
//3获取执行对象
Statement sta = con.createStatement();
//4执行sql语句并返回对象
String sql = "select * from student";
ResultSet result = sta.executeQuery(sql);
//5处理结果
while (result.next()){
int id = result.getInt("id");
String name = result.getString("name");
System.out.println(id+"\t"+name);
}
//6释放资源
con.close();
sta.close();
result.close();
}
}
JDBC功能类详解
1.DriverManager:驱动管理对象
- 注册驱动
Class.forName("com.mysql.jdbc.Driver");
mysql5以后可以省略注册驱动步骤
- 连接数据库
获取数据库连接对象:static Connection getConnection("url","user","password")
url:jdbc:mysql://ip地址(域名)/数据库名
user:用户
password:密码
2.Conection:数据库连接对象
- 获取执行者对象
-获取普通执行者对象:Statement createStatement(String sql);
-获取预编译执行者对象:PreparedStatement PreparedStatement(String sql);
- 管理事务
-开启事务:SetAutoCommit(boolean autoCommit);参数为false,则开启事务
-提交事务:commit();
-回滚事务:rollback();
- 释放资源
3.Statement:执行SQL语句对象
-执行DML语句:int executeUpdate(String sql);
返回值int:返回影响的行数
参数sql语句:可以执行insert,update,delete
-执行DQL语句:ResultSet executeQuery(String sql);
返回值ResultSet:封装查询的结果
参数sql:可以执行select语句
4.ResultSet:结果集对象
-判断结果集中是否还有数据:boolean next();
有数据返回true,并把所有向下移动一行
没有数据返回false
-获取结果集中的数据:XXX get.xxx("列名");
JDBC案例
1.JDBCUtils工具类
public class JDBCUtils {
//1.构造方式私有化
private JDBCUtils(){};
//2.定义需要的配置变量
public static String driverClass;
public static String url;
public static String username;
public static String password;
//3.静态代码块,读取配置文件并赋值
static {
try {
//获取配置文件的数据
InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("config.properties");
//创建properties集合接受数据
Properties prop = new Properties();
prop.load(is);
//获取资源
driverClass = prop.getProperty("diverClass");
url=prop.getProperty("url");
username=prop.getProperty("username");
password=prop.getProperty("password");
//加载驱动
Class.forName(driverClass);
} catch (Exception e) {
e.printStackTrace();
}
}
//4.提供静态的获取数据库的连接方法
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,username,password);
}
//5.提供静态的释放资源的方法
public static void close(ResultSet rs , Connection con , Statement stat){
if (rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stat!=null){
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void close(Connection con ,Statement stat){
if (con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stat!=null){
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
2.config.properties配置文件
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db_jdbc
username=root
password=root
3.StudentDaoImpl
public class StudentDaoImpl implements StudentDao {
@Override
public ArrayList<Student> findAll() {
ArrayList<Student> list =null;
Statement stat =null;
ResultSet rs =null;
Connection con =null;
try {
con = JDBCUtils.getConnection();
//获取执行对象
stat = con.createStatement();
//执行sql语句
String sql = "select * from student";
rs = stat.executeQuery(sql);
//创建集合
list = new ArrayList<>();
//处理结果
while (rs.next()){
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
Date birthday = rs.getDate("birthday");
Student stu = new Student(id, name, age, birthday);
list.add(stu);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.close(rs,con,stat);
}
return list;
}
@Override
public Student findById(Integer id) {
Student stu =null;
Statement stat =null;
ResultSet rs =null;
Connection con =null;
try {
con = JDBCUtils.getConnection();
//获取执行对象
stat = con.createStatement();
//执行sql语句
String sql = "select * from student where id = '"+id+"'";
rs = stat.executeQuery(sql);
//处理结果
while (rs.next()){
int sid = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
Date birthday = rs.getDate("birthday");
stu = new Student(sid, name, age, birthday);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.close(rs,con,stat);
}
return stu;
}
@Override
public int deleteById(Integer id) {
Statement stat =null;
Connection con =null;
int result = 0;
try {
con = JDBCUtils.getConnection();
//获取执行对象
stat = con.createStatement();
//执行sql语句
String sql = "delete from student where id='"+id+"'";
result = stat.executeUpdate(sql);
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.close(con,stat);
}
return result;
}
@Override
public int update(Student stu) {
Statement stat =null;
Connection con =null;
int result = 0;
try {
JDBCUtils.getConnection();
//获取执行对象
stat = con.createStatement();
//执行sql语句
Date date = stu.getBirthday();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String birthday = sdf.format(date);
String sql = "update student set id='"+stu.getId()+"',name='"+stu.getName()+"',age='"+stu.getAge()+"',birthday='"+birthday+"' where id='"+stu.getId()+"'";
result = stat.executeUpdate(sql);
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.close(con,stat);
}
return result;
}
@Override
public int insert(Student stu) {
Statement stat =null;
Connection con =null;
int result = 0;
try {
JDBCUtils.getConnection();
//获取执行对象
stat = con.createStatement();
//执行sql语句
Date date = stu.getBirthday();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String birthday = sdf.format(date);
String sql = "insert into student values ('"+stu.getId()+"','"+stu.getName()+"','"+stu.getAge()+"','"+birthday+"')";
result = stat.executeUpdate(sql);
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtils.close(con,stat);
}
return result;
}
}
4.StudentController
public class StudentController {
private StudentService studentService = new StudentServiceImpl();
//查询所有
@Test
public void findAll(){
ArrayList<Student> list = studentService.findAll();
for (Student stu : list) {
System.out.println(stu);
}
}
//根据id查询
@Test
public void findById(){
Student stu = studentService.findById(2);
System.out.println(stu);
}
//根据id删除删除
@Test
public void deleteById(){
int result = studentService.deleteById(5);
System.out.println(result);
}
//更新
@Test
public void update(){
Student stu = new Student(2, "李顺超", 31, new Date());
int result = studentService.update(stu);
if (result==0){
System.out.println("更新失败");
}else {
System.out.println("更新成功");
}
}
//新增
@Test
public void insert(){
Student stu = new Student(5, "王五", 25, new Date());
int result = studentService.insert(stu);
if (result==0){
System.out.println("添加失败");
}else {
System.out.println("添加成功");
}
}
}
注入攻击
1.注入攻击的介绍
-
SQL注入攻击:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全性问题( 输入用户随便,输入密码:‘a’ or ‘a’ = ‘a’)
-
SQL注入攻击的原理
- 按照正常来说,在密码输入框输入的都认为是密码的组成
- 当时现在Statement对象在执行sql语句时,将密码的一部分内容当成查询条件执行了
2.注入攻击的解决
- PreparedStatement:预编译执行者对象
- SQL语句中的参数使用**?**作为占位符
- 为 ?占位符赋值的方法:setXxx(参数1,参数2);
- Xxx代表:数据类型
- 参数1:?的位置编号(编号从1 开始)
- 参数2:?的实际参数
- 执行SQL语句
String sql = "select * from student where name = ? ";
pstm = con.preparedStatement(sql);
pstm = setString(1,"张三");
rs = stat.executeQuery();
JDBC管理事务
事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败。
- 管理事务的功能类:Connection
-开启事务
setAutoCommit(boolean autoCommit);参数为false,则开启事务
-回滚事务
rollback();
-提交事务
commit();
- 代码实现
public class JDBCDemo10 {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt1 = null;
PreparedStatement pstmt2 = null;
try {
//1.获取连接
conn = JDBCUtils.getConnection();
//开启事务
conn.setAutoCommit(false);
//2.定义sql
//2.1 张三 - 500
String sql1 = "update account set balance = balance - ? where id = ?";
//2.2 李四 + 500
String sql2 = "update account set balance = balance + ? where id = ?";
//3.获取执行sql对象
pstmt1 = conn.prepareStatement(sql1);
pstmt2 = conn.prepareStatement(sql2);
//4. 设置参数
pstmt1.setDouble(1,500);
pstmt1.setInt(2,1);
pstmt2.setDouble(1,500);
pstmt2.setInt(2,2);
//5.执行sql
pstmt1.executeUpdate();
// 手动制造异常
int i = 3/0;
pstmt2.executeUpdate();
//提交事务
conn.commit();
} catch (Exception e) {
//事务回滚
try {
if(conn != null) {
conn.rollback();
}
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}finally {
JDBCUtils.close(pstmt1,conn);
JDBCUtils.close(pstmt2,null);
}
}
}