1.jdbc是什么,本质是什么
Java数据库连接,java可以操作各种关系型数据库
本质就是一个普通的java类,数据库厂商提供的驱动jar包,来实现sun公司提供一套"应用程序接口规范"
java.sql.Drvier 驱动接口
java.sql.DriverManager:驱动管理类(管理jdbc的驱动服务)
java.sql.Connection:与特定数据库的一种会话连接
java.sql.Statement:执行静态sql语句 (执行对象,操作数据库)
2.jdbc的基本操作步骤
1)导包注册驱动
Class.forName("com.mysql.jdbc.Driver"); //mysql5.5 /5.7---对应的jar包
//Class.forName("com.mysql.cj.jdbc.Driver") ;//mysql8.0 --对应jar包 8.0的jar包
2)获取数据库的连接对象
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/库名", //如果驱动包8.0 带参数
"root",
"123456"
);
3)准备好的sql语句
String sql = "sql语句";
4) 连接数据库的执行对象
Statement stmt = conn.createStatement();
5)执行sql,发送到数据库
//通用的更新表的记录(insert into, update , delete) executeUpdate(String sql)
int count = stmt . executeUpdate(sql);
6)输出结果
syso;
7)释放资源
stmt.close();
conn.close;
3.JDBC如何操作DQL语句,操作步骤
//1)导包,并注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2)获取数据库的连接对象
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/库名",
"root",
"数据库密码"
);
//3)准备sql语句--查询语句
String sql = "select*from 表名";
//4)获取执行对象Statement
Statement stmt = conn.createStatement();
//5)执行dql语句
ResultSet rs = stmt.executeQuery(sql);
//6)遍历结果集的数据
while(rs.next()){
字段类型 变量名 = rs.getXXX("字段名称");
//或者是 字段类型 变量名 = rs.getXXX(列的索引值); 列的索引值 从1..开始
//使用这个变量名
}
//7)释放资源
rs.close();
stmt.close();
conn.close();
4.封装JDBC基本操作的工具类的步骤
//配置文件
//在src目录下:类路径 xxx.properties
//driverClass=com.mysql.jdbc.Driver
//url=jdbc:mysql://localhost:3306/库名
//username=root
//password=登录的密码
class JdbcUtils{
private static String driverClass = null;
private static String url = null;
private static String username = null;
private static String password = null;
private JdbcUtils (){}
//提供静态代码块:随着类的加载而加载
static{
//创建属性列表:属性集合类 Properties
Properties prop = new Properties();
//读取配置文件 获取配置文件所在的输入流对象
InputStream inputStream = JdbcUtils.class.getClassLoader().getResurcesAsStream("xxx.properties");
//将流对象中的加载属性列表中prop
prop.load(inputStream);
//通过key获取它里面的value
driverClass = prop.getProperty("driverClass");
url = prop.getProperty("url");
user = prop.getProperty("username");
password = prop.getProperty("password");
//注册驱动
Class.forname(drivername);
}
//获取连接对象
public static Connection getConnection(){
Connection conn = DriverManager.getConnection(url,username,password);
return conn;
}
//释放资源--关闭相关系统资源(发送sql到数据库Statement执行对象,Connection,ResultSet)
public static void close(Statement stmt,Connection conn){
close(null,stmt,conn);
}
public static void close(ResultSet rs,Statement stmt,Connection conn){
if(rs!=null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrice();
}
}
..
...
}
}
5.JDBC使用PreparedStatement预编译对象操作数据库的步骤
//原生操作步骤
//1.导包 驱动包:5.1jar /8.0以及它以上的包
//2.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//3.获取数据库的连接对象
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/库名",
"root",
"密码"
);
//4)准备好参数化的DML语句
String sql = "insert into 表名 values(?,?,?,?...)";
String sql2 = "update 表名 set 字段名称1=?,字段名称2=?,字段名称3=?,where 字段名称=?";
String sql3 = "delete from 表名 where 字段名称 = ?" ;
//sql语句:参数化的DQL语句
String sql4 = "select * from 表名 " ;
String sql5 = "select * from 表名 where 字段名称 = ?" ;
//...
//5)获取预编译对象,同时将sql语句发送给数据库
PreparedStatement ps = conn.preparedStatement(sql);
//6)通过预编译对象,为参数赋值
ps.setXXX = ps.executeUpdate();
//7)要么执行DML语句
int count = ps.executeUpdate();
//影响行数 count
//执行的DQL语句
ResultSet rs = ps.executeQuary();
while(rs.next()){
//获取结果数据
xxx变量名 = rs.getXXX("列的名称或列的索引值");
}
//释放资源
//执行DQL语句
//执行DML语句,值需要释放后面两个对象 ps 对象 以及 conn对象
rs.close();
ps.close();
conn.close();
6.Statement和PreparedStatement对象的区别
1)执行sql效率区别
Statement对象:执行sql,每一次将sql都需要发送一次,相对于PreparedStatement对象效率低,不用它的原因
数据库的性能优化--->减少服务器的交互次数(和数据库的交互次数减少)
PreparedStatement对象:预编译对象: 执行的参数化的sql,直接先发送给数据库,数据库会进行校验(参数类型,以及参数的字段是哪一列),并且保存在预编译对象中,可以不断的重新赋值;执行sql效率高!
2)是否存在sql注入的区别
Statement对象:执行的sql语句,都是静态化sql,sql存在字符串拼接,就会导致可能出现sql注入,非常不安全!
举例
select * from user where username = '"+变量名+"' and password '"+值...+"' ;
PreparedStatement预编译对象:每次是在自己内存中直接赋值对应的值,sql语句永远是占位符号?
select * from user where username = ? and password = ? ;
不会造成sql注入问题,非常安全.
7.什么是数据库连接池,数据库连接池的好处是什么
数据库连接池:
可以分配,释放,管理数据库连接对象,当前某个连接对象释放之后,会归还到连接池中,大大提高了JDBC操作数据库性能!
弊端:维护成本高; (维护它druid的版本以及监控它的连接数量)
好处:可以设置参数,将数据库连接池进行调优;
每一个线程都会使用自己的连接对象!
前某个连接对象释放之后,会归还到连接池中,等待下一次利用(大大提高了连接对象的使用率)
在连接池中:会初始化一些连接数量(提供了很多参数)
initialSize:初始化数量
maxActive:最大激活数量
maxWait:最大等多等待时间(毫秒值)
maxidle:最大空闲数量
minidel:最小空闲数量
...
...
8.通过Druid获取数据源的操作步骤
//1)导包
//2)加入连接池的配置文件
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/exercise
username=root
password=123456
initialSize=5
maxActive=10
maxWait=3000
//3)读取配置文件
InputStream inputStream = 当前类.class.getClassLoader().getResourceAsStream("xxx.properties");
//4)创建属性集合列表
Properties prop = new Properties();
prop.load(inputStream);
//5)获取数据源---DruidDataSourceFactory -- 德鲁伊数据源工厂
//public static DataSource createDataSource(Properties prop)
DataSource ds = DruidDataSourceFactory.createDataSource(prop);
//DataSource替代了DriverManager: Connection getConnection() ;
//6)获取连接对象
Connection conn = ds.getConnection();
//使用连接对象
9.封装jdbc工具类,加入数据库连接池以及ThreadLocal的步骤
//为了模拟真实场景:一个线程使用自己的连接对象--操作数据库
class DruidJdbcUtils{
//成员变量
private static DataSource ds ; //数据源
private staitc ThreadLocal<Connection> t1 = new ThreadLocal<>() ;//当前线程对象
private DruidJdbcUtils(){}
//静态代码块
static{
//1)需要读取连接池的配置文件
//创建属性集合列表
Propereties prop = new Properties() ;
//获取连接池配置文件的所在的输入流对象
InputStream inputStream = DruidJdbcUtils.class.getClassLoader().getRresourceAsStream("druid.properties") ;
//将资源输入流加载到属性列表中
prop.load(inputStream) ;
//2)获取数据源---给成员变量ds赋值
//使用德鲁伊的工厂
ds = DruidDataSourceFactory.createDataSource(prop) ;
}
//封装:获取连接对象的功能
public static Connection getConnection(){
//首先:从当前线程中获取连接对象
Connection conn = t1.get() ;
if(conn ==null){
//当前线程持有连接对象
//从数据源:连接池中获取
conn = ds.getConnection() ;
//将连接对象绑定到当前线程中
t1.set(conn) ;
}
return conn ;
}
//关闭资源---是否conn对象---close()---->t1.remove()解绑; 从当前线程中解绑
}
10.commons-dbutils的说明
commons-dbutils的官网地址: Apache组织机构旗下的开源的工具类库
https://commons.apache.org/proper/commons-dbutils/
就是被用来完成jdbc操作,简化了jdbc操作的一种书写格式(查询多条记录,将这些记录封装List中)
针对原生Jdbc的简易封装完成jdbc操作
使用步骤:
1)需要导入核心的jar包 commons-dbtils.jar
mysql驱动jar包
连接池--druid的jar包
junit单元测试:核心包junit.jar以及依赖包2)有关commons-dbtils.jar 核心接口以及核心类有哪些
使用的执行对象:操作数据库
org.apache.commons.dbutils.QueryRunner 里面封装就是PreparedStatement
两个通用的方法
query(xxx,ResultSetHandler rsh):针对dql语句来完成查询操作
update(xxx,xx):针对dml域操作:insert into,update,delete from ....
核心接口:ResultSetHandler:针对结果集的处理实现类
BeanListHandler:可以将查询的多条记录封装到List集合中
BeanHandler:将查询的结果集中某条记录封装到一个Java实体类中
ScalarHandler:查询出的单行单列的数据----查询出总记录数(经常用到) :聚合函数
select count(id字段) from 表名 ; -----封装到Object对象中