博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javaWeb基础07-jdbc
阅读量:4130 次
发布时间:2019-05-25

本文共 18391 字,大约阅读时间需要 61 分钟。

目录

案例1-通过jdbc完成单表的curd操作

jdbc:

java操作数据库.jdbc是oracle公司指定的一套规范(一套接口)驱动:jdbc的实现类.由数据库厂商提供.我们就可以通过一套规范操作不同的数据库了(多态)jdbc作用:	连接数据库	发送sql语句	处理结果

jdbc操作步骤:★

1.数据库和表2.创建一个项目3.导入驱动jar包4.编码:	注册驱动	获取连接	编写sql	创建预编译的语句执行者	设置参数	执行sql	处理结果	释放资源初始化数据库和表:
CREATE DATABASE day07;USE day07;	create table category(	cid varchar(20) primary key,	cname varchar(20));insert into category values('c001','电器');insert into category values('c002','服饰');insert into category values('c003','化妆品');insert into category values('c004','书籍');
IDE打开之后	1.修改字符集 utf-8	2.新建 java项目	3.使用的jdk为自己的jdk 不用使用内置使用junit单元测试	要求:		1.方法是public void xxx(){}		2.在方法上添加 @Test		3.在@Test 按下 ctrl+1(快速锁定错误)		4.在方法上右键 run as  -->junit 就可以执行方法了.

jdbc-api详解:

所有的包 都是 java.sql 或者 javax.sqlDriverManager:管理了一组jdbc的操作 类	常用方法:		了解:注册驱动				static void registerDriver(Driver driver) :				通过查看 com.mysql.jdbc.Driver的源码 有如下代码
static {
try {
java.sql.DriverManager.registerDriver(new Driver());//这段代码我们已经写过 } catch (SQLException E) {
throw new RuntimeException("Can't register driver!"); }}
驱动注册了两次.我们只需要将静态代码块执行一次,类被加载到内存中会执行静态代码块,并且只执行一次.				现在只需要将类加载到内存中即可:					方式1:						★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@实例									参数2:账户名 root				参数3:密码(了解)Driver:java.sql 接口 驱动Connection:连接 接口	常用方法:		获取语句执行者:			(了解)Statement createStatement() :获取普通的语句执行者  会出现sql注入问题			★PreparedStatement prepareStatement(String sql) :获取预编译语句执行者			(了解)CallableStatement prepareCall(String sql):获取调用存储过程的语句执行者		了解:			setAutoCommit(false) :手动开启事务			commit():提交事务			rollback():事务回滚Statement:语句执行者 接口PreparedStatement:预编译语句执行者 接口	常用方法:		设置参数:			setXxx(int 第几个问号,Object 实际参数);				常见的方法:					 setInt					 setString					 setObject				执行sql:			 ResultSet executeQuery() :执行 r 语句 返回值:结果集			 int executeUpdate() :执行cud 语句 返回值:影响的行数ResultSet:结果集 接口	执行查询语句之后返回的结果		常用方法:			boolean next():判断是否有下一条记录,若有返回true且将光标移到下一行,若没有呢则返回false				光标一开始处于第一条记录的上面						获取具体内容				getXxx(int|string)					若参数为int :第几列					若参数为string:列名(字段名)				例如:					获取cname的内容可以通过						getString(2)						getString("cname")				常用方法:					getInt					getString 也可以获取int值					getObject 可以获取任意

常见的配置文件格式:

1.properties	里面内容的格式 key=value2.xml若我们的配置文件为properties,并且放在src目录下.我们可以通过 ResourceBundle工具快速获取里面的配置信息	使用步骤:		1.获取ResourceBundle 对象:			static ResourceBundle getBundle("文件名称不带后缀名") 		2.通过ResourceBundle 对象获取配置信息 			String getString(String key) :通过执行key获取指定的value

案例

@Testpublic void test2() throws Exception {
//注册驱动 //DriverManager.registerDriver(new Driver()); //为什么不用DriverManager.registerDriver(new Driver());?因为Driver内部又注册了一次。 Class.forName("com.mysql.jdbc.Driver"); //获取连接 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day07", "root", "123456"); //创建执行语句预编译对象 PreparedStatement ps = conn.prepareStatement("select * from category"); //设置参数 //执行sql,获取结果集 ResultSet rs = ps.executeQuery(); while (rs.next()) {
String cid = rs.getString("cid"); String cname = rs.getString("cname"); System.out.println("test2---cid="+cid+",cname="+cname); } //释放资源:关闭connection resultset ps rs.close(); ps.close(); conn.close();}

封装 注册驱动+获取连接 和释放资源的操作:

@Testpublic void test3() throws Exception {
//注册驱动 +获取连接 Connection conn = Jdbc1Utils.getConnection(); //创建执行语句预编译对象 PreparedStatement ps = conn.prepareStatement("select * from category"); //设置参数 //执行sql,获取结果集 ResultSet rs = ps.executeQuery(); while (rs.next()) {
String cid = rs.getString("cid"); String cname = rs.getString("cname"); System.out.println("test3---cid="+cid+",cname="+cname); } //释放资源:关闭connection resultset ps Jdbc1Utils.closeResource(rs, ps, conn);}
public class Jdbc1Utils {
public static Connection getConnection() throws Exception {
//注册驱动 Class.forName("com.mysql.jdbc.Driver"); //获取连接 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day07", "root", "123456"); return conn; } public static void closeResource(ResultSet rs,Statement st,Connection conn) {
closeResultSet(rs); closeStatement(st); closeConnection(conn); } public static void closeResultSet(ResultSet rs) {
if(null!=rs) {
try {
rs.close(); } catch (Exception e) {
e.printStackTrace(); } rs=null; } } public static void closeStatement(Statement st) {
if(null!=st) {
try {
st.close(); } catch (Exception e) {
e.printStackTrace(); } st=null; } } public static void closeConnection(Connection conn) {
if(null!=conn) {
try {
conn.close(); } catch (Exception e) {
e.printStackTrace(); } conn=null; } }}

优化: 数据库的信息我们应该写到配置文件里面,这样改的话比较方便

@Testpublic void test4() throws Exception {
Connection conn = JdbcUtils.getConnection(); //创建执行语句预编译对象 PreparedStatement ps = conn.prepareStatement("select * from category"); //设置参数 //执行sql,获取结果集 ResultSet rs = ps.executeQuery(); while (rs.next()) {
String cid = rs.getString("cid"); String cname = rs.getString("cname"); System.out.println("test4---cid="+cid+",cname="+cname); } //释放资源:关闭connection resultset ps JdbcUtils.closeResource(rs, ps, conn);}
public class JdbcUtils {
public static final String DRIVERCLASS; public static final String URL; public static final String USER; public static final String PASSWORD; //jdbc// static {
// ResourceBundle bundle = ResourceBundle.getBundle("jdbc");// DRIVERCLASS = bundle.getString("driverClass");// URL = bundle.getString("url");// USER = bundle.getString("user");// PASSWORD = bundle.getString("password");// } //c3p0 // static {
// ResourceBundle bundle = ResourceBundle.getBundle("c3p0");// DRIVERCLASS = bundle.getString("c3p0.driverClass");// URL = bundle.getString("c3p0.jdbcUrl");// USER = bundle.getString("c3p0.user");// PASSWORD = bundle.getString("c3p0.password");// } //dbcp static {
ResourceBundle bundle = ResourceBundle.getBundle("dbcp"); DRIVERCLASS = bundle.getString("driverClassName"); URL = bundle.getString("url"); USER = bundle.getString("username"); PASSWORD = bundle.getString("password"); } static {
//注册驱动 try {
Class.forName(DRIVERCLASS); } catch (ClassNotFoundException e) {
e.printStackTrace(); } } public static Connection getConnection() throws Exception {
//获取连接 Connection conn = DriverManager.getConnection(URL, USER, PASSWORD); return conn; } public static void closeResource(ResultSet rs,Statement st,Connection conn) {
closeResultSet(rs); closeStatement(st); closeConnection(conn); } public static void closeResultSet(ResultSet rs) {
if(null!=rs) {
try {
rs.close(); } catch (Exception e) {
e.printStackTrace(); } rs=null; } } public static void closeStatement(Statement st) {
if(null!=st) {
try {
st.close(); } catch (Exception e) {
e.printStackTrace(); } st=null; } } public static void closeConnection(Connection conn) {
if(null!=conn) {
try {
conn.close(); } catch (Exception e) {
e.printStackTrace(); } conn=null; } }}

增:

@Testpublic void test5() throws Exception {
Connection conn = JdbcUtils.getConnection(); //创建执行语句预编译对象 PreparedStatement ps = conn.prepareStatement("insert into category values(?,?)"); //设置参数 ps.setObject(1, "c007"); ps.setString(2, "小米手机"); int executeUpdate = ps.executeUpdate(); System.out.println("test5---executeUpdate="+executeUpdate); //释放资源:关闭connection resultset ps JdbcUtils.closeResource(null, ps, conn);}

改:

@Testpublic void test6() throws Exception {
Connection conn = JdbcUtils.getConnection(); //创建执行语句预编译对象 PreparedStatement ps = conn.prepareStatement("update category set cname=? where cid=?"); //设置参数 ps.setObject(1, "小米9"); ps.setString(2, "c008"); int executeUpdate = ps.executeUpdate(); System.out.println("test6---executeUpdate="+executeUpdate); //释放资源:关闭connection resultset ps JdbcUtils.closeResource(null, ps, conn);}

删:

@Testpublic void f7() throws Exception {
//获取连接 Connection conn = JdbcUtils.getConnection(); //语句执行者 PreparedStatement ps = conn.prepareStatement("delete from category where cid=?"); //执行 ps.setString(1, "c007"); int executeUpdate = ps.executeUpdate(); System.out.println("test7---executeUpdate="+executeUpdate); //释放资源 //释放资源:关闭connection resultset ps JdbcUtils.closeResource(null, ps, conn);}

案例2-通过连接池(数据源)优化我们的操作.

需求:

使用jdbc的时候,没操作一次都需要获取连接(创建)用完之后把连接释放掉了(销毁),通过连接池来优化curd操作.

技术分析:

连接池

连接池概述:

管理数据库的连接,作用:	提高项目的性能.就是在连接池初始化的时候存入一定数量的连接,用的时候通过方法获取,不用的时候归还连接即可.所有的连接池必须实现一个接口 javax.sql.DataSource接口获取连接方法:	Connection getConnection() 归还连接的方法就是以前的释放资源的方法.调用connection.close();自定义一个连接池(理解思想)

常用连接池:

DBCPC3P0

增强方法

1.继承2.装饰者模式(静态代理)3.动态代理

装饰者模式:★★★

使用步骤:	1.装饰者和被装饰者实现同一个接口或者继承同一个类	2.装饰者中要有被装饰者的引用	3.对需要增强的方法进行加强	4.对不需要加强的方法调用原来方法

常用的连接池:

DBCP:(理解)

apache组织	使用步骤:		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");			b.配置文件				实现编写一个properties文件				//存放配置文件				Properties prop = new Properties();				prop.load(new FileInputStream("src/dbcp.properties"));				//设置				//prop.setProperty("driverClassName", "com.mysql.jdbc.Driver");								//创建连接池				DataSource ds = new BasicDataSourceFactory().createDataSource(prop);

C3P0:(★)

hibernate和spring使用	有自动回收空闲连接的功能.	使用步骤:		1.导入jar包(c3p0-0.9.1.2.jar)		2.使用api			a.硬编码(不推荐)				new ComboPooledDataSource()			b.配置文件				配置文件的名称:c3p0.properties 或者 c3p0-config.xml				配置文件的路径:src下							编码只需要一句话					new ComboPooledDataSource()//使用默认的配置					new ComboPooledDataSource(String configName)//使用命名的配置 若配置的名字找不到,使用默认的配置

自定义简易连接池

public static void main(String[] args) {
MyDateSource ds = new MyDateSource(); Connection conn = ds.getConnection();// Connection conn = MyDateSource.getConnection(); System.out.println(conn); MyDateSource.addBack(conn);}
public class MyDateSource {
public static LinkedList
pooList=new LinkedList
(); //创建3个连接,并放入集合中 static {
for (int i = 0; i < 3; i++) {
try {
Connection conn = JdbcUtils.getConnection(); pooList.addLast(conn); } catch (Exception e) {
e.printStackTrace(); } } } //取任意一个连接 public static Connection getConnection() {
//取之前判断连接池是否为空,为空则新增3个 if(pooList.isEmpty()) {
for (int i = 0; i < 3; i++) {
try {
Connection conn = JdbcUtils.getConnection(); pooList.addLast(conn); } catch (Exception e) {
e.printStackTrace(); } } } return pooList.removeFirst(); } //归还连接 public static void addBack(Connection conn) {
pooList.addLast(conn); }}

Connection 装饰者模式+简易连接池(各连接池jar的原理)

Connection 装饰者模式:

public class ConnectionWrap implements Connection {
private Connection conn; private LinkedList
list; public ConnectionWrap(Connection conn,LinkedList
list) {
this.conn=conn; this.list=list; } @Override public
T unwrap(Class
iface) throws SQLException {
return conn.unwrap(iface); } @Override public boolean isWrapperFor(Class
iface) throws SQLException {
// TODO Auto-generated method stub return false; } @Override public Statement createStatement() throws SQLException {
return conn.createStatement(); } @Override public PreparedStatement prepareStatement(String sql) throws SQLException {
return conn.prepareStatement(sql); } @Override public void close() throws SQLException {
System.out.println("close前---"+list.size()); list.addLast(this); System.out.println("close后---"+list.size()); } ...}

自定义简易连接池:

public class MyDateSource {
public static LinkedList
pooList=new LinkedList
(); //创建3个连接,并放入集合中 static {
for (int i = 0; i < 3; i++) {
try {
Connection conn = JdbcUtils.getConnection(); pooList.addLast(conn); } catch (Exception e) {
e.printStackTrace(); } } } //取任意一个连接 public static Connection getConnection() {
//取之前判断连接池是否为空,为空则新增3个 if(pooList.isEmpty()) {
for (int i = 0; i < 3; i++) {
try {
Connection conn = JdbcUtils.getConnection(); pooList.addLast(conn); } catch (Exception e) {
e.printStackTrace(); } } } Connection conn = pooList.removeFirst(); ConnectionWrap wrap = new ConnectionWrap(conn, pooList); return wrap; } //归还连接 public static void addBack(Connection conn) {
pooList.addLast(conn); }}

测试:

public static void main(String[] args) throws SQLException {
MyDateSource ds = new MyDateSource(); Connection conn = ds.getConnection(); System.out.println(conn); conn.close();}

dbcp连接池

在这里插入图片描述

  • 需要2个jar: commons-dbcp-1.4.jar+commons-pool-1.5.6.jar
@Testpublic void f1() throws SQLException {
//创建数据源 BasicDataSource ds = new BasicDataSource(); ds.setDriverClassName("com.mysql.jdbc.Driver"); ds.setUrl("jdbc:mysql:///day07"); ds.setUsername("root"); ds.setPassword("123456"); //获取连接 Connection conn = ds.getConnection(); PreparedStatement ps = conn.prepareStatement("insert into category values(?,?)"); ps.setString(1, "c008"); ps.setString(2, "苹果12"); //执行 int executeUpdate = ps.executeUpdate(); JdbcUtils.closeResource(null, ps, conn);}@Testpublic void f2() throws Exception {
Properties properties=new Properties(); properties.load(new FileInputStream("src/dbcp.properties")); //创建数据源 DataSource ds = BasicDataSourceFactory.createDataSource(properties); //获取连接 Connection conn = ds.getConnection(); PreparedStatement ps = conn.prepareStatement("insert into category values(?,?)"); ps.setString(1, "c009"); ps.setString(2, "苹果13"); //执行 int executeUpdate = ps.executeUpdate(); JdbcUtils.closeResource(null, ps, conn);}

dbcp.properties:

driverClassName=com.mysql.jdbc.Driverurl=jdbc:mysql:///day07username=rootpassword=123456

9

c3p0连接池

c3p0-0.9.1.2.jar

@Testpublic void f1() throws Exception {
ComboPooledDataSource ds=new ComboPooledDataSource(); //如果默认是c3p0.properties,下面的4行可以省略 ds.setDriverClass("com.mysql.jdbc.Driver"); ds.setJdbcUrl("jdbc:mysql:///day07"); ds.setUser("root"); ds.setPassword("123456"); //获取连接 Connection conn = ds.getConnection(); PreparedStatement ps = conn.prepareStatement("insert into category values(?,?)"); ps.setString(1, "c010"); ps.setString(2, "苹果10"); //执行 int executeUpdate = ps.executeUpdate(); JdbcUtils.closeResource(null, ps, conn);}

封装数据库参数:

@Testpublic void f2() throws Exception {
ComboPooledDataSource ds=new ComboPooledDataSource("c3p0.properties"); //获取连接 Connection conn = ds.getConnection(); PreparedStatement ps = conn.prepareStatement("insert into category values(?,?)"); ps.setString(1, "c011"); ps.setString(2, "苹果11"); //执行 int executeUpdate = ps.executeUpdate(); JdbcUtils.closeResource(null, ps, conn);}

案例3-使用dbutils完成curd操作

dbutils:

是apache组织的一个工具类,jdbc的框架,更方便我们使用使用步骤:	1.导入jar包(commons-dbutils-1.4.jar)	2.创建一个queryrunner类		queryrunner作用:操作sql语句			构造方法:				new QueryRunner(Datasource ds);	3.编写sql	4.执行sql		query(..):执行r操作		update(...):执行cud操作

核心类或接口

QueryRunner:类名	作用:操作sql语句	构造器:		new QueryRunner(Datasource ds);	注意:		底层帮我们创建连接,创建语句执行者 ,释放资源.	常用方法:		query(..):		update(..):DbUtils:释放资源,控制事务 类	closeQuietly(conn):内部处理了异常	commitAndClose(Connection conn):提交事务并释放连接	....ResultSetHandler:封装结果集 接口		 ArrayHandler, ArrayListHandler, BeanHandler, BeanListHandler, ColumnListHandler, KeyedHandler, MapHandler, MapListHandler, ScalarHandler

带有List表示结果是集合,不带list表示结果是对象(相等于取集合的第一条数据)

(了解)ArrayHandler, 将查询结果的第一条记录封装成数组,返回 (了解)ArrayListHandler, 将查询结果的每一条记录封装成数组,将每一个数组放入list中返回 ★★BeanHandler, 将查询结果的第一条记录封装成指定的bean对象,返回 ★★BeanListHandler, 将查询结果的每一条记录封装成指定的bean对象,将每一个bean对象放入list中 返回. (了解)ColumnListHandler, 将查询结果的指定一列放入list中返回  (了解)MapHandler, 将查询结果的第一条记录封装成map,字段名作为key,值为value 返回 ★MapListHandler, 将查询结果的每一条记录封装map集合,将每一个map集合放入list中返回 ★ScalarHandler,针对于聚合函数 例如:count(*) 返回的是一个Long值

在这里插入图片描述

BeanHandler

QueryRunner qr = new QueryRunner(C3p0DataSourceUtils.getDataSource());String sql="select * from category";Category category = qr.query(sql, new BeanHandler<>(Category.class));System.out.println(category);

在这里插入图片描述

BeanListHandler

QueryRunner qr = new QueryRunner(C3p0DataSourceUtils.getDataSource());String sql="select * from category";List
list = qr.query(sql, new BeanListHandler<>(Category.class));for (Category category : list) {
System.out.println(category);}

在这里插入图片描述

ScalarHandler

QueryRunner qr = new QueryRunner(C3p0DataSourceUtils.getDataSource());String sql="select count(cid) from category";Object Object = qr.query(sql, new ScalarHandler());System.out.println(Object.getClass().getName());System.out.println(Object);Long count = (Long) qr.query(sql, new ScalarHandler());System.out.println(count);

在这里插入图片描述

ArrayHandler

QueryRunner qr = new QueryRunner(C3p0DataSourceUtils.getDataSource());String sql="select * from category";Object[] result = qr.query(sql, new ArrayHandler());System.out.println(Arrays.toString(result))

在这里插入图片描述

ArrayListHandler

QueryRunner qr = new QueryRunner(C3p0DataSourceUtils.getDataSource());String sql="select * from category";List
list = qr.query(sql, new ArrayListHandler());for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));}

在这里插入图片描述

MapHandler

QueryRunner qr = new QueryRunner(C3p0DataSourceUtils.getDataSource());String sql="select * from category";Map
map = qr.query(sql, new MapHandler());System.out.println(map);

在这里插入图片描述

MapListHandler

QueryRunner qr = new QueryRunner(C3p0DataSourceUtils.getDataSource());String sql="select * from category";List
> list = qr.query(sql, new MapListHandler());for (Map
map : list) {
System.out.println(map);}

在这里插入图片描述

ColumnListHandler

QueryRunner qr = new QueryRunner(C3p0DataSourceUtils.getDataSource());String sql="select * from category";//无参默认第一列的值List list = qr.query(sql, new ColumnListHandler("cname"));for (Object object : list) {
System.out.println(object); System.out.println(object.getClass().getName());}

在这里插入图片描述

KeyedHandler

QueryRunner qr = new QueryRunner(C3p0DataSourceUtils.getDataSource());String sql="select * from category";//无参默认第一列的值Map
> map = qr.query(sql, new KeyedHandler());System.out.println(map);Set
keySet = map.keySet();for (Object cid : keySet) {
//key:cid value:record System.out.println(cid+"---"+map.get(cid));}

在这里插入图片描述

源码

转载地址:http://rcdvi.baihongyu.com/

你可能感兴趣的文章
Objective-C 基础入门(一)
查看>>
Flutter Boost的router管理
查看>>
iOS开发支付集成之微信支付
查看>>
C++模板
查看>>
【C#】如何实现一个迭代器
查看>>
【C#】利用Conditional属性完成编译忽略
查看>>
VUe+webpack构建单页router应用(一)
查看>>
(python版)《剑指Offer》JZ01:二维数组中的查找
查看>>
Spring MVC中使用Thymeleaf模板引擎
查看>>
PHP 7 的五大新特性
查看>>
深入了解php底层机制
查看>>
PHP中的stdClass 【转】
查看>>
XHProf-php轻量级的性能分析工具
查看>>
OpenCV gpu模块样例注释:video_reader.cpp
查看>>
就在昨天,全球 42 亿 IPv4 地址宣告耗尽!
查看>>
Mysql复制表以及复制数据库
查看>>
Linux分区方案
查看>>
如何使用 systemd 中的定时器
查看>>
git命令速查表
查看>>
linux进程监控和自动重启的简单实现
查看>>