1.Jdbc概述
全称:Java database connectivity 用于java连接数据库
使用的是java代码连接数据库,对数据库进行增删改查。
JDBC是一种规范,mysql自己封装了一个jar包,这个包就是连接数据库的driver。
1.1入门案例介绍
步骤:
(1)下载jar包导入到工程中,附上连接:https://mvnrepository.com/ (2)在新建的工程里面的src下面创建lib文件 (3)将下载好的jar包导入到lib文件下面 (4)点击jar包,右键add as Libaray... 即可
代码中连接数据库的操作:
public class Demo1 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/java2304?useSSl=false";
String user = "root";
String password = "123456";
//建立与给懂数据库URL的连接
Connection connection = DriverManager.getConnection(url,user,password);
System.out.println(connection);
//关闭连接
connection.close();
}
}
1.2对数据库中的数据进行增删改
添加操作:使用Statement
public class Demo1 {
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/java2304?useSSL=false";
String user = "root";
String password = "123456";
Connection connection = DriverManager.getConnection(url,user,password);
//创建搬运工对象
Statement statement = connection.createStatement();
String sql = "insert into work(name,age,info)values('狗蛋',12,'比较狗')";
//执行
int i = statement.executeUpdate(sql);
//关闭连接
statement.close();
connection.close();
}
}
删除操作以及修改操作只需要修改SQL语句即可。
场景案例:查询所有数据之后,把所有数据赋值给一个对象,然后把对象存储到集合内。
public class Demo2 {
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
//2.准备连接数据库的参数
String url = "jdbc:mysql://localhost:3306/java2304?useSSL=false";
String user = "root";
String password = "123456";
//3.获取连接数据库的对象
Connection connection = DriverManager.getConnection(url, user, password);
//创建搬运工
Statement statement = connection.createStatement();
String sql = "select *from work";
//执行给定的SQL语句,该语句返回单个 ResultSet对象。
//一个ResultSet对象,其中包含给定查询产生的数据 就是数据库中的数据
ResultSet resultSet = statement.executeQuery(sql);
//创建集合
List<Work> list = new ArrayList<Work>();
while (resultSet.next()) {
//通过字段的值获取当前字段的数据
int id = resultSet.getInt(1);
String name = resultSet.getString("name");
int age = resultSet.getInt("age");
String info = resultSet.getString("info");
Work work = new Work(id, name, age, info);
list.add(work);
}
resultSet.close();
statement.close();
connection.close();
}
}
2.封装JdbcUtil工具类
工具类的作用:
1、获取Connection对象
2、关闭资源
需要新建一个叫db.properties的配置文件,需要在JdbcUtil这个类下面读取这个配置文件里面的内容。
封装的工具类:
public class JdbcUtil {
private static String url = null;
private static String user = null;
private static String password = null;
static {
try {
Properties properties = new Properties();
//流的形式
properties.load(new FileInputStream("D:\\IntelliJ IDEA\\review\\src\\db.properties"));
String driver = properties.getProperty("driver");
url = properties.getProperty("url");
user = properties.getProperty("user");
password = properties.getProperty("password");
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection () {
Connection connection = null;
try {
connection = DriverManager.getConnection(url, user, password);//本文章使用的是DriverManager获取的getConnection方法,接下来会讲连接池获取getConnection方法
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
//关闭资源
public static void close(Connection connection) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void close(Statement statement, Connection connection) {
try {
statement.close();
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void close(ResultSet resultSet, Statement statement, Connection connection) {
try {
resultSet.close();
statement.close();
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
配置文件:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/java2304?useSSL=false
user=root
password=123456
3.预处理搬运工
概念:
之前的搬运工对象Statement,主要功能就是把sql语句搬运到数据库进行执行,写的sql语句叫静态的sql语句。而预处理的搬运工对象处理的是参数化的sql语句,以后的开发中会常用。
静态的SQL语句: insert into work (name, age, info) values("你好", 12, "abc"); Statement 参数化的SQL语句: insert into work (name, age, info) values(?, ?, ?); PreparedStament
案例:
package com.qf.a_test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
public class Demo3 {
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/java2304?useSSL=false";
String user = "root";
String password = "123456";
Connection connection = DriverManager.getConnection(url, user, password);
//参数化sql语句
String sql = "insert into work(name,age,info)values(?, ?, ?)";
//预处理搬运工
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//赋值
preparedStatement.setObject(1,"卡卡西");
preparedStatement.setObject(2,34);
preparedStatement.setObject(3,"写轮眼");
//执行
int i = preparedStatement.executeUpdate();
System.out.println(i);
//关闭资源
preparedStatement.close();
connection.close();
}
}
4.sql注入【了解】
SQL注入:即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾后,添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
例如:
delete from emp where id = 6 or 1=1 一旦or 1=1,条件就没有用了
若是执行条件1=1,则会删除emp表内的全部数据
搬运工对象Statement是无法预防sql注入的,但是预处理的搬运工对象是可以预防sql注入的。
public class Demo4 {
public static void main(String[] args) throws Exception {
String sql = "delete from person where id = 1 or 1=1";
statementTest(sql);
String sql1 = "delete from user where id = ? or 1=1";
preparedStatementTest(sql1);
}
//搬运工--sql注入
public static void statementTest(String sql) throws Exception {
Connection connection = JdbcUtil.getConnection();
Statement statement = connection.createStatement();
int i = statement.executeUpdate(sql);
System.out.println(i);
JdbcUtil.close(statement, connection);
}
//预处理的搬运工--sql注入
public static void preparedStatementTest(String sql) throws Exception {
Connection connection = JdbcUtil.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setObject(1, "1");
int i = preparedStatement.executeUpdate();
System.out.println(i);
JdbcUtil.close(preparedStatement, connection);
}
}
5.JavaBean规范
JavaBean是实体类,写实体类的时候一定要规范
1、私有化变量
2、一定要提供一个无参构造方法
3、一定要提供set和get方法
4、每个类都要单独成为一个文件
package com.qf.a_test;
public class Work {
private int id;
private String name;
private int age;
private String info;
public Work() {
}
public Work(int id, String name, int age, String info) {
this.id = id;
this.name = name;
this.age = age;
this.info = info;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
public String toString() {
return "Work{id = " + id + ", name = " + name + ", age = " + age + ", info = " + info + "}";
}
}
6.元数据
元数据(Meta Date),关于数据的数据或者叫做用来描述数据的数据或者叫做信息的信息。 这些定义都很是抽象,我们可以把元数据简单的理解成,最小的数据单位。元数据可以为数据说明其元素或属性(名称、大小、数据类型、等),或其结构(长度、字段、数据列),或其相关数据(位于何处、如何联系、拥有者)。
关于sql参数的元数据
关于resultSet(结果集)的元数据
6.1关于sql参数的元数据
public class Demo1 {
public static void main(String[] args) throws SQLException {
Connection connection = JdbcUtil.getConnection();
String sql = "insert into work(name, age, info)values(?, ?, ?)";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//参数元数据
ParameterMetaData parameterMetaData = preparedStatement.getParameterMetaData();
//获取的是参数的个数
int parameterCount = parameterMetaData.getParameterCount();
System.out.println(parameterCount);
//数组
Object[] obj = {"鸣人",19,"旋螺丸"};
//借助于循环对?进行赋值
for (int i = 1; i <= parameterCount; i++) {
//执行赋值操作
preparedStatement.setObject(i, obj[i - 1]);
}
}
}
6.1关于结果集的元数据
public class Demo2 {
public static void main(String[] args) throws SQLException {
Connection connection = JdbcUtil.getConnection();
String sql = "select *from work";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//获取结果集对象使用executeQuery()方法
ResultSet resultSet = preparedStatement.executeQuery();
//通过结果集对象获取结果集元数据
ResultSetMetaData metaData = resultSet.getMetaData();
//只是获得的是参数的个数,用于循环条件
int columnCount = metaData.getColumnCount();
for (int i = 1; i <= columnCount; i++) {
//结果集元数据调用getColumnName方法
String columnName = metaData.getColumnName(i);
//打印的是字段
System.out.println(columnName);
}
//对字段进行赋值
while (resultSet.next()) {//行 光标会下移
for (int i = 1; i <= columnCount ; i++) {//列
String columnName = metaData.getColumnName(i);
Object object = resultSet.getObject(columnName);
System.out.println(object);
}
}
}
}
7.封装BaseDao
public class BaseDao {
//创建增删改方法
public int update(String sql, Object[] parameters) {
//创建数据路对象,从JdbcUtil中导入
Connection connection = JdbcUtil.getConnection();
//创建预处理搬运对象
PreparedStatement preparedStatement = null;
try {
preparedStatement = connection.prepareStatement(sql);
//通过元数据获取参数的个数
int parameterCount = preparedStatement.getParameterMetaData().getParameterCount();
//先判断数组参数
if (parameters != null && parameters.length == parameterCount) {
//循环赋值
for (int i = 1; i <= parameterCount; i++) {
preparedStatement.setObject(i, parameters[i - 1]);
}
}
//元数据执行
int i = preparedStatement.executeUpdate();
return i;
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtil.close(preparedStatement, connection);
}
return 0;
}
public <T> List<T> query(String sql, Object[] parameters, Class<T> cls) {
Connection connection = JdbcUtil.getConnection();
//预处理搬运对象
PreparedStatement preparedStatement = null;
//结果集对象
ResultSet resultSet = null;
try {
preparedStatement = connection.prepareStatement(sql);
//获取参数个数
int parameterCount = preparedStatement.getParameterMetaData().getParameterCount();
//判断
if (parameters != null && parameters.length == parameterCount) {
for (int i = 1; i <= parameterCount; i++) {
preparedStatement.setObject(i, parameters[i - 1]);
}
}
//执行sql语句,赋值给结果集
resultSet = preparedStatement.executeQuery();
//创建空集合
List<T> list = new ArrayList<T>();
//获取元数据结果集,通过结果集过去字段的名字和值
ResultSetMetaData metaData = resultSet.getMetaData();
//通过元数据的字段的个数
int columnCount = metaData.getColumnCount();
//遍历数据
while (resultSet.next()) {
//创建类的对象
T t = cls.getConstructor(null).newInstance(null);
//for循环对字段进行赋值
for (int i = 1; i <= columnCount; i++) {
//i指的是列,也就是字段的意思,获取的是字段
String columnName = metaData.getColumnName(i);
//获取字段值
Object value = resultSet.getObject(columnName);
System.out.println(value);
//13.获取数据库重点额数据之后,将数据赋值一个对象,得有类
//BeanUtils.setProperty(对象, 属性, 值) 设置值的语句
BeanUtils.setProperty(t, columnName, value);
}
//添加对象数据
list.add(t);
}
return list.size() != 0 ? list : null;
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtil.close(resultSet, preparedStatement, connection);
}
return null;
}
}