代码仓库+教程:
https://gitee.com/DerekAndroid/jdbcProject.git
1.案例
案例效果:
案例分析:
准备数据:
CREATE DATABASE day07;
CREATE TABLE products(
pid INT PRIMARY KEY AUTO_INCREMENT ,
pname VARCHAR(50),
price INT,
flag VARCHAR(2), #是否上架标记为:1表示上架、0表示下架
category_id VARCHAR(32)
);
#商品
INSERT INTO products(pname,price,flag,category_id) VALUES('联想',5000,'1','c001');
INSERT INTO products(pname,price,flag,category_id) VALUES('海尔',3000,'1','c001');
INSERT INTO products(pname,price,flag,category_id) VALUES('雷神',5000,'1','c001');
INSERT INTO products(pname,price,flag,category_id) VALUES('JACK JONES',800,'1','c002');
INSERT INTO products(pname,price,flag,category_id) VALUES('真维斯',200,'1','c002');
INSERT INTO products(pname,price,flag,category_id) VALUES('花花公子',440,'1','c002');
INSERT INTO products(pname,price,flag,category_id) VALUES('劲霸',2000,'1','c002');
INSERT INTO products(pname,price,flag,category_id) VALUES('香奈儿',800,'1','c003');
INSERT INTO products(pname,price,flag,category_id) VALUES('相宜本草',200,'1','c003');
代码:
1数据库连接工具
package com.itheima.utils;
import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
/**
* 在C3P0连接池中 遵循了javax.sql.DataSource接口的实现类:
* ComboPooledDataSource
*
*
* @author yingpeng
*
*/
public class C3P0Utils02 {
private static ComboPooledDataSource ds = new ComboPooledDataSource();
public static DataSource getDataSource(){
return ds;
}
//static代码块设置数据库连接四大要素
public static Connection getConnection() throws SQLException{
//获取连接,不要自己去DriverManager获取,而是从C3P0连接池获取
return ds.getConnection();
}
//关闭所有资源的统一代码
public static void closeAll(Connection conn,Statement st,ResultSet rs){
//负责关闭
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(st != null){
try {
st.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
package com.itheima.utils;
import java.sql.Connection;
import java.sql.SQLException;
/**
* 连接管理类:
* 主要负责获取连接,开启事务,提交事务,回滚事务
* @author yingpeng
*
*/
public class ConnectionManager {
//1.定义一个集合 ThreadLocal 对象来保存当前线程的连接
private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
//2.获取连接
public static Connection getConnection() throws SQLException{
//1.先从tl中获取连接
Connection conn = tl.get();
//2.判断conn是否为空
if(conn == null){
//说明 是service层第一次获取
conn = C3P0Utils02.getConnection();
tl.set(conn);
}
//如果不为空 说明 是dao层第二次以后获取
return conn;
}
//3.开启事务
public static void start() throws SQLException{
ConnectionManager.getConnection().setAutoCommit(false);
}
//4.提交事务
public static void commit() throws SQLException{
ConnectionManager.getConnection().commit();
}
//5.回滚事务
public static void rollback() throws SQLException{
ConnectionManager.getConnection().rollback();
}
//6.关闭连接
public static void close() throws SQLException{
ConnectionManager.getConnection().close();
}
}
2.商品Dao层
package com.itheima.dao;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import com.itheima.domain.Product;
import com.itheima.utils.C3P0Utils02;
import com.itheima.utils.ConnectionManager;
/**
* 商品Dao层
* @author yingpeng
*
*/
public class ProductDao {
//批量删除
public void deleteById(int id) throws SQLException{
//1.创建QueryRunner对象
QueryRunner qr = new QueryRunner();
//2调动qr的update
qr.update(ConnectionManager.getConnection(),"delete from products where pid = ?", id);
}
//根据id删除商品
public void deleteByOneId(int id) throws SQLException{
//1.创建QueryRunner对象
QueryRunner qr = new QueryRunner(C3P0Utils02.getDataSource());
//2调动qr的update
qr.update(ConnectionManager.getConnection(),"delete from products where pid = ?", id);
}
//插入商品
public void addProdcut(Product p) throws SQLException {
// TODO Auto-generated method stub
//1.创建QueryRunner对象
QueryRunner qr = new QueryRunner(C3P0Utils02.getDataSource());
//2.调用qr的update方法
Object[] params = {p.getPname(),p.getPrice(),"1","c002"};
qr.update("insert into products (pname,price,flag,category_id) values (?,?,?,?)", params);
}
public Product findById(int id) throws SQLException {
// TODO Auto-generated method stub
//1.创建QueryRunner对象
QueryRunner qr = new QueryRunner(C3P0Utils02.getDataSource());
//2.调用qr的query
Product p = qr.query("select * from products where pid = ?",new BeanHandler<Product>(Product.class), id);
return p;
}
public void updateProduct(Product p) throws SQLException {
// TODO Auto-generated method stub
//1.创建QueryRunner对象
QueryRunner qr = new QueryRunner(C3P0Utils02.getDataSource());
//2.修改
qr.update("update products set pname=?,price=? where pid=?",p.getPname(),p.getPrice(),p.getPid());
}
public List<Product> findAll() throws SQLException {
//1.创建QueryRunner对象
QueryRunner qr = new QueryRunner(C3P0Utils02.getDataSource());
//2.调用qr的query
List<Product> ps = qr.query("select * from products", new BeanListHandler<Product>(Product.class));
//返回
return ps;
}
}
3商品类
package com.itheima.domain;
/**
* 商品类
* @author yingpeng
*
*/
public class Product {
private int pid;
private String pname;
private int price;
private String flag;
private String category_id;
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getFlag() {
return flag;
}
public void setFlag(String flag) {
this.flag = flag;
}
public String getCategory_id() {
return category_id;
}
public void setCategory_id(String category_id) {
this.category_id = category_id;
}
@Override
public String toString() {
return "Product [pid=" + pid + ", pname=" + pname + ", price=" + price + ", flag=" + flag + ", category_id="
+ category_id + "]";
}
public Product() {
super();
// TODO Auto-generated constructor stub
}
public Product(int pid, String pname, int price, String flag, String category_id) {
super();
this.pid = pid;
this.pname = pname;
this.price = price;
this.flag = flag;
this.category_id = category_id;
}
public Product(String pname, int price) {
super();
this.pname = pname;
this.price = price;
}
}
4 商品的Service层
package com.itheima.service;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import com.itheima.dao.ProductDao;
import com.itheima.domain.Product;
import com.itheima.utils.C3P0Utils02;
import com.itheima.utils.ConnectionManager;
/**
* 商品的Service层
* @author yingpeng
*
*/
public class ProductService {
//批量删除商品
public void deleteAll(List<Integer> ids){
ProductDao dao = new ProductDao();
//循环调用dao.deleteById();
try {
//开启事务
ConnectionManager.start();
for (int id : ids) {
dao.deleteById(id);
System.out.println(1/0);
}
//提交事务
ConnectionManager.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
//回滚事务
try {
ConnectionManager.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}finally{
try {
ConnectionManager.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//根据id删除商品
public void deleteById(int id){
ProductDao dao = new ProductDao();
try {
dao.deleteByOneId(id);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//添加商品
public void addProduct(Product p) {
// TODO Auto-generated method stub
ProductDao dao = new ProductDao();
try {
dao.addProdcut(p);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Product findById(int id) {
// TODO Auto-generated method stub
ProductDao dao = new ProductDao();
Product p = null;
try {
p = dao.findById(id);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return p;
}
//修改商品
public void updateProduct(Product p) {
// TODO Auto-generated method stub
ProductDao dao = new ProductDao();
try {
dao.updateProduct(p);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public List<Product> findAll() {
// TODO Auto-generated method stub
ProductDao dao = new ProductDao();
List<Product> ps = null;
try {
ps = dao.findAll();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return ps;
}
}
5view-交互层
package com.itheima.view;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import com.itheima.domain.Product;
import com.itheima.service.ProductService;
public class ProductView {
public static void main(String[] args) throws SQLException {
//1.显示菜单
System.out.println("欢迎来到商品管理系统,请输入一下命令进行操作:");
while(true){
System.out.println("C:新增 U:修改 D:删除 DA:批量删除 FI:查询 FA:查询所有 Q:退出");
//2.获取用户的键盘输入
Scanner sc = new Scanner(System.in);
String userSelect = sc.nextLine();
//3.判断用户输入的到底是哪一个命令
switch (userSelect.toUpperCase()) {
case "C":
//新增商品
addProduct();
break;
case "U":
//修改商品
editProduct();
break;
case "D":
//根据ID删除商品
deleteProduct();
break;
case "DA":
//批量删除
deleteAllProducts();
break;
case "FI":
//根据id查询
findById();
break;
case "FA":
//查询所有商品
findAll();
break;
case "Q":
System.out.println("欢迎您下次再来哦~~么么哒");
System.exit(0);//结束正在运行的JVM
break;
default:
System.out.println("您傻吗?你输得啥玩意...");
break;
}
}
}
private static void findAll() {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
System.out.println("您选择了查看所有商品功能!");
ProductService service = new ProductService();
List<Product> ps = service.findAll();
//判断有没有商品
if(ps.isEmpty()){
System.out.println("数据库中暂时没有数据,亲添加后再查看哟~~~");
}else{
for (Product p : ps) {
System.out.println(p);
}
System.out.println("所有商品显示完毕!");
}
}
private static void findById() {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
System.out.println("您选择了查询商品功能!");
//1.请输入要修改的商品的编号
System.out.println("请输入要查询的商品的编号:");
int id = Integer.parseInt(sc.nextLine());
//2.调用service的查询方法
ProductService service = new ProductService();
Product p = service.findById(id);
//3.展示
if(p==null){
System.out.println("查询的商品不存在..请确认后输入...");
}else{
System.out.println("您查询的商品是:"+p);
System.out.println("显示商品成功!");
}
}
private static void deleteAllProducts() {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
ProductService service = new ProductService();
System.out.println("您选择了批量删除商品功能!");
//1.先创建一个集合 保存要删除的商品的id
List<Integer> ids = new ArrayList<Integer>();
//2.请输入您要删除的商品的编号(-1表示结束)
while(true){
System.out.println("请输入您要删除的商品的编号(-1表示结束):");
int deleteId = Integer.parseInt(sc.nextLine());
if(deleteId == -1){
break;
}
//3.判断有没有此id的商品
Product p = service.findById(deleteId);
if(p!=null){
//如果有此商品
ids.add(deleteId);
System.out.println("已经标记此商品..");
}else{
// 如果没有此商品
System.out.println("此商品不存在,请重新输入");
}
}
//5.调用service的方法
if(ids.isEmpty()){
System.out.println("批量删除操作已经取消...");
}else{
//友情提示
System.out.println("您一共标记了"+ids.size()+"个要删除的商品");
System.out.println("您确定都要删除吗? y/n");
String isOrNot = sc.nextLine();
if("y".equals(isOrNot)){
service.deleteAll(ids);
System.out.println("批量删除"+ids.size()+"个商品成功!");
}else{
System.out.println("取消操作..");
}
//....
}
}
private static void deleteProduct() {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
System.out.println("您选择了删除商品功能!");
//1.请输入要删除的商品编号
System.out.println("请输入要删除的商品编号:");
int id = Integer.parseInt(sc.nextLine());
//2.判断有没有此id的商品
ProductService service = new ProductService();
Product p = service.findById(id);
if(p==null){
//如果没有 告诉用户 没有此商品
System.out.println("查无此商品....");
}else{
//如果有 先告诉用户 此id商品的具体信息
System.out.println("您要删除的商品信息如下:");
System.out.println(p);
System.out.println("您确认要删除吗? y/n");
String isOrNot = sc.nextLine();
if("y".equals(isOrNot)){
service.deleteById(id);
System.out.println("删除商品成功!");
}else{
System.out.println("操作取消..");
}
}
//....
}
private static void editProduct() {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
System.out.println("您选择了修改商品功能!");
//1.请输入要修改的商品的编号
System.out.println("请输入要修改的商品的编号:");
int id = Integer.parseInt(sc.nextLine());
//2.查询数据库,如果有告诉用户选择的商品是什么信息
// 如果没有要提示用户商品不存在
ProductService service = new ProductService();
Product p = service.findById(id);
if(p==null){
System.out.println("您要修改的商品编号"+id+",该商品不存在");
}else{
//说明该商品存在
System.out.println("您要修改的商品信息如下:");
System.out.println(p);
//请输入商品的新的名字
System.out.println("请输入商品的新的名字:");
String newName = sc.nextLine();
//请输入商品的新的价格
System.out.println("请输入商品的新的价格:");
int newPrice = Integer.parseInt(sc.nextLine());
//设置新的名字和价格
p.setPname(newName);
p.setPrice(newPrice);
//调用servicee层
service.updateProduct(p);
System.out.println("修改商品成功!");
}
//....
}
//添加商品
private static void addProduct() {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
System.out.println("您选择了新增商品功能!");
//1.请输入新的商品名字
System.out.println("请输入新的商品名字:");
String name = sc.nextLine();
//2.请输入新的商品价格
System.out.println("请输入新的商品价格:");
int price = Integer.parseInt(sc.nextLine());
//3.封装成商品对象
Product p = new Product(name,price);
//4.调用service层的添加商品方法
ProductService service = new ProductService();
service.addProduct(p);
System.out.println("添加商品成功!");
}
}
2.总结
/**
* 一.SQL语句
*
* 1.分类:
* DDL:数据库定义语言,主要对数据库,表,列,进行增删改查
* a.创建数据库
* create database 数据名 [charset 字符集名];
* ***b.创建表
* create table 表名(
* 字段名 数据类型(长度) [约束],
* 字段名 数据类型(长度) [约束]
* );
* SQL中的数据类型:
* 整数:int
* 小数:double
* 字符串:varchar(长度),建议 用2的整数倍
* 日期:date 格式: 'YYYY-MM-DD'
* SQL中的约束:
* a.主键约束:primary key, 唯一且非空
* b.自动增长列约束:auto_increment,必须是数值类型,而且一般我们会给主键加上自增长约束
* c.唯一约束:Unique, 多个记录的该列的值不能相同
* d.非空约束: Not Null,不能为null
* e.默认约束: default 默认值,为某一个字段设置默认值
* f.外键约束: foreign key 多表查询
* DCL:数据库控制语言
* 了解(Oracle时说讲述)
* **DML:数据库操作语言 : 对数据库中表中的数据进行增删改
* 增:
* insert into 表名 (字段1,字段2...) values (值1,值2,值3);
* 注意事项:
* 1.字段和值要一一对应
* 2.如果是全字段,表名后面可以不写,但是values必须写上全部字段的值
* 3.值的写法: 除了数值类型的值,其他值必须用''或者""括起来
* 删:
* delete from 表名 [where条件];
* trancate table 表名:
* 以上两种删除表中数据的区别:
* delete from 表名:只会删除记录,不会重置自动增长值,下次插入数据时,接着增加自动增长值
* trancate table 表名: 摧毁表,再重建,即会删除所有记录,也会重置自动增长值(重置为1)
* 改:
* update 表名 set 字段=值,字段=值 [where 条件]
*
* **DQL:数据库查询语言: 对数据库中表中的数据进行花式查询
* 单表查询:
* a.条件查询:
* select * from 表名 where 条件:
* 条件:
* 大小: > < >= <= = != <>
* 区间:
* between .. and .. 注意:只能判断数值和日期
* 比如: between '1990-05-30' and '2000-10-10'
* age in (10,20)===> age=10 or age = 20;
* 为空:
* is null;
* is not null
* 模糊查询:
* like '表达式', 符号_表示任意一个字符 符号%表示任意个任意字符
* b.排序查询
* select * from 表名 order by 字段 ASC(默认,升序)|DESC(降序);
* c.聚合查询:
* select count(*)|max(数值字段)|min(数值字段)|sum(数值字段)|avg(数值字段) from 表名
* 注意事项:聚合函数查询出来的只有一个值,会忽略null值
* d.分组查询:
* select 分组字段,聚合函数 from 表名 group by 某个字段;
* 在分组查询中,要查询的字段必须是分组字段,也可以是聚合函数
* e.分页查询
* select * from 表名 limit 第几条记录,要查询第三条记录
* 比如: 我要查询第m页,每页有n条记录
* 第一页: limit (1-1)*n,n;
* 第二页: limit (2-1)*n,n;
* 第m页: limit (m-1)*n;n
* f.去重复查询
* select distinct 字段 from 表名;
* 查询出所有该字段,并且去掉重复值
* 多表:
* 1.为什么使用多表? 回顾第二天视频
* 2.表与表之间的关系:
* 一对多:商品分类 和 商品信息, 学生和考试成绩,省和市
* 必须两张表,一张主表,一张从表,
* 原则:从表必须有一个外键,这个外键 引用 主表的主键
* 如何给从表添加外键约束
* Alter table 从表 add constraint 主表_从表_fk
* foreign key (从表外键名) references 主表 (主键名);
* 多对多: 学生和课程, 演员和角色 , 老师和学生
* 必须有三张表,两张正常表,一张中间表
* 原则: 中间表,至少有两个字段,分别是外键,引用两张的主键
* Alter table 中间表 add constraint _fk
* foreign key (第一个外键名) references 第一张表 (主键名);
* Alter table 中间表 add constraint _fk
* foreign key (第二个外键名) references 第二张表 (主键名);
* 一对一: QQ号码,和QQ详细信息
* 可以用一张表示
* 多表查询语句:
* 1.交叉查询: 本身有错误的 ,实际上是一个叫做笛卡尔积的东西
* select * from 表1,表2;
* 2.内连接:在交叉连接的基础上 添加条件(一般是主表.主键=从表.外键)
* 隐式内连接: 不写inner join 后面的条件用where判断
* select * from 表A,表B where 表A.主键=表B.外键
* 显示内连接: 写上inner join 后面的条件用on判断
* select * from 表A inner join 表B on 表A.主键=表B.外键
*
* 3.外链接:关键字 outer join
* 左外连接: left outer join,以左表作为,如果右表中没有和左表匹配的那条记录
* 那么也会将这条记录查询出来,没有值的地方填充null;
* 右外连接: right outer join
* 以右表作为,如果左表中没有和右表匹配的那条记录
* 那么也会将这条记录查询出来,没有值的地方填充null;
* 4.子查询:
* 一条select语句的结果,作为另外一条select语句的一部分
* 比如: 商品分类表和 商品详情表为例
* 查询 商品名字为 "霸王" 的商品的分类名
* select cname from 商品分类表 where 分类id =
* (select 商品分类id from 商品详情表 where 商品名="霸王");
*
*
* 二.JDBC:
* 1.JDBC原生API
* 步骤:
* 1.注册驱动:
* Class.forName("com.mysql.jdbc.Driver");
* 2.获取连接:
* Connection conn =
* DriverManager.getConnection("jdbc:mysql://ip:3306/数据库名","用户名","密码");
* 3.获取sql执行对象
* Statement st = conn.createStatement();
* 4.执行sql语句,并且获取结果集(只有查询有结果集,其他都是int返回值)
* int rows = st.excuteUpdate(sql);
* ResultSet rs = st.excuteQuery(sql);
* 5.处理结果集
* 结果集中的两个方法
* next();//判断有没有下一条记录
* getXxx(int colid),getXxx(String colname);
* 其中Xxx可以是int,String,Double,Object
* 6.释放资源
* conn.close(),st.close(),rs.close();
* 2.JDBCUtils工具类
* //四个要素
* private static String driverName = "com.mysql.jdbc.Driver";
* private static String url = "jdbc:mysql://localhost:3306/day04";
* private static String username = "root";
* private static String password = "123";
* //static
* static{
* Class.forName(driverName);
* }
* //获取连接:
* public static Connection getConnection(){
* DriverManager.getConnecton(url,username,password);
* }
* //关闭资源
* public static void closeAll(Connection conn,Statement st,ResultSet rs){..}
*
* 3.连接池: 是一个集合,预先获取一些连接对象,保存到集合中以便下次使用
* JDBC中规定:所有的连接池对象,必须实现 DataSource接口
* DBCP连接池:
* public class BasicDataSource implements DataSource;
* ==================================================
* DBCPUtils工具类: 不使用配置文件
* //四个要素
* private static String driverName = "com.mysql.jdbc.Driver";
* private static String url = "jdbc:mysql://localhost:3306/day04";
* private static String username = "root";
* private static String password = "123";
* //连接池
* private static BasicDataSource ds = new BasicDataSource();
* static{
* //设置四大要素
* ds.setDriverClassName(driverName);
* ds.setUrl(url);
* ds.setUsername(username);
* ds.setPassword(password);
* }
* public static Connection getConnection(){
* ds.getConnection();
* }
* //关闭资源
* public static void closeAll(Connection conn,Statement st,ResultSet rs){..}
* ==================================================
* DBCPUtils工具类: 使用配置文件(推荐使用Properties配置文件)
* //配置文件中写四个要素
* driverName=com.mysql.jdbc.Driver
* url=jdbc:mysql://localhost:3306/day04
* username=root
* password=123
* //连接池
* private static DataSource ds;
* static{
* Properties ps = new Properties();
* ps.load(new FIleInputStream("dbcpconfig.properties"))
* //用到一个生产BasicDataSource的工厂类
* ds = BasicDataSourceFactory.createDataSource(ps);
* //设置四大要素
* //ds.setDriverClassName(ps.get("driverName"));
* //ds.setUrl(ps.get("url"));
* //ds.setUsername(ps.get("username"));
* //ds.setPassword(ps.get("password"));
* }
* public static Connection getConnection(){
* ds.getConnection();
* }
* //关闭资源
* public static void closeAll(Connection conn,Statement st,ResultSet rs){..}
* =============================================
* C3P0连接池:不使用配置文件
* //四个要素
* private static String driverName = "com.mysql.jdbc.Driver";
* private static String url = "jdbc:mysql://localhost:3306/day04";
* private static String username = "root";
* private static String password = "123";
* //连接池对象
* ComboPooledDataSource ds = new ComboPooledDataSource();
* //静态代码块
* static{
* ds.setDriverClass(driverName);
* ds.setJdbcurl(url);
* ds.setUser(username);
* ds.setPassword(password);
* }
* public static Connection getConnection(){
* ds.getConnection();
* }
* //关闭资源
* public static void closeAll(Connection conn,Statement st,ResultSet rs){..}
* =============================================
* C3P0连接池:使用配置文件
* //四个要素写到XMl文件中
* <default-config><!-- 默认配置 -->
* <property name="driverClass">com.mysql.jdbc.Driver</property>
* <property name="jdbcUrl">jdbc:mysql://localhost:3306/day04</property>
* <property name="user">root</property>
* <property name="password">123</property>
* <property name="initialPoolSize">10</property>
* </default-config>
* //连接池对象
* //在创建ComboPooledDataSource对象时,底层会去自动读取并解析XML
* //但是这个XML必须Src根目录下,文件名字必须叫做c3p0-config.xml
* ComboPooledDataSource ds = new ComboPooledDataSource();
*
* public static Connection getConnection(){
* ds.getConnection();
* }
* //关闭资源
* public static void closeAll(Connection conn,Statement st,ResultSet rs){..}
* 第三方框架: DBUtils工具类
* DBUtils: 主要是关系资源
* public static void closeQuietly(Connection conn,Statement st,ResultSet rs);
*
* QueryRunner:SQL语句执行对象
* 不支持事务
* 构造:QueryRunner(DataSource ds)
* 1.int update(String sql,Object... params)
* 2. query(String sql,ResultSetHandler接口 rsh, Object...params)
* 支持事务
* 构造:QueryRunner()
* 1.int update(Connection conn,String sql,Object... params)
* 2. query(Connection conn,String sql,ResultSetHandler接口 rsh, Object...params)
* ResultSetHandler接口 的实现类
* Object[] ArrayHandler:
* 把结果集中的第一条记录,封装到一个数组中,数组中的每个元素都是字段的值
* List<Object[]> ArrayListHandler:
* 把结果集中的每一条记录,分别封装到一个数组中,数组中的每个元素都是字段的值
* 把所有数组再封装到List集合中,并返回这个集合
* JavaBean BeanHandler:
* 把结果集中的第一条记录,封装到一个JavaBean对象中,并返回这个对象
* List<JavaBean> BeanListHandler:
* 把结果集中的每一条记录,分别封装到一个JavaBean对象中,
* 把这些对象保存到集合中,并返回这个集合
* Map<String,Object> MapHandler:
* List<Map<String,Object>> MapListHandler
* List<Object> ColumnHandler:
* Object Scalarhandler:
* 事务:
* 开始事务:
* try{
* conn.setAutoCommit(false);
* insert(..)
* insert(..)
* insert(..)
* conn.commit();
* }catch(Exception ex){
* conn.rollback();
* }
* ThreadLocal:底层是一个Map<Thread,Object>
* set(Object 值);==> map.set(当前线程对象,值)
* get();===>map.get(当前线程对象)
* remove();====>map.remove(当前线程对象)
*
*/