JavaEE:企业级java开发 Web
前端(页面:展示,数据!)
后台(连接点:连接数据库JDBC,连接前端(控制视图跳转和给前端传递数据))
数据库(存数据,Txt,Excel,Word)
数据库(DB,DataBase)
概念:数据仓库,软件,安装在操作系统之上!SQL,可以存储大量的数据
作用:存储数据,管理数据
通过表和表之间,行和列之间的关系进行数据的存储。学员信息表,考勤表,···
非关系型数据库,对象存储,通过对象自身的属性来决定。
MySQL是一个关系型数据库管理系统
前世:瑞典MySQLAB公司
今生:属于Oracle旗下产品
MySQL是最好的RDBMS(Relational Database Management System,关系型数据库管理系统)应用软件之一
体积小、速度快、总体拥有成本低
中小型网站、或者大型网站,集群!
官方:https://www.mysql.com
官网下载地址:https://dev.mysql.com/downloads/mysql/
安装建议:
create database kuangshenMySQL
character set utf8;
创建表
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;
常用命令
show create database kuangshenMySQL -- 查看创建数据库的语句
show create table student -- 查看student数据表的定义语句
desc student -- 显示表的结构
INNODB,MYISAM早些年使用
MYISAM | **INNODB | |
---|---|---|
事务支持 | 不支持 | 支持 |
数据行锁定 | 不支持 | 支持 |
外键约定 | 不支持 | 支持 |
全文索引 | 支持 | 不支持 |
表空间的大小 | 较小 | 较大,约为MYSAM两倍 |
常规使用操作:
在物理空间存在的位置
所有的数据库文件都存在data目录下!,一个文件夹对应一个数据库
本质还是文件的存储!
MySQL引擎在物理文件上的区别
设置数据库表的字符集编码
charset=utf8
不设置的话,会是mysql默认的字符集编码~(不支持中文)
MySQL的默认编码是Latin1,不支持中文
在my.ini中配置默认编码
character-set-server=utf8
方式一:在创建表的时候,增加约束
create table `grade`(
`gradeId` int(10) not null auto_increment comment '年纪Id',
`gradeName` varchar(50) not null comment '年级名称',
primary key(`gradeId`)
)engine=innodb default charset=utf8;
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 '出生日期',
`gradeId` int(10) not null comment '学生的年级',
`address` varchar(100) default null comment '家庭地址',
`email` varchar(50) default null comment '邮箱',
primary key(`id`),
-- 学生表的gradeId字段 要去引用年级表的 gradeId
-- 定义外键key
-- 给这个外键添加约束(执行引用)
key `FK_gradeId`(`gradeId`),
constraint foreign key (`gradeId`) references `grade`(`gradeId`)
)Engine =innodb DEFAULT CHARSET=utf8;
删除有外键关系的表的时候,必须要先删除引用别人的表(从表),再删除被引用的表(主表)
方式二:创建表成功后,添加外键约束
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 '出生日期',
`gradeId` int(10) not null comment '学生的年级',
`address` varchar(100) default null comment '家庭地址',
`email` varchar(50) default null comment '邮箱',
primary key(`id`)
)Engine =innodb DEFAULT CHARSET=utf8;
-- 创建表的时候没有外键
alter table `student`
add constraint `FK_gradeId` FOREIGN KEY(`gradeId`) references `grade`(`gradeId`);
-- alter table 表 add constraint `约束名` FOREIGN KEY (`作为外键的字段`) references `哪个表`(`哪个字段`)
以上操作都是物理外键,数据库级别的外键,我们不建议使用!(避免数据过多造成困扰,了解就好)
最佳实践
INSERT INTO `student`(`name`) VALUES('张三');
INSERT INTO `student`(`name`,`pwd`,`sex`) VALUES('张三','aaaaa','男');
INSERT INTO `student`(`name`,`pwd`,`sex`)
VALUES('张三','aaaaa','男'),('李四','aaaaa','男');
语法:insert into `表名` (`字段名1`,`字段名2`) VALUES (‘值1’,‘值2’), (‘值1’,‘值2’)…;
注意事项:
update `student` set name='Can同学' where name = '张三' AND sex = '男'
语法:UPDATE `表名` set colnum_name = value,[colnum_name=value,…] where [条件]
注意事项:
delete命令
-- 删除数据,如果没有条件where则会删除全部数据
delete from `student` where id = 1;
语法:delete from 表名 where 条件
truncate命令
作用:完全清空
一个数据库表,表的结构和索引约束不会变!
-- 清空 student表
truncate `student`
相同点
不同点
了解即可:delete删除的问题,重启数据库,现象
操作 | 描述 |
---|---|
inner join | 如果表中至少有一个匹配,就返回行,只返回匹配的行 |
left join | 会从左表中返回所有的值,即使右边中没有匹配 |
right join | 会从右表中返回所有的值,即使左边中没有匹配 |
-- 第一页 limit 0,5 (1-1)*5
-- 第二页 limit 5,5 (2-1)*5
-- 第三页 limit 10,5 (3-1)*5
-- 第N页 limit 0,5 (n-1)*pageSize
-- 【pageSize:页面大小】
-- 【(n-1)*pageSize:起始值】
-- 【n:当前页】
-- 【数据总数/页面大小 = 总页数】
语法:limit(查询起始下标,pageSize)
-- ====================常用函数====================
-- 数学运算
SELECT ABS(-8); -- 绝对值
SELECT CEILING(9.4); -- 向上取整
SELECT FLOOR(9.4); -- 向下取整
SELECT RAND(); -- 返回一个0~1之间的随机数
SELECT SIGN(-10); -- 判断一个数的符号 0-0 负数返回-1,正数返回1
-- 字符串函数
SELECT CHAR_LENGTH('即使再小的帆也能远航'); -- 字符串长度
SELECT CONCAT('哈','撒','给'); -- 拼接字符串
SELECT INSERT('我爱编程helloworld',2,4,'嗯'); -- 查询,从某个位置开始替换某个长度,替换下标到哪个下标
SELECT LOWER('Can'); -- 转成小写字母
SELECT UPPER('Can'); -- 转成大写字母
SELECT INSTR('Ccan','c'); -- 返回第一次出现的字串的索引,不区分大小写
SELECT REPLACE('明天还要继续','继续','看'); -- 替换出现的指定字符串
SELECT SUBSTR('明天还要继续哈哈',4,5); -- 返回指定的字符串,(源字符串,截取的位置,截取的长度)
SELECT REVERSE('明天还要继续哈'); -- 反转 哈续继要还天明
-- 时间和日期函数(记住)
SELECT CURRENT_DATE(); -- 获取当前日期 2020-04-21
SELECT CURDATE(); -- 获取当前日期 2020-04-21
SELECT NOW(); -- 获取当前的时间 2020-04-21 22:16:59
SELECT LOCALTIME(); -- 本地时间 2020-04-21 22:17:29
SELECT SYSDATE(); -- 系统时间 2020-04-21 22:17:45
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();
函数名称 | 描述 |
---|---|
COUNT() | 计数 |
SUM() | 求和 |
AVG() | 平均值 |
MAX() | 最大值 |
MIN() | 最小值 |
… | … |
-- =============聚合函数=============
-- 都能够统计 表中的数据
-- 列名为主键时,count(列名)比count(1)快,否则count(1)快
-- 如果表多个列并且没有主键,则count(1)的执行效率优于count(*)
-- 如果有主键。则count(主键)的执行效率最优的
-- 如果表只有一个字段,则count(*)最优
SELECT COUNT(birthday) from student; -- count(字段),会忽略所有的null值
SELECT COUNT(*) from student; -- count(*),不会忽略Null值,本质 计算行数
SELECT COUNT(1) from student; -- count(1),不会忽略Null值
SELECT SUM(pwd) as 总和 from student;
SELECT AVG(pwd) as 平均分 from student;
SELECT MAX(pwd) as 最高分 from student;
SELECT MIN(pwd) as 最低分 from student;
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=utf8;
-- 明文密码
insert into testmd5 values(1,'张三','123456'),(2,'李四','123456'),(3,'张里','123456');
-- 加密
UPDATE testmd5 set pwd = MD5(pwd) where id=1;
UPDATE testmd5 set pwd = MD5(pwd); -- 加密全部的密码
-- 插入的时候加密
insert into testmd5 values (4,'小明',MD5('123456'));
-- 如何校验:将用户传递进来的密码,进行MD5加密,然后对比加密后的值。
select * from testmd5 where `name` = '小明' AND PWD =MD5(MD5('123456'));
事务原则:ACID原则 原子性,一致性,隔离性,持久性 (脏读,幻读。。。)
隔离所导致的一些问题
MySQL官方对索引的定义为:索引(index)是帮助MySQL高效获取数据的数据结构。提取句子主干,就可以得到索引的本质:索引是数据结构。
在一个表中,主键索引只能有一个,而唯一索引可以有多个
create table if not exists `student_index`(
`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 '出生日期',
`gradeId` int(10) not null comment '学生的年级',
`address` varchar(100) default null comment '家庭地址',
`email` varchar(50) default null comment '邮箱',
primary key(`id`),
key(`email`)
)Engine =MYISAM DEFAULT CHARSET=utf8;
insert into student_index values(null,'谢3','123','男',NOW(),3,'address','@qq'),(null,'谢4','123','男',NOW(),4,'address','@qq'),(null,'谢5','123','男',NOW(),5,'address','@qq'),(null,'谢6','123','男',NOW(),6,'address','@qq');
-- 显示所有的索引信息
show index from student_index;
-- 增加一个全文索引(索引名)
alter table kuangshenmysql.student_index add fulltext index `studentName`(`name`);
-- EXPLAIN 分析sql执行的状况
EXPLAIN SELECT * FROM student_index; -- 非全文索引
EXPLAIN SELECT * FROM student_index WHERE MATCH(`name`) AGAINST('谢');
CREATE TABLE `APP_USER`(
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) default '' comment '用户昵称',
`email` VARCHAR(50) NOT NULL COMMENT '用户邮箱',
`phone` varchar (20) default '' comment '手机号',
`gender` TINYINT(4) UNSIGNED DEFAULT '0' comment '性别(0:男;1:女)',
`password` varchar(100) not null comment '密码',
`age` TINYINT(4) default '0' comment'年龄',
-- `create_time` DATETIME default SYSDATE(),
-- `update_time` BIGINT(10) default unix_timestamp(now()),
primary key (`id`)
)ENGINE=INNODB default charset=utf8mb4 comment='app用户表';
-- 插入100万数据
DELIMITER $$ -- 写函数之前必须要写,标志
CREATE FUNCTION mock_data()
RETURNS INT
BEGIN
DECLARE num INT DEFAULT 1000000;
DECLARE i INT DEFAULT 0;
WHILE i<num DO
-- 插入语句
INSERT INTO app_user(`name`,`email`,`phone`,`gender`,`password`,`age`)values(CONCAT('用户',i),'[email protected]',
CONCAT('13',FLOOR(RAND()*((9999999999-100000000)+100000000))),FLOOR(RAND()*2),UUID(),FLOOR(RAND()*100));
SET i = i+1;
END WHILE;
RETURN i;
END;
-- 执行方法
-- 栈不够的问题 打开.ini 改配置thread_stack = 128K#改为512K
select mock_data();
1001506才找到它,很慢
加上索引
-- 命名方式:id_表名_字段名
-- CREATE INDEX 索引名 on 表(字段)
CREATE INDEX id_app_user_name ON app_user(`name`);
-- 明显变快了
select * from APP_USER WHERE `name` = '用户99999'; -- 0.001s
索引在小数据量的时候,用处不大,但是在大数据的时候,区别十分明显~
索引的数据结构
Hash类型的索引
Btree:InnoDB的默认数据结构(B树)
用户表:mysql.user
本质:对这张表进行增删改查
select * from mysql.user;
-- 创建用户
CREATE USER can identified by '123456';
-- 修改密码(修改当前用户密码)
SET PASSWORD = PASSWORD('root')
-- 修改密码(修改指定用户密码)
SET PASSWORD FOR can = PASSWORD('root')
-- 重命名 rename user 原来的名 to 新的名
rename user can to can2;
-- 用户授权 ALL PRIVILEGES 全部的权限,库.表
-- ALL PRIVILEGES 除了给别人授权,其他都能干
GRANT ALL privileges ON *.* to can2;
-- 查看权限
SHOW grants for can2; -- 查看指定用户的权限
-- 查看root权限 要加上@主机
show grants for root@localhost;
-- 撤销权限 REVOKE 哪些权限,在哪个库撤销,给谁撤销
REVOKE ALL PRIVILEGES ON *.* from can2;
-- 删除用户
DROP USER can2;
为什么要备份:
MySQL备份的方式
#命令行mysqldump导出SQL
#mysqldump -h主机 -u用户名 -p密码 数据库 表名 > 物理磁盘位置/文件名
mysqldump -hlocalhost -uroot -proot kuangshenmysql student > D:/a.sql
#导出多张表
#mysqldump -h主机 -u用户名 -p密码 数据库 表名1 表名2 > 物理磁盘位置/文件名
# 注意这里-B `B`必须是大写,代表导出有建库的语句
mysqldump -hlocalhost -uroot -proot -B kuangshenmysql student grade > D:/b.sql
#导出数据库所有数据
#mysqldump -h主机 -u用户名 -p密码 数据库 > 物理磁盘位置/文件名
mysqldump -hlocalhost -uroot -proot -B kuangshenmysql > D:/b.sql
# 登录的情况下,如果导入表,切换到指定的数据库,如果导入数据库的话就没必要切换了
# source 备份文件
source d:/a.sql
# 没有登录的情况,不建议用这个
#导入表
mysql -u用户名 -p密码 库名< 备份文件
#导入库
mysql -u用户名 -p密码 <备份文件
假设你要备份数据库,防止数据丢失。
把数据库给朋友!sql文件给别人即可!
当数据库比较复杂的时候,我们就需要设计了
糟糕的数据设计:
良好的数据库设计:
软件开发中关于数据库的设计
设计数据库的步骤:(个人博客)
收集信息,分析需求
标识实体(把需求落地到每个字段)
为什么需要数据规范化?
三大范式
第一范式(1NF)
原子性:保证每一列不可再分
第二范式(2NF)
前提:满足第一范式
每张表只描述一件事情
第三范式(3NF)
前提:满足第一范式和第二范式
第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。
(规范数据库的设计)
规范性 和 性能的问题
阿里的规范:关联查询的表不能超过三张表
SUN公司为了简化开发人员(对数据库的统一)操作,提供了一个(Java操作数据库的)规范,俗称JDBC这些规范的实现由具体的厂商去做~
驱动下载地址:https://dev.mysql.com/downloads/file/?id=489462
mysql-connector-java.jar
创建测试数据库
create database kuangshenjdbc character set utf8 collate utf8_general_ci;
use kuangshenjdbc;
create table users(
id int primary key,
name varchar(40),
password varchar(40),
email varchar(60),
birthday date
);
insert into users(id,name,password,email,birthday)
values(1,'can1','123456','@qq.com','1997-03-03'),
(2,'can2','123456','@qq.com','1997-03-03'),
(3,'can2','123456','@qq.com','1997-03-03');
3.编写测试代码
package com.can.lesson01;
import java.sql.*;
/**
* 第一个JDBC程序
*/
public class JdbcFirstDemo {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");//固定写法,加载驱动
//2.用户信息和url,useSSL使用安全的连接
String url = "jdbc:mysql://localhost:3306/kuangshenjdbc?useUnicode=true&characterEncoding=utf-8&useSSL=true";
String username = "root";
String password = "root";
//3.连接成功,返回数据库对象
Connection connection = DriverManager.getConnection(url,username,password);
//默认会开启事务
connection.setAutoCommit(false);//关闭事务
//4.执行SQL的对象
Statement statement = connection.createStatement();
//5.执行SQL的对象, 去执行SQL,可能存在结果,查询返回结果
ResultSet resultSet = statement.executeQuery("SELECT * FROM users"); //返回结果集
PreparedStatement r1 = connection.prepareStatement("update users set password='123' where name ='can1' ");
int i = r1.executeUpdate();
System.out.println(i);
//提交事务
connection.commit();
//归滚
// connection.rollback();
while (resultSet.next()){
System.out.println("id==>"+resultSet.getObject("id"));
System.out.println("name==>"+resultSet.getObject("name"));
System.out.println("password==>"+resultSet.getObject("password"));
System.out.println("email==>"+resultSet.getObject("email"));
System.out.println("birthday==>"+resultSet.getObject("birthday"));
}
//6.释放连接
resultSet.close();
statement.close();
connection.close();
}
}
步骤总结:
JdbcUtils
package com.can.lesson01;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
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 {
//getClassLoader获得该类的装载器
//getResourceAsStream用给定的名查找资源
InputStream in = JdbcUtils.class.getClass().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");
Class.forName("com.mysql.jdbc.Driver");
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException {
return DriverManager.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 {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
SQL存在漏洞,会被攻击导致数据泄露
SQL会被拼接 or
package com.can.lesson01;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
public class SQL注入 {
public static void main(String[] args) {
// login("can1","123"); //正常登录
login(" ' or '1=1","123' or '1=1"); // SQL注入
}
//登录业务
private static void login(String username,String password){
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
st = conn.createStatement();
//SQL
//select * from users where name = '' or '1=1' and password='123' or '1=1';
String sql = "select * from users where `name`='"+username+"'"+"AND "+"`password`='"+password+"'";
rs = st.executeQuery(sql);
while (rs.next()){
System.out.println(rs.getObject("name"));
System.out.println(rs.getObject("password"));
System.out.println("============");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//6.释放连接
JdbcUtils.release(conn,st,rs);
}
}
}
preparedStatement可以防止SQL注入。效果更好!
package com.can.lesson01;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Date;
import java.util.Scanner;
/**
* prepareStatement
* 预编译 防止SQL注入
*/
public class PreparedStatementDemo {
public static void main(String[] args) {
// PreparedStatementDemo.login("can1","123"); //正常登录
login(" ' or '1=1","123' or '1=1"); // SQL注入
}
//登录业务
private static void login(String username,String password){
Connection conn = null;
// Statement st = null;
PreparedStatement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
//区别
//prepareStatement 防止SQL注入的本质: 把传递过来的参数 当作字符 包裹起来 '参数'
//假设字符中存在转义字符,就直接忽略, '会被直接转义
String sql = "select * from kuangshenjdbc.users where `name`= ? and `password` =?";//预编译SQL 参数用 '?'
// st = conn.createStatement();
st = conn.prepareStatement(sql); //预编译SQL,先写sql,然后不执行
//手动参数赋值
st.setString(1,username);
st.setString(2,password);
//注意点:sql.Date 数据库 java.sql.Date()
// util.Date Java new Date().getTime() 获得时间戳
// st.setDate(2,new java.sql.Date(new Date().getTime()));
//执行
rs = st.executeQuery();
while (rs.next()){
System.out.println(rs.getObject("name"));
System.out.println(rs.getObject("password"));
System.out.println("============");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//6.释放连接
JdbcUtils.release(conn,st,rs);
}
}
}
数据库连接–执行完毕–释放
连接–释放 十分浪费系统资源
池化技术:准备一些预留的资源,过来就连接预先准备好的
----开门—业务员:等待 --服务–
常用连接数100个
最小连接数:100
最大连接数:1000 |业务最高承载上限,超过1000个人会排队等待,
等待超时:100ms |会断掉
编写连接池,只需要实现一个接口,DataSrouce
开源数据源实现(拿来即用)
DBCP
C3P0
Druid:阿里巴巴
使用了这些数据库连接池之后,我们在项目开发中就不需要编写连接数据库的代码了!
DBCP
需要用到的jar包
下载地址:http://commons.apache.org/proper/commons-dbcp/download_dbcp.cgi
commons-dbcp-1.4.jar、commons-pool-1.6.jar
package com.can.lesson01.utils;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class poolUtil_DBCP {
private static DataSource dataSource = null;
// private static BasicDataSource dataSource = null;
static{
try {
InputStream in = poolUtil_DBCP.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 (conn!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (st!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
C3P0
需要用到的jar包
c3p0-0.9.5.5、mchange-commons-java-0.2.19
package com.can.lesson01.utils;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class poolUtil_C3P0 {
private static ComboPooledDataSource dataSource = null;
// private static BasicDataSource dataSource = null;
static{
try {
//代码版配置
// dataSource = new ComboPooledDataSource();
// dataSource.setDriverClass();
// dataSource.setUser();
// dataSource.setPassword();
// dataSource.setJdbcUrl();
//
// dataSource.setMaxPoolSize();
// dataSource.setMinPoolSize();
//配置文件写法
dataSource = new ComboPooledDataSource("test"); //使用test数据源
// dataSource = new ComboPooledDataSource(); //使用默认数据源
} 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 (conn!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (st!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
结论