JDBC是oracle公司指定的一套规范(一套接口) ,用java操作数据库。
驱动:JDBC的实现类,由数据库厂商提供,可以通过一套规范操作不同的数据库(多态)。
JDBC的3个作用:连接数据库、发送sql语句、处理结果。
1.准备数据库和表
CREATE DATABASE day07;
USE day07;
create table category(
cid varchar(20) primary key,
cname varchar(20)
) character set = utf8;
insert into category values('c001','电器');
insert into category values('c002','服饰');
insert into category values('c003','化妆品');
insert into category values('c004','书籍');
2.创建一个项目,设置编码为utf-8
3.导入驱动jar包,mysql-connector-java-5.1.39-bin.jar
4.流程:注册驱动、获取连接、编写sql、创建预编译的语句执行者、设置参数、执行sql、处理结果、释放资源。
代码实现:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.junit.Test;
import com.itheima.utils.JdbcUtils;
import com.mysql.jdbc.Driver;
public class Hello {
@Test
public void f2() throws Exception{
//注册驱动
//Class.forName("com.mysql.jdbc.Driver");
DriverManager.registerDriver(new Driver());
//获取连接 ctrl+o 整理包
Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/day07", "root", "1234");
//编写sql
String sql="select * from category";
//创建语句执行者
PreparedStatement st=conn.prepareStatement(sql);
//设置参数
//执行sql
ResultSet rs=st.executeQuery();
//处理结果
while(rs.next()){
System.out.println(rs.getString("cid")+"::"+rs.getString("cname"));
}
//释放资源.
rs.close();
st.close();
conn.close();
}
//插入一条数据
@Test
public void f3(){
Connection conn=null;
ResultSet rs=null;
PreparedStatement st=null;
try {
//获取连接
conn=JdbcUtils.getConnection();
//编写sql
String sql="insert into category values(?,?)";
//获取语句执行者
st=conn.prepareStatement(sql);
//设置参数
st.setString(1, "c006");
st.setString(2, "户外");
//执行sql
int i=st.executeUpdate();
//处理结果
if(i==1){
System.out.println("success");
}else{
System.out.println("fail");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//释放资源
JdbcUtils.closeResource(conn, st, rs);
}
}
//更新
@Test
public void f11(){
Connection conn=null;
PreparedStatement st=null;
ResultSet rs=null;
try {
conn=JdbcUtils.getConnection();
String sql="update category set cname = ? where cid = ?";
st=conn.prepareStatement(sql);
st.setString(1, "手机");
st.setString(2, "c006");
int i=st.executeUpdate();
if(i==1){
System.out.println("success");
}else{
System.out.println("fail");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
//释放资源
JdbcUtils.closeResource(conn, st, rs);
}
}
//删除
@Test
public void f12(){
Connection conn=null;
PreparedStatement st=null;
ResultSet rs=null;
try {
conn=JdbcUtils.getConnection();
String sql="delete from category where cid = ?";
st=conn.prepareStatement(sql);
st.setString(1, "c006");
int i=st.executeUpdate();
if(i==1){
System.out.println("success");
}else{
System.out.println("fail");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
JdbcUtils.closeResource(conn, st, rs);
}
}
}
该类用于注册驱动,类中注册驱动的方法为:static void registerDriver(Driver driver)。
在DriverManager类被加载时,执行静态代码块,将会注册一次驱动,所以如果再使用register方法,将会注册两次驱动。
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
注册的方法主要三种(其实就是加载drivermanager类的方法)。
方式1:Class clazz = Class.forName("com.mysql.jdbc.Driver");//全限定名
方式2:类名.class;
方式3:对象.getClass();
获取连接:static Connection getConnection(String url, String user, String password)
参数1:协议:数据库类型:子协议参数
mysql: jdbc:mysql://localhost:3306/数据库名称
oracle: jdbc:oracle:thin@localhost:1521@实例
获取语句执行者:
(了解)Statement createStatement():获取普通的语句执行者,会出现sql注入问题
PreparedStatement prepareStatement(String sql):获取预编译语句执行者
(了解)CallableStatement prepareCall(String sql):获取调用存储过程的语句执行者
PreparedStatement:预编译语句执行者,接口。常用方法:
设置参数:setXxx(int第几个问号,Object实际参数):setInt、setString、setObject。
执行sql:
ResultSet executeQuery() :执行查询语句,返回值:结果集
int executeUpdate() :执行cud 语句,返回值:影响的行数
st=conn.prepareStatement(sql);
st.setString(1, "c006");
st.setString(2, "户外");
//执行sql
int i=st.executeUpdate();
//处理结果
if(i==1){
System.out.println("success");
}else{
System.out.println("fail");
}
执行查询语句之后返回的结果。常用方法:
判断是否有下一条记录:boolean next(),若有返回true且将光标移到下一行,若没有则返回false。光标一开始处于第一条记录的上面。
获取具体内容:getXxx(int|string),若参数为int :第几列,若参数为string:列名(字段名)。
例如:获取cname的内容可以通过,getString(2)或getString("cname")
getInt、getString 也可以获取int值、getObject 可以获取任意。
内容的格式:key=value,value不带“”。
若配置文件后缀名为.properties,并且放在src目录下,可以通过ResourceBundle工具快速获取里面的配置信息。
1.获取ResourceBundle 对象
static ResourceBundle getBundle("文件名称不带后缀名")
2.通过ResourceBundle对象获取配置信息
String getString(String key):通过执行key获取指定的value
使用jdbc的时候,操作一次都需要获取连接(创建)用完之后把连接释放掉了(销毁),通过连接池来优化curd操作。
连接池概述:管理数据库的连接,就是在连接池初始化的时候存入一定数量的连接,用的时候通过方法获取,不用的时候归还连接即可。所有的连接池必须实现一个接口 javax.sql.DataSource接口。
获取连接方法:Connection getConnection()
归还连接的方法就是以前的释放资源的方法,调用connection.close();
这个连接池不能够自动回收,只是作为了解,主要还是使用c3p0。
1.导入jar包(commons-dbcp-1.4.jar和commons-pool-1.5.6.jar)
2.使用api
a.硬编码
//创建连接池
BasicDataSource ds = new BasicDataSource();
//配置信息
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql:///day07");
ds.setUsername("root");
ds.setPassword("1234");
//设置好参数后,直接可以用连接池的连接了,接下来的代码和之前一样
Connection conn = ds.getConnection();
b.配置文件
Properties prop = new Properties();
prop.load(new FileInputStream("src/dbcp.properties"));
DataSource ds = new BasicDataSourceFactory().createDataSource(prop);
在配置文件中:首字母必须小写,因为在其类中,该字段就是这个名字,所以必须要保持一致。传入这个属性,其实就是类中提供的set方法。配置文件内容如下:
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/day07
username=root
password=123
hibernate和spring框架已经使用,有自动回收空闲连接的功能。
使用步骤:
1.导入jar包(c3p0-0.9.1.2.jar)
2.使用api
a.硬编码(不推荐)
ComboPooledDataSource ds = new ComboPooledDataSource();
ds.setDriverClass("com.mysql.jdbc.Driver");
ds.setJdbcUrl("jdbc:mysql:///day07");
ds.setUser("root");
ds.setPassword("1234");
Connection conn=ds.getConnection();
String sql="insert into category values(?,?);";
PreparedStatement st=conn.prepareStatement(sql);
//设置参数
st.setString(1, "c013");
st.setString(2, "毒药");
int i = st.executeUpdate();
System.out.println(i);
JdbcUtils.closeResource(conn, st, null);
b.配置文件
配置文件的名称:c3p0.properties 或者 c3p0-config.xml,配置文件的路径:src路径下。
c3p0.properties
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql:///day07
c3p0.user=root
c3p0.password=1234
c3p0-config.xml
com.mysql.jdbc.Driver
jdbc:mysql://127.0.0.1:3306/day07
root
1234
30000
30
10
30
100
10
200
com.mysql.jdbc.Driver
jdbc:mysql://127.0.0.1:3306/xxxx
root
1234
5
20
10
40
20
5
ComboPooledDataSource ds = new ComboPooledDataSource();//使用默认的配置
Connection conn=ds.getConnection();
String sql="insert into category values(?,?);";
PreparedStatement st=conn.prepareStatement(sql);
//设置参数
st.setString(1, "c124");
st.setString(2, "解药");
int i = st.executeUpdate();
System.out.println(i);
JdbcUtils.closeResource(conn, st, null);
new ComboPooledDataSource(String configName)在配置文件c3p0-config.xml中可以写多份的配置文件,通过这个名字来指定具体用哪一个。
是apache组织的一个工具类,更方便我们使用。
使用步骤:
1.导入jar包(commons-dbutils-1.4.jar)
2.创建一个queryrunner类
queryrunner作用:操作sql语句
构造方法:new QueryRunner(Datasource ds);
3.编写sql
4.执行sql
query(..):执行r操作
update(...):执行cud操作
QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
//2.编写sql
String sql="insert into category values(?,?)";
//3.执行sql
qr.update(sql, "c201","厨房电器");
QueryRunner:操作sql语句
构造器:new QueryRunner(Datasource ds);底层创建连接,创建语句执行者,释放资源。
常用方法:query(..),update(..):
DbUtils:释放资源,控制事务,是一个类
closeQuietly(conn):内部处理了异常
commitAndClose(Connection conn):提交事务并释放连接
ResultSetHandler:封装结果集,接口
ArrayHandler,ArrayListHandler,BeanHandler,BeanListHandler,ColumnListHandler,KeyedHandler,MapHandler, MapListHandler,ScalarHandler
(了解)ArrayHandler, 将查询结果的第一条记录封装成数组,返回
Object[] query = qr.query(sql, new ArrayHandler());
(了解)ArrayListHandler, 将查询结果的每一条记录封装成数组,将每一个数组放入list中返回
List
★★BeanHandler, 将查询结果的第一条记录封装成指定的bean对象返回,需要先创建一个用于接收返回值的类,数据库中有几个属性就相应地创建几个属性。
★★BeanListHandler,将查询结果的每一条记录封装成指定的bean对象,将每一个bean对象放入list中返回。
List
list = qr.query(sql, new BeanListHandler<>(Category.class));
(了解)ColumnListHandler, 将查询结果的指定一列放入list中返回。
(了解)MapHandler,将查询结果的第一条记录封装成map,字段名作为key,值为value 返回。
★MapListHandler,将查询结果的每一条记录封装map集合,将每一个map集合放入list中返回。
List
★ScalarHandler,针对于聚合函数,例如:count(*)返回的是一个Long值。
Long obj = (Long) qr.query(sql2, new ScalarHandler());