JDBC全称Java DataBase Connectivity ( Java数据库连接 ),是Java语言操作数据库的一种技术。本质上是一个接口,具体的实现类由数据库厂商来实现
入门
编写一个jdbc文件
- 确保数据库已安装好
- 在模块中导入jar包
- 开写
public static void main(String[] args) throws SQLException, ClassNotFoundException {
//1.注册驱动(指定是哪个数据库的jar)
//Driver类中已经注册了一次驱动,所以会有驱动重复注册的问题,不建议使用
//DriverManager.registerDriver(new Driver());
//通过反射的方式加载Driver类
Class.forName("com.mysql.jdbc.Driver");//建议使用,但是不使用也行,在后来的驱动版本中,通过url间接确认数据库
//2.获取连接
String url = "jdbc:mysql://localhost:3306/jdbc";
String username = "root";
String password = "root";
//connection:数据库连接对象
Connection connection = DriverManager.getConnection(url, username, password);
//3.获取执行sql的对象
Statement statement = connection.createStatement();
//4.执行sql语句
//executeUpdate用于执行增删改(DML)语句, 其返回结果是一个数字,代表sql对数据库的影响行数
String sql = "insert into tbl_user values(null,'杨毅','123',3000)";
int i = statement.executeUpdate("insert into tbl_user values(null,'杨毅','123',3000)");
//executeQuery用于执行查询(DQL)语句, 其返回值是一个对象(数据的集合)
ResultSet resultSet = statement.executeQuery("select * from tbl_user");
//5.处理返回结果
//executeUpdate结果
System.out.println("处理了"+i+"条数据");
//executeQuery结果
List<User> list = new ArrayList<>();//创建集合保存用户数据
while (resultSet.next()){//判断条件为是否有下一行,如果有,将指针移动到下一行
//操作本行
int id = resultSet.getInt("id");
String name = resultSet.getNString("username");
String pass = resultSet.getNString("password");
int money = resultSet.getInt("money");
//并封装成实体对象
User user = new User(id, name, pass, money);
//添加进集合
list.add(user);
}
//打印
System.out.println(list);
//6.释放资源
statement.close();
connection.close();
}
jdbc事务+封装工具类
和sql中一样,一个事务中的一系列的操作要么全部成功,要么一个都不做。
MySQL中事务的相关方法
- 开启事务: begin
- 提交事务: commit
- 回滚事务: rollback
JDBC中事务的相关方法
- 开启事务: setAutoCommit(false)
- 提交事务: commit()
- 回滚事务: rollback()
工具类
package com.eponine.utils;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class Jdbc_utils {
static String url;
static String username;
static String password;
static String driverClass;
//静态代码块,仅在类被加载时运行一次,给成员变量赋值并且注册驱动
static {
//读取配置文件
InputStream resourceAsStream = Jdbc_utils.class.getClassLoader().getResourceAsStream("jdbc.properties");
Properties properties = new Properties();
try {
properties.load(resourceAsStream);
} catch (IOException e) {
e.printStackTrace();
}
//给成员变量赋值
url=properties.getProperty("url");
username=properties.getProperty("username");
password=properties.getProperty("password");
driverClass=properties.getProperty("driverClass");
//注册驱动(指定是哪个数据库的jar)
//通过反射的方式加载Driver类
try {
Class.forName(driverClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException {
//获取连接
Connection connection = DriverManager.getConnection(url, username, password);
//由于mysql默认事务提交方式为自动,这里设置成手动,否则会报错
connection.setAutoCommit(false);
return connection;
}
//提交并关闭
public static void commitAndClose(Connection connection, Statement statement, ResultSet resultSet) throws SQLException {
if (resultSet!=null){
resultSet.close();
}
if (statement!=null){
statement.close();
}
if (connection!=null){
connection.commit();
connection.close();
}
}
//回滚并关闭
public static void rollbackAndClose(Connection connection, Statement statement, ResultSet resultSet) throws SQLException {
if (resultSet!=null){
resultSet.close();
}
if (statement!=null){
statement.close();
}
if (connection!=null){
connection.rollback();
connection.close();
}
}
}
实体类
public static void main(String[] args) throws SQLException, ClassNotFoundException {
//获取连接
Connection connection = JDBCUtils03.getConnection();
//查询id为2的用户信息
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT * FROM tbl_user WHERE id = 2");
resultSet.next();
int id = resultSet.getInt("id");
String username1 = resultSet.getString("username");
String password1 = resultSet.getString("password");
int money = resultSet.getInt("money");
TblUser user = new TblUser(id,username1,password1,money);
System.out.println(user);
//关闭资源
JDBCUtils01.commitAndClose(connection,statement,resultSet);
}
sql注入
- 用户输入的内容作为了SQL语句语法的一部分,改变了原有 SQL真正的意义,这个问题称为SQL注入问题。
//sql注入数据 账号:随意 密码:abc' OR '1' ='1
ResultSet resultSet = statement.executeQuery("select * from tbl_user where username='杨晨'and password='abc' or '1'='1'");
- 解决方法 预编译
//编写一个带有占位符(?) 的SQL语句, 发往数据库编译
String sql = "select * from tbl_user where username=?and password=?";
//PreparedStatement表示预编译的SQL语句的对象
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//将参数传入
preparedStatement.setString(1,"杨晨");
preparedStatement.setString(2,"123456");
//执行sql语句(增删改用executeUpdate,查用executeQuery)
ResultSet resultSet = preparedStatement.executeQuery();
连接池
- 连接池是一个容器,它会在程序初始化完毕之后, 创建一批Connection对象,维护在自身的容器中。这样的设计既可以节约资源,减轻服务器压力,也可以提高连接复用性。
- 使用连接池(德鲁伊)
public static void main(String[] args) throws SQLException {
//1.创建连接池
DruidDataSource dataSource = new DruidDataSource();
//设置参数 基本四项(必须设置)
dataSource.setDriverClassName("com.mysql.jdbc.Driver");//驱动
dataSource.setUrl("jdbc:mysql://localhost:3306/jdbc");//连接
dataSource.setUsername("root");//用户名
dataSource.setPassword("root");//密码
//其他的可选项
dataSource.setMaxActive(10); //最大激活数
dataSource.setInitialSize(3); //初始个数
dataSource.setMaxWait(3000); //最大等待时间 单位毫秒
//获得连接
DruidPooledConnection connection = dataSource.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("select * from tbl_user");
//执行sql语句
ResultSet resultSet = preparedStatement.executeQuery();
//处理返回结果
List<User> list = new ArrayList<>();
while (resultSet.next()){
int id = resultSet.getInt("id");
String username = resultSet.getString("username");
String password = resultSet.getString("password");
int money = resultSet.getInt("money");
User user=new User(id,username,password,money);
list.add(user);
}
System.out.println(list);
}
- 连接池工具类
//创建连接池
private static DruidDataSource dataSource;
static {
InputStream resourceAsStream = DruidUtil.class.getClassLoader().getResourceAsStream("druidConfig.properties");
Properties properties = new Properties();
try {
properties.load(resourceAsStream);
dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
//获得连接
DruidPooledConnection connection = dataSource.getConnection();
connection.setAutoCommit(false);
return connection;
}