-
DDL 定义
-
DML 操作
-
DQL 查询
-
DCL 控制
基本命令
数据库
CREATE DATABASE [IF NOT EXISTS] test01
DROP DATABASE [IF EXISTS] test01
USE `test01`
SHOW DATABASES
SHOW CREATE DATABASE school
SHOW CREATE TABLE student
DESC student
数据类型
数值
-
tinyint 1个字节
-
smallint 2个字节
-
mediumint 3个字节
-
int 4个字节
-
bigint 8个字节
-
float 4个字节
-
double 8个字节
-
decimal 字符串形式的浮点数 金融上使用 (精度问题)
字符串
-
char 0-255
-
varchar 可变字符串 0-65535 常用变量
-
tinytext 2^8-1
-
text 2^16-1 保存大文本
时间
-
date YYYY-MM-DD
-
time HH:mm:ss
-
datetime YYYY-MM-DD HH:mm:ss
-
timestamp 时间戳 1970.1.1到现在的毫秒数
-
year 年份
null
-
没有值
-
不要使用NULL进行运算, 结果为NULL
字段属性
-
unsigned 无符号整数 声明该列不能为负数
-
zerofill 0填充的 不足位数, 使用0填充 int(3) 5 ----> 005
-
自增 必须是整数 可以自定义起始值
-
not null 非空
-
默认
必要字段
id 主键
version 乐观锁
id_delete 伪删除
create_time创建时间
update_time修改时间
表
创建表
CREATE TABLE IF NOT EXISTS `student` (
`id` INT(4) NOT NULL AUTO_INCREMENT COMMENT '学号',
`name` VARCHAR(30) NOT NULL DEFAULT '匿名' COMMENT '姓名',
`pwd` VARCHAR(20) NOT NULL DEFAULT '123456' COMMENT '密码',
`sex` VARCHAR(2) NOT NULL DEFAULT '女' COMMENT '性别',
`birthday` DATETIME DEFAULT NULL COMMENT '出生日期',
`address` VARCHAR(100) DEFAULT NULL COMMENT '地址',
`email` VARCHAR(50) DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY(`id`)
)ENGINE = INNODB DEFAULT CHARSET=utf8
MyISAM和INNODB区别
MYISAM | INNODB | |
---|---|---|
事务支持 | 不支持 | 支持 |
数据行锁定 | 不支持 | 支持 |
外键约束 | 不支持 | 支持 |
全文索引 | 支持 | 不支持 |
表空间大小 | 较小 | 较大,约2倍 |
-
MYISAM 空间小, 速度快
-
INNODB 安全性高, 事务的处理, 多表多用户操作
-
物理文件的不同
数据库编码
-
默认不支持中文(Latin)
修改和删除
ALTER TABLE teacher RENAME AS teacher1 --新表名
ALTER TABLE teacher1 ADD age INT(11) --增加字段
ALTER TABLE teacher1 MODIFY age VARCHAR(11) --修改字段
ALTER TABLE teacher1 CHANGE age age1 INT(1) --字段重命名
ALTER TABLE teacher1 DROP age1 --删除字段
DROP TABLE IF EXISTS teacher1 --删除表
外键(了解)
-
方式一: 创建表的时候 添加外键约束
key `FK_gradeid` (`gradeid`),
constraint `FK_gradeid` foreign key (`gradeid`) references `grade` (`gradeid`)
-
方式二: 通过修改表
alter table `student`
add constraint `FK_gradeid` foreign key (`gradeid`) references `grade` (`gradeid`)
DML语言
insert into `student` values ("jack", 1, "男") --省略需要插入所有的值
insert into `student` (name, age) values ("jack", 1) --插入指定字段
insert into `student` (name, age) values ("jack", 1), ("mark",2) --多条插入
update `student` set `name` = '张三' where id = 1
update `student` set `name` = '张三' --没有条件修改全部
update `student` set `name` = '张三', sex = '男' where id = 1 --修改多个字段
-
where条件
=, <>或!=, >, <, <=, >=, between...and, and, orupdate
student
setname
= '张三' where id = 1 and sex = '男'
delete from `student` where id = 1 --删除指定数据 delete from `student` -- 全部删除了
--清空数据库 表的结构和索引约束不会变 truncate `student`
-
delete和 truncate的区别
相同点: 都能删除数据, 都不会删除表结构 不同: truncate 重新设置 自增列 计数器会归零 truncate: 不会影响事务delete删除的问题 重启数据库 现象 innodb 自增列会从1 开始 (存在内存中, 断电即失) myisam 继续从上一个自增量开始 (存在文件中, 不会丢失)</pre>
DQL查询数据
select * from `student` --查询全部select
name
,age
fromstudent
--查询指定select
name
as 姓名,age
as 年龄 fromstudent
as s --查询并别名select concat('姓名: ',name) as 新名字 from student --拼接函数
去重
select distinct id from result --去除相同id的数据其他
select version() --查询系统版本 select 100*3-1 as 计算结果 -- 用于计算 select @@auto_increment_increment --查询自增的步长 select `id`, `result` + 1 as '提分后' from result --所有result都增加1where条件子
逻辑运算符
运算符 | 语法 | 描述 |
---|---|---|
and && | a and b a && b | 两边都为真即为真 |
or || | a or b a || b | 一边为真即为真 |
Not ! | not a !a | 真即假, 假即真 |
模糊查询: 比较运算符
运算符 | 语法 | 描述 |
---|---|---|
is null | a is null | 如果操作符为null,结果为真 |
is not null | a is not null | 如果操作符不为null, 结果为真 |
between | a between b and c | 若a在b和c之间, 则结果为真 |
like | a like b | SQL匹配, 如果a匹配b, 则结果为真 |
in | a in (a1, a2, a3) | 假设a在a1,a2...中其中的一个值 ,即为真 |
-
like结合
% 0 到任意个字符 _ 一个字符select
id
,name
fronstudent
where name like '刘_'select
id
,name
fronstudent
where name like '刘%'select
id
,name
fronstudent
where name like '%刘%'
-
in结合 in 里的是一个具体的值
select `id`, `name` fron `student` where in (1001, 1002, 1003)
-
null not null
select `id`, `name` from `student` where address = '' or address is nullselect
id
,name
fromstudent
where birthdey is not null
联表查询
-
left join
-
inner join
-
right join
--内联 有一个匹配就返回 select s.id, name, subId, subResult from student as s inner join result as r where s.id = r.id--右联 右边有的返回, 左表没有的为ulll
select s.id, name, subId, subResult
from student s --as可以省略
right join result r
on s.id = r.id--左联 左边有的返回, 右表没有的为ulll
select s.id, name, subId, subResult
from student s --as可以省略
left join result r
on s.id = r.id-- 查询什么数据
-- 需要什么表
-- 选择交叉查询
-- 表格多了, 两张两张来select id, name, subName, subResult
from student s
right join result r
on r.id = s.id
inner join subject sub
on r.subId = sub.subId
自连接
-
自己和自己连接 将自己拆为两张一样的表
categoryid | pid | categoryName |
---|---|---|
7 | 5 | ps技术 |
6 | 3 | web开发 |
2 | 1 | 信息技术 |
8 | 2 | 办公技术 |
4 | 3 | 数据库 |
5 | 1 | 美术设计 |
3 | 1 | 软件开发 |
select `categoryName` as '父栏目', `categoryName' as 子栏目 from `category` as a, `category` as b where a.`categoryid` = b.`pid`
分页和排序
-
limit/order by
select * from student order by desc --降序select * from student order by asc --升序
-- 解决数据库压力
--每页显示5条select * from student limit 0,5 --参数: 起始位置, 每页条数 第一页, 每页5条
select * from student limit 5,5 --第二页 每页5条-- (当前页-1) * 页面大小, 页面大小
-- 总页数: 数据总数/页面大小
子查询和嵌套查询
-
where中嵌套一个子查询语句
-- 表连接 select id, subId, subResult from result r inner join subject sub on r.subId = sub.subId where subName = '数据库结构' order by subResult desc-- 子查询
select id, subId, subResult
from result
where subId = (
select subId from subject where subName = '数据库结构'
)
常用函数
select abs(-8) select ceiling(9.4) --向上取整 select floor(9.4) --向下取整 select rand() --返回[0-1)随机数 select sign(0) --返回一个数的符号 正数: 1, 负数:-1select char_length('字符串') --字符串长度
select concat('我','唉','你') -- 拼接字符串
select insert('我爱编程',1,2,'超级可爱') --从某个位置开始替换指定长度 超级可爱编程
select lower('cHx') --转小写
select upper('cHx') --转大写
select instr('chaca','h') --返回第一次出现的位置 2
select replace('坚持就会成功','坚持','努力') -- 替换出现的指定字符串
select substr("坚持就会成功",4,1) --从指定位置截取指定长度
select reverse('坚持就会成功') --反转-- 替换 周 为 邹
select replace(name,'周','邹') from student
where name like '周%'-- 时间和日期
select current_date() -- 当前日期
select curdate() -- 当前日期
select now() -- 当前时间
select localtime -- 本地时间
select sysdate -- 系统时间-- 年 月 日 时 分 秒
select year(now())
select month(now())
select day(now())
select hour(now())
select minute(now())
select second(now())-- 系统
select system_user() --当前用户
select user() --当前用户
select version() --版本
聚合函数
-- 统计表数 select count(name) from student --忽略所有的null select count(*) from student --不会忽略所有的null select count(1) from student --不会忽略所有的null 忽略列数-- 列名为主键 count(主键) 优于 count(1)
-- 列名不为主键 count(1) 优于 count(name)-- 表多列且没有主键 count(1) 优于 count()
-- 如果有主键count(主键) 最优
-- 如果只有一个字段 count() 最优select sum(result) as 总和 from result
select avg(result) as 平均分 from result
select max(result) as 最高分 from result
select min(result) as 最低分 from result
分组过滤
select subName, avg(result) as 平均分, max(result) as 最高分, min(result) as 最低分 from result r inner join `subject`sub on r.subId = sub.subId group by r.subId having 平均分
数据库级别的MD5加密
-
主要增强算法复杂度和不可逆性
-
不可逆, 常见的MD5是一致的
create table `testmd5`( `id` int(4) not null, `name` varchar(20) not null, `pwd` varchar(50) not null, primary key (`id`) )engine=innodb default charset=utf8insert into
testmd5
values(1,'zhangsan','123456'),(2,'lisi','123456'),(3,'wangwu','123456');update testmd5 set pwd = MD5(pwd) where id = 1
update testmd5 set pwd = MD5(pwd)insert into
testmd5
values(5,'小明',md5('123456'))select * from testmd5 where
name
= '小明' and pwd = md5('123456');
顺序
select xxx join on where group by having order by limit
事务
-
要么都成功, 要么都失败
ACID原则
-
原子性: 要么都成功, 要么都不成功 (转账)
-
一致性: 保证事务操作前, 操作后的状态一致 (转账总额一致)
-
隔离性: 多个用户同时操作, 互不影响
-
持久性: 事务提交后才, 持久化数据库 (断电, 数据恢复原状) 事务提交不可逆
事务隔离级别(隔离导致的问题)
脏读
-
指一个事务读取了另外一个事务未提交的数据
A: 800 C: 1000 B: 200A 转 200 给 B 在这个过程中 左边的事务还没有提交的时候
A - 200 = 600 C 转 100 给 B
B + 200 = 400 这里拿到的B为 200 + 100 = 300
一边是400, 一边300 就出现脏读
不可重复读
-
在一个事务内读取表中的某一行数据 多次读取结果不同.
第一次读取的时候 A: 100 B: 200 C: 500在这个过程中 有人给B转了300 并且事务提交了
第二次读取的时候
A: 100
B: 500
C: 500
虚读(幻读)
-
是指在一个事务内读取到了别的事务插入的数据, 导致前后读取不一致
-
(一般是行影响, 多了一行)
第一次读 A: 100 B: 500 C: 500第二次读
A: 100
B: 500
C: 500
D: 500
事务
-
mysql 是默认开启事务自动提交
-
set autocommit = 0 关闭自动提交事务 1 为开启
-- 关闭事务自动提交 set autocommit = 0-- 开启事务 一组事务的过程
start transaction-- 处理业务
-- 提交 持久化 (成功)
commit-- 回滚 (失败)
rollback-- 事务结束
set autocommit = 1 -- 开启事务自动提交
-- 了解 savepoint 保存点名 -- 设置一个事务的保存点 rollback to savepoint 保存点名 -- 回滚到保存点 release savepoint 保存的名 -- 撤销保存点
索引
-
根据索引可以让我们更快的获取数据
-
数据结构
-
大数据量的时候, 定位, 减少遍历
索引分类
-
主键索引(primary key)
-
唯一的表示, 主键不可重复, 只能有一个列作为主键
-
-
唯一索引(unique key)
-
避免重复的列出现, 唯一索引可以重复, 多个列都可以被标记为位移索引
-
-
常规索引(key/index)
-
默认的
-
-
全文索引(fulltext)
-
在特定的数据库引擎下才有: myisam
-
宽恕定位数据
-
-- 查看所有索引信息 show index from `student`-- 添加一个全文索引
alter table school.student add fulltextindexname
(name
)
索引原则
-
索引不是越多越好
-
不要对经常变动的数据添加索引
-
小数据量的表不需要加索引
-
索引一般加在常用来查询的字段上
权限管理和备份
用户管理
-- 用户表 mysql.user-- 操作表 权限
-- 创建用户
create user chen identfied by '123456'-- 修改当前用户密码
set password = password('123456')--修改制指定用户
set password for chen = password('123456')-- 重命名
rename user chen to chen2-- 用户授权 库.表
grant all privileges on ".* to chen-- 查看权限
show grants for chen2
show grants for root@localhost-- 撤销权限 库 谁
remove all privileges on . to chen-- 删除用户
drop user chen
备份
-
保存数据
-
数据转移
-- mysqldump -h 主机 -u 用户名 -p 密码 数据库 表名 > 物理磁盘位置/文件名 mysqldump -hlocalhost -uroot -p123456 school student >D:/a.sql-- 导入 登录情况下 切换到指定数据库
source D:/a.sql-- 导入 未登录
mysql -u用户名 -p密码 库名 < 备份文件
规范设计数据库
糟糕的数据库
-
数据冗余, 浪费空间
-
数据库插入数据和删除都会麻烦, 异常(避免使用物理外键)
-
程序的性能差
良好的数据库
-
节省能查空间
-
保存数据库完整性
-
方便我们开发系统
设计数据库
-
分析需求: 分析业务和需求处理的数据库的需求
-
概要设计: 设计关系图E-R图
步骤(个人博客)
-
收集信息, 分析需求
-
用户表 (用户登录注销, 用户的个人信息, 写博客, 创建分类)
-
分类表 (文章分类, 谁创建的)
-
评论表
-
文章表: (文章的信息)
-
友链表 (友链信息)
-
自定义表 (系统信息, 某个关键的字, 或者一些主字段) key value
-
-
标识实体:(把需求落地到每一张表)
-- 用户表 user id username password sex age sign avatar open_id 签名 其他登录(微信id)-- 分类表 category
id category_name create_user_id-- 文章表 blog
id title author_id category_id context create_time update_time love
喜欢/收藏-- 评论表 comment
id blog_id user_id content create_time user_id_parent
回复的人的id-- 友链表 links
id links href sort
网站名称 网站链接 网站排序-- 粉丝表 user_follow
id user_id follow_id
被关注的id 关注人id
-
标识实体之间的关系
-- 写博客 user -> blog-- 创建分类
user -> category-- 关注
user -> user-- 友链
links-- 评论
user -> user -> blog
三大范式
为什么需要数据规范
-
信息复杂
-
更新异常
-
插入异常
-
无法正常显示信息
-
-
删除异常
-
丢失有效的信息
-
三大范式
-
第一范式
-
原子性: 保证每一列不可再分
-
-
第二范式
-
前提: 遵循第一范式
-
每张表值描述一件事情(产品表里不能出现订单表的信息)
-
-
第三范式
-
前提: 遵循第一第二范式
-
需要确保数据表的每一列数据都和主键直接相关, 而不是间接相关
-
(学生表只需要存老师id即可)
-
规范性和性能问题
-
关联查询的表不得超过三张表
-
考虑商业化的问题和目标
-
-
在规范性能的问题上, 需要适当的考虑一下 规范性
-
故意给某些表增加一些冗余的字段(从多表变为单表查询)
-
故意增加一些计算列 (从大数据量降低为小数据量的查询)
JDBC
数据库驱动(程序和数据库连接)
-
mysql驱动
-
oracle驱动
JDBC
-
简化开发人员对数据库操作 jjava的dbc规范
-
掌握jdbc接口的操作即可
环境
-
java.sql
-
javax.sql
-
mysql驱动
程序
-
添加lib jdbc驱动
-
测试
public static void main(String[] args) throws ClassNotFoundException, SQLException{ //1. 加载驱动 Class.forName("com.mysql.jdbc.Driver");//2. 用户信息和url String url = "jdbc:mysql://127.0.0.1:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false&zeroDateTimeBehavior=convertToNull&&serverTimezone=Asia/Shanghai"; String username = "root"; String password = "123455"; //3. 连接成功, 数据库对象 Connection: 代表数据库 可以进行提交, 回滚.. Connection connection = DriverManger.getConnection(url, username, password); //4. 执行SQL的对象Statement Statement statement = connection.createStatement(); //5. 执行SQL的对象 去 执行SQL, 可能存在结果, 查询返回结果 String sql = "select * from users"; ResultSet resultSet = statement.executeQuery(sql);//结果集:封装了查询结果 while(resultSet.next()){ System.out.println("id="+resultSet.getObject("id")); System.out.println("name="+resultSet.getObject("name")); System.out.println("pwd="+resultSet.getObject("pwd")); } //6. 释放连接 resultSet.close(); statement.close(); connection.close();
}
statement.executeQuery();//查询操作 返回ResultSet statement.execute();//执行任何SQL statement.executeUpdate();//更新, 插入, 删除, 返回受影响的行数
ResultSet: 结果集:封装了查询结果 //如果知道类型就指定具体类型 resultSet.getString(); resultSet.getInt(); resultSet.getFloat(); resultSet.getDate(); resultSet.getObject();
Statement
-
用于向数据库发送sql语句
Statement statement = connection.createStatement(); String sql = "insert into user(...) values(...)"; int row = statement.executeUpdate(sql); if(row>0){ System.out.println("插入成功!"); }
Statement statement = connection.createStatement(); String sql = "delete from user where id=1"; int row = statement.executeUpdate(sql); if(row>0){ System.out.println("删除成功!"); }
Statement statement = connection.createStatement(); String sql = "update user set name = '' where name = '' "; int row = statement.executeUpdate(sql); if(row>0){ System.out.println("修改成功!"); }
Statement statement = connection.createStatement(); String sql = "select * from user"; ResultSet resultSet = statement.executeQuery(sql); while(resultSet.next()){ //... }
封装工具类
-
db.properties
driver=com.mysql.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false&zeroDateTimeBehavior=convertToNull&&serverTimezone=Asia/Shanghai username=root password=123456
-
JdbcUtils
public class JdbcUtils{ private static String driver = null; private static String url = null; private static String username = null; private static String password = null;static { try{ InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties"); Properties properties = new Properties(); properties.load(in); driver = properties.getProperty("driver"); url = properties.getProperty("url"); username = properties.getProperty("username"); password = properties.getProperty("password"); //1. 驱动只用加载一次 Class.forName(driver); } catch (Exception e){ e.printStackTrace(); } //获取连接 public static Connection getConnection() throws SQLException{ return DriverManger.getConnection(url, username, password); } //释放连接资源 public static void release(Connection conn, Statement st, ResultSet rs){ if(rs != null){ try{ rs.close(); } catch (SQLException e){ e.printStackTrace(); } } if(st != null){ try{ st.close(); } catch (SQLException e){ e.printStackTrace(); } } if(conn != null){ try{ conn.close(); } catch (SQLException e){ e.printStackTrace(); } } } }
}
public static void main(String[] args) { Connection conn = null; Statement st = null; ResultSet rs = null; try{ conn = JdbcUtils.getConnection(); st = conn.createStatement(); String sql = "insert into user(id,`name`,`password`) values(1,'chen','123456')"; int row = st.executeUpdate(sql); if(row > 0){ System.out.println("插入成功"); } } catch (SQLException e){ e.printStackTrace(); } finallt { JdbcUtils.release(conn, st, rs); } }
public static void main(String[] args) { Connection conn = null; Statement st = null; ResultSet rs = null; try{ conn = JdbcUtils.getConnection(); st = conn.createStatement(); String sql = "select * from user"; rs = st.executeQuery(sql); while(rs.next()){ System.out.println(rs.getString("name")); } } catch (SQLException e){ e.printStackTrace(); } finallt { JdbcUtils.release(conn, st, rs); } }
SQL注入
-
sql存在漏洞, 导致数据泄露
public static void login(String username, String password) { Connection conn = null; Statement st = null; ResultSet rs = null;try{ conn = JdbcUtils.getConnection(); st = conn.createStatement(); String sql = "select * from user where `name`='"+username+"' and `password` = '"+password+"'"; rs = st.executeQuery(sql); while(rs.next()){ System.out.println(rs.getString("name")); System.out.println(rs.getString("password")); } } catch (SQLException e){ e.printStackTrace(); } finallt { JdbcUtils.release(conn, st, rs); }
}
public static void main(String[] args) {
//正常
//login("chen","123456");//非正常 login(" 'or '1=1"," 'or '1=1");
}
PreparedStatement对象
-
可以防止sql注入, 并且效率高
-
本质: 将传入的参数包裹一层, 转为字符串 转义字符会被忽略
'
会被转义
public static void main(String[] args) { Connection conn = null; PreparedStatement st = null;try{ conn = JdbcUtils.getConnection(); //使用? 占位符 String sql = "insert into user(id, name, pwd,create_time) values(?, ?, ?)"; st = conn.preparedStatement(sql);//预编译sql, 但不执行 //参数赋值 st.setInt(1, 1); st.setString(2, "jack"); st.setString(3, "123456"); //sql.Date 数据库 //util.Date java new Date().getTime() 获取时间戳 st.setDate(4, new java.sql.Date(new Date().getTime())); //执行 int row = st.executeUpdate(sql); if(row > 0){ System.out.println("插入成功"); } } catch (SQLException e){ e.printStackTrace(); } finallt { JdbcUtils.release(conn, st, rs); }
}
public static void main(String[] args) { Connection conn = null; PreparedStatement st = null; ResultSet rs = null; try{ conn = JdbcUtils.getConnection(); //使用? 占位符 String sql = "select * from user where name = ? and password = ?"; st = conn.preparedStatement(sql);//预编译sql, 但不执行 //参数赋值 st.setString(1, "jack"); st.setString(2, "123456"); //执行 rs = st.executeQuery(); while(rs.next()){ System.out.println(rs.getString("name")); System.out.println(rs.getString("password")); } } catch (SQLException e){ e.printStackTrace(); } finallt { JdbcUtils.release(conn, st, rs); } }
事务
-
要么都成功, 要么都失败
ACID原则
-
原子性: 要么都完成, 要么都不完成
-
一致性: 总数不变
-
隔离性: 多个进程互不干扰
-
持久性: 一旦提交不可逆, 持久化到数据库
隔离性问题
-
脏读: 一个事务读取了另一个没有提交的事务
-
不可重复读: 在同一个事务内, 重复读取表中的数据, 表数据发生了变化
-
虚读(幻读): 在一个事务内, 读取到了被人插入的数据, 导致前后读取出来的数据不一致
//开启事务或关闭自动提交事务 conn.setAutoCommit(false);//提交事务
conn.commit();//显示定义事务回滚
conn.rollback();
数据库连接池
-
数据库连接---执行完毕---释放 这样十分浪费资源
-
池化技术 : 准备一些预先的资源, 过来就连接预先准备好的
-
最小连接数: 常用连接数
-
最大连接数:
-
等待超时:
编写连接池
-
实现接口 DataSource
开源数据源实现
-
DBCP
-
C3P0
-
Druid
-
我们就不需要编写连接数据库的代码了
DBCP
-
jar包
commons-dbcp-1.4 commons-pool-1.6
-
dbcpconfig.properies
driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false&zeroDateTimeBehavior=convertToNull&&serverTimezone=Asia/Shanghai username=root password=123456初始化连接
initialSize=10
最大连接数
maxIdle=20
最小连接数
minIdle=5
超时
maxWait=60000
connectionProperties=useUnicode=true;characterEncoding=UTF8
事务自动提交
defaultAutoCommit=true
public class JdbcUtils_DBCP{ private static DataSource dataSource = null; static { try{ InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties"); Properties properties = new Properties(); properties.load(in); //创建数据源 dataSource = BasicDataSourceFactory.createDataSource(properties) } catch (Exception e){ e.printStackTrace(); } //获取连接 public static Connection getConnection() throws SQLException{ return dataSource.getConnection();//从数据源中获取连接 } //释放连接资源 public static void release(Connection conn, Statement st, ResultSet rs){ if(rs != null){ try{ rs.close(); } catch (SQLException e){ e.printStackTrace(); } } if(st != null){ try{ st.close(); } catch (SQLException e){ e.printStackTrace(); } } if(conn != null){ try{ conn.close(); } catch (SQLException e){ e.printStackTrace(); } } } } }
public static void main(String[] args) { Connection conn = null; PreparedStatement st = null; try{ conn = JdbcUtils_DBCP.getConnection(); //使用? 占位符 String sql = "insert into user(id, name, pwd,create_time) values(?, ?, ?)"; st = conn.preparedStatement(sql);//预编译sql, 但不执行 //参数赋值 st.setInt(1, 1); st.setString(2, "jack"); st.setString(3, "123456"); //sql.Date 数据库 //util.Date java new Date().getTime() 获取时间戳 st.setDate(4, new java.sql.Date(new Date().getTime())); //执行 int row = st.executeUpdate(sql); if(row > 0){ System.out.println("插入成功"); } } catch (SQLException e){ e.printStackTrace(); } finallt { JdbcUtils_DBCP.release(conn, st, rs); } }
C3P0
-
jar包
c3p0-0.9.5.5 mchange-commons-java-0.2.19
-
c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?><c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false&zeroDateTimeBehavior=convertToNull&&serverTimezone=Asia/Shanghai</property>
<property name="user">root</property>
<property name="password">123456</property><property name="acquireIncrement">5</property> <property name="initialPoolSize">10</property> <property name="minPoolSize">5</property> <property name="maxPoolSize">20</property>
</default-config>
<!-- This app is massive! -->
<named-config name="MySQL">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false&zeroDateTimeBehavior=convertToNull&&serverTimezone=Asia/Shanghai</property>
<property name="user">root</property>
<property name="password">123456</property><property name="acquireIncrement">5</property> <property name="initialPoolSize">10</property> <property name="minPoolSize">5</property> <property name="maxPoolSize">20</property>
</named-config>
</c3p0-config>
public class JdbcUtils_C3P0{ private static ComboPooledDataSource dataSource = null; static { try{ //==================方式一 //dataSource = new ComboPooledDataSource() //============== //dataSource = new ComboPooledDataSource(); //dataSource.setDriverClass(); //dataSource.setUser(); //dataSource.setPassword(); //dataSource.setJdbcUrl(); //dataSource.setMaxPoolSize(); //dataSource.setMinPoolSize(); dataSource = new ComboPooledDataSource("MySQL"); } catch (Exception e){ e.printStackTrace(); } //获取连接 public static Connection getConnection() throws SQLException{ return dataSource.getConnection();//从数据源中获取连接 } //释放连接资源 public static void release(Connection conn, Statement st, ResultSet rs){ if(rs != null){ try{ rs.close(); } catch (SQLException e){ e.printStackTrace(); } } if(st != null){ try{ st.close(); } catch (SQLException e){ e.printStackTrace(); } } if(conn != null){ try{ conn.close(); } catch (SQLException e){ e.printStackTrace(); } } } } }
public static void main(String[] args) { Connection conn = null; PreparedStatement st = null; try{ conn = JdbcUtils_C3P0.getConnection(); //使用? 占位符 String sql = "insert into user(id, name, pwd,create_time) values(?, ?, ?)"; st = conn.preparedStatement(sql);//预编译sql, 但不执行 //参数赋值 st.setInt(1, 1); st.setString(2, "jack"); st.setString(3, "123456"); //sql.Date 数据库 //util.Date java new Date().getTime() 获取时间戳 st.setDate(4, new java.sql.Date(new Date().getTime())); //执行 int row = st.executeUpdate(sql); if(row > 0){ System.out.println("插入成功"); } } catch (SQLException e){ e.printStackTrace(); } finallt { JdbcUtils_C3P0.release(conn, st, rs); } }