Jdbc的本质就是实现sun提供的一套接口规范,实现了sun提供java.sql.xxx接口
Driver/Connection/Statement/ResultSet..
1.jdbc原生7大步骤
1)Jdbc操作DML语句的操作步骤
//导驱动jar包
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//获取数据库连接对象getConnection(url,user,password)
Connection conn=
DriverManager.getConnection("jdbc:mysql://localhost:3306/库名","root","123465");
//sql语句
Stirng sql="insert into 表名(字段列表) values(实际参数列表...)";
//创建执行对象
Statement stmt=conn.createStatement();
//执行sql语句,发送给数据库
int count=stmt.executeUpdate(sql);
//释放资源
stmt.close();
conn.close();
2)jdbc操作DQL语句的操作步骤
//导入驱动jar包
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//获取数据库连接对象
Connection conn=
DriverManager.getConnection("jdbc:mysql://localhost:3306/库名","root","123456");
//sql语句
String sql="select * from 表名";
//创建执行对象
Satatement stmt=conn.createStatement();
//执行sql语句,发送给数据库
ResultSet rs=stmt.executeQuery(sql);
//遍历结果集
while(rs.next()){ //将光标从当前位置向前移动一行,ResultSet光标最初位于第一行之前
//获取
//xxx getxxx(int columnIndex):通过列的索引值获取列的内容呢
int id=rs.getInt(1);
//xxx getxxx(String columnLaber):通过列的名称获取当前的内容(就是字段名称)
int id=rs.getInt("id");
}
//释放资源
stmt.close();
conn.close();
2.封装jdbc的工具类JdbcUtils
封装了:1.导包 2.注册驱动 3.创建数据库连接对象 4.释放资源
1)src下面:提供jdbc.properties
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/库名
user=root
password=123456
2)工具类
class JdbcUtils{
private static String driverClass=null;
private static String url=null;
private static String user=null;
private static String password=null;
//外界不能new对象
private JdbcUtils(){}
//静态代码块:随着类的加载而加载
static{
Properrties prop=new Properties();
InputStream inputstream=
JdbcUtils.classgetClassLoader().getResourAsStream("jdbc.properties");
prop.load(inputstream);
driverClass=prop.getProperty("driverClass");
user=prop.getProperty("user");
url=prop.getProperty("url");
password=prop.getProperty("password");
//注册驱动
Class.forName(driverClass);
//捕获异常
}
//提供功能:获取连接对象
public static Connecton getConnectoin(){
Connection conn=DriverManager.getConnection(url,user,password);
return conn;
}
//释放资源
//针对DQL语句关闭ResultSet,Statement,Connection
public static void close(ResultSet rs,Statement stmt,Connection conn){
if(rs!=null){
rs.close();
}
if(stmt!=null){
stmt.close();
}
if(conn!=null){
conn.close();
}
}
//针对DML语句关闭statement,connection
public static void close(Statement stmt,Connection conn){
close(null,stmt,conn);
}
}
3.Statement执行对象操作数据库
1)通过JdbcUtils工具类获取连接对象
Connection conn=JdbcUtils.getConnection();
2)sql语句
DML语句:
String sql="insert into 表名(字段名称1,字段名称2) values(值1,值2)";
String sql="update 表名 set 字段名称1=?,字段名称2=?,where 字段名称=值";
String sql="delete * from 表名 where 字段名称=值";
DQL语句:
String sql="select * from 表名 where name like 值";
String sql="select * from 表名";
3)通过连接对象获取执行对象
Statement stmt=conn.createStatement();
4)执行sql语句
//DML语句
int count=stmt.executeUpdate(sql);
//DQL语句
ResultSet rs=stmt.executeQuery(sql);
while(rs.next()){
//rs.getXXX("列的名称/列的索引值")
//封装数据
}
//释放资源
JdbcUtils.close(rs,stmt,conn);
4.PreparedStatement预编译对象操作数据库
1)通过JdbcUtils工具类获取连接对象
Connection conn=JdbcUtils.getConnection();
2)sql语句
//sql语句中可以用英文问号占位 参数化的sql语句
DML语句:
String sql="insert into 表名(字段名称1,字段名称2) values(?,?)";
String sql="update 表名 set 字段名称1=?,字段名称2=?,where 字段名称=?";
String sql="delete * from 表名 where 字段名称=?";
DQL语句:
String sql="select * from 表名 where name like ?";
String sql="select * from 表名";
3)创建执行对象,将sql语句发送给数据库编译,将sql语句保存预编译对象中
PreParedStatement ps=conn.prepareStatement(sql);
4)传参
ps.setXXX(1,xx);
ps.setXXX(2,xx);
5)执行
//执行DML语句
ps.executeUpdate();
//执行DQL语句
ResultSet rs=ps.executeQuery();
while(rs.next()){
//rs.getXXX("列的名称/列的索引值")
//封装数据
}
6)释放资源
JdbcUtils.close(rs,stmt,conn);
5.Statement和PreparedStatement的区别
两者共同点:
他们都可以称为"数据库执行对象",将sql语句发送给数据库,两个都是接口(java.sql.接口/核心类),他们都被数据库厂商提供的驱动jar包子实现类实现这些接口;
他们两个是一个继承关系 interface PreparedStatement extends Statement
不同点:
Statement:执行静态sql语句,静态sql语句存在"硬编码行为",这些参数值可能变量,存在字符串拼接sql语句,就造成sql注入,相对于PreparedStatement不安全,执行sql语句效率相对PreparedStatement来说,效率低.
Statement stmt=数据库连接对象.createStatement();
stmt.executeUpdate(sql)---发送sql语句到数据库(每一条sql,都需要Statement执行)
PreparedStatement:执行预编译的sql语句,称为"参数化sql语句",参数都使用占位符号"?",不存在字符串拼接,相对于Statement安全,有效防止sql注入,执行sql语句,执行效率相对于Statement来说,效率高(一条sql语句,频繁的区使用它)
String sql="insert into 表名(字段名称1,字段名称2,字段名称3) values(?,?,?)";
将sql发送给数据库编译,将sql语句保存预编译对象中
PreparedStatement ps=数据库连接对象.prepareStatement(sql);
ps.setXXX(1,xx);
ps.setXXX(2,xx);
//执行
ps.executeUpdate();
ps.setXXX(1,xx);
ps.setXXX(2,xx);
执行
ps.executeUpdate();
6.jdbc方式管理事务
java.sql.Connection:
public void setAutoCommit(boolean auto);是否开启事务:默认自动提交
public void rollback();事务回滚
public void commit();提交事务
7.Druid连接池
对获取连接对象的优化
数据库连接池负责,管理以及释放数据库连接的,允许应用程序可以重复利用某个连接对象,而不新建一个连接对象;
为什么使用连接池?
连接数据库消耗时间,不断消耗资源,,需要建立通道(初次握手),身份校验以及连接数据库的字符信息(XXX.properties),当一个用户发送请求,访问服务器端,连接数据库,每一个用户使用完毕连接对象,就直接释放了,消耗资源严重,使用连接池,他是一个容器,初始化数量,最大连接数量,超过最大连接数量的等待时间以及连接数据库的基本信息,会自动将容器中的参数进行封装,可以重复利用某个连接对象,而不会新建一个连接对象;
连接池的好处:
节省资源,防止资源消耗
是一个容器,大大提供服务器的性能
//导入druid.jar包
//加入连接池,以及模拟线程场景,每一个线程使用自己的Connection
class DruidJdbcUtils{
//声明数据源
private static DataSource ds;
//创建线程对象,每一个线程使用自己的Coonection
private static ThreadLocal<Connection> t1=new ThreadLocal<>();
//构造方法私有化---外界不能new 对象了
//静态代码块
static{
//1)读取src下面的连接池的配置文件
//创建属性集合列表
Properties prop= new Properties();
//读取文件
InputStream inputstream=
DruidJdbcUtils.class.getClassLoader.getResourAsStream("连接池的配置文件");
//2)加载资源输入流
prop.load(inputstream);
//3)
使用DruidDataSourceFactory工厂类创建数据源
ds=DruidDataSourceFactory.createDataSource(prop);
}
//封装一个方法:获取数据源
public static DataSource getDataSource(){
return ds;
}
//封装一个方法,获取连接对象
public static Connection getConnection(){
//从当前线程中获取连接对象
Connection conn=t1.get();
//判断如果为null
if(conn==null){
//当前线程没有绑定连接对象
//从线程池获取连接对象
conn = ds.getConnection();
//将当前连接对象绑定到当前线程中
t1.set(conn);
}
return conn;
}
}
8.Common-Dbutils
对执行对象的优化
1)导入jar包:Commons-Dbutils-1.6.jar
mysql驱动jar包
druid的jar包
2)在接口实现类中完成jdbc操作
//执行对象QueryRunner(DataSource ds)
QueryRunner qr=new QueryRunner(DruidJdbcUtils.getDataSource);
3)准备sql语句
String sql="insert into /delete from/update";
String sql="select..."
4)通用固定更新方法 update
int count=qr.update(sql,实际参数...);
通用的查询方法 query(String sql,ResultSetHandler rsh,object...params)
参数1:sql语句
参数2:查询结果集的处理---接口
将查询的多条记录添加到List集合中,List<T>---子实现类BeanListHandler<T> BeanListHadnler<T>(Class<T> type)
将查询的某条记录封装到Java实体中-----子实现类BeanHandler<T>
BeanHadnler<T>(Class<T> type)
查询单元单例的数据---一般统计/平均分/最大值...聚合函数---->子实现类ScalorHandler<>()---->Object
参数3:查询中有条件,条件的实际参数
List<T> list = qr.query(sql,子实现类,实际参数...);
T t = qr.query(sql,子实现类,实际参数...);
//输出结果