MySql学习笔记--详细整理--下
索引
MySQL官方对索引的定义为:索引(index)是帮助MySQL高效获取数据的的数据结构,提取句子主干,就可以得到作用的本质,索引是数据结构。
索引的分类
- 主键索引:PRIMARY KEY
- 唯一的标识,主键不可重复,只能由一个列作为索引
- 唯一索引:UNIQUE KEY
- 避免重复的列出现,唯一索引可以重复,多个列都可以标识为唯一索引
- 常规索引:KEY/INDEX
- 默认的,index,key关键字设置
- 全文索引:FullText
- 在特定的数据库引擎下才有
- 快速定位数据
基础语法
--索引的使用
--在创建表的时候给字段增加索引 或创建完表后增加
USE school
SHOW INDEX FROM student1
--增加索引
ALTER TABLE `student1` ADD FULLTEXT INDEX `studentname`(`studentname`)
--EXPLAIN 分析sql执行的状况
EXPLAIN SELECT * FROM `student1` --非全文索引
EXPLAIN SELECT * FROM student1 WHERE MATCH(studentname) AGAINST('韩')
测试索引
--测试索引
CREATE TABLE `app_user`(
`id` INT(4) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(20) DEFAULT'' COMMENT'用户姓名',
`email` VARCHAR(20) NOT NULL COMMENT'用户邮箱',
`phone` VARCHAR(20) DEFAULT'' COMMENT'用户电话',
`gender` TINYINT(4) UNSIGNED DEFAULT'0' COMMENT'性别(1是男,2是女)',
`password` VARCHAR(50) NOT NULL COMMENT '密码',
`age` INT(3) DEFAULT'0' COMMENT'年龄',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
`update_name` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY(`id`)
)ENGINE INNODB DEFAULT CHARSET=utf8mb4 COMMENT'app用户表'
--插入100万条数据
--写函数之前必须写 标志
DELIMITER $$
CREATE FUNCTION mock_dat() #创建一个函数
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),'813794474@qq.com',CONCAT('18',FLOOR(RAND()*((999999999-1000000000)+1000000000))),
FLOOR((RAND()*2)+1),UUID(),FLOOR(RAND()*100));
SET i=i+1;
END WHILE;
RETURN i;
END;
--
SELECT mock_dat();
SELECT * FROM app_user WHERE name = '用户9999';
EXPLAIN SELECT * FROM app_user WHERE name = '用户9999';
EXPLAIN SELECT * FROM app_user WHERE name = '用户1';
--创建索引 id_表名_字段名 on 表(字段)
CREATE INDEX id_app_user_name ON app_user(`name`);
SELECT * FROM app_user WHERE name = '用户9999';
EXPLAIN SELECT * FROM app_user WHERE name = '用户9999';
索引在小数据的时候用处不大,在大数据的时候,区别十分明显。
索引原则
- 索引不是越多越好
- 不要对经常变动的数据加索引
- 小数据量的表不需要加索引
- 索引一般加在常用来查询的字段上
索引的数据结构
Hash 类型的索引
Btree:innodb默认的数据结构
权限管理和备份
点击用户进去可以选择新增用户,在服务器权限中可以给用户设置不同的权限。
也可以使用SQL赋予每个用户权限
--创建用户
CREATE USER zhou IDENTIFIED BY '123456'
--修改当前用户密码
SET PASSWORD = PASSWORD('111111')
--修改指定用户密码
SET PASSWORD FOR zhou = password('111111')
--重命名
RENAME USER zhou TO zzzz
--用户授权 授予全部的权限
--ALL PRIVILEGES除了给别人授权都可以
GRANT ALL PRIVILEGES ON *.* TO zzzz
--查看指定用户权限
SHOW GRANTS FOR zzzz
--查看管理员权限
SHOW GRANTS FOR root@localhost
--root用户权限 GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
--撤销权限
REVOKE ALL PRIVILEGES *.* FROM zzzz
--删除用户
DROP zzzz
备份
为什么备份:
- 保证重要的数据不丢失
- 数据转移
MySQL数据库备份的方式
直接拷贝物理文件
在可视化工具中手动导出数据库
- 在想要导出的表或者库中,右键选择转储sql文件
使用命令行导出 mysqldump 命令行使用
--mysqldump -h主机 -u用户名 -p密码 数据库 表名 >物理磁盘位置/文件名
mysqldump -hlocalhost -uroot -p123456 school student1 > D:/a.sql --mysqldump -h主机 -u用户名 -p密码 数据库 表名1 表名2 >物理磁盘位置/文件名
mysqldump -hlocalhost -uroot -p123456 school student1 subject > D:/b.sql --mysqldump -h主机 -u用户名 -p密码 数据库 >物理磁盘位置/文件名
mysqldump -hlocalhost -uroot -p123456 school > D:/c.sql --导入表
--登录
mysql -uroot -p123456
use school;
sourse d/a.sql 或
mysql -u用户名 -p密码 库名 表名<文件路径
规范数据库设计
当数据库比较复杂的时候,需要按规范设计。
糟糕的数据库设计:
- 数据冗余,浪费空间
- 数据插入和删除都麻烦【阿里巴巴开发手册 屏蔽使用外键】
- 系统的性能差
良好的数据库设计:
- 节省内存空间
- 保证数据库的完整性
- 性能好,便于开发
软件开发中关于数据库的设计
- 分析需求:分析业务和需要处理的数据库的需求
- 概要设计:设计关系图E-R图
设计数据库的步骤:(个人博客)
- 收集信息,分析需求
- 用户表(用户登录注册,个人信息,写博客,创建分类)
- 分类表(文章分类,博客作者)
- 文章表(文章信息)
- 友链表(友链信息)
- 评论表 (评论信息)
- 自定义表(可选) (存储其他信息)
- 标识实体(把需求写到字段)
- 标识实体之间的关系
- 写博客:user-->blog
- 创建分类:user-->category
- 友链:link
- ...
三大范式
第一范式(1NF):原子性,要求数据库表的每一列都是不可分割的原子数据项。
第二范式(2NF):满足第一范式,非码属性必须完全依赖于候选码,确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关。即每张表只描述一件事情。
第三范式(3NF):满足第一第二范式,任何非主属性不依赖于其它非主属性(即消除传递依赖),第三范式需要确保数据表中每一列数据都与主键直接相关,而不能间接相关。
规范性和性能问题:(关联查询的表不得超过三张表 阿里规约)
- 考虑商业化需求和目标(成本,用户体验),数据库的性能更加重要
- 在规范性能需求的时候,需要适当考虑一下规范性
- 在有些情况下,故意给表增加一些冗余字段(多表查询变为单表查询),提高效率
- 故意增加一些计算列(从大数据量降为小数据量的一些查询)
JDBC
数据库驱动:应用程序和数据库之间需要有驱动来进行连接。
SUN公司为了简化开发人员的(对数据库的统一)操作,提供了一个(Java操作数据库)规范,俗称JDBC。
这些规范的具体实现由数据库厂商去做。
对于开发人员来说只需掌握JDBC接口的操作即可。
java.sql javac.sql
JDBC程序
创建lib目录,在lib下放入mysql-connector-java-5.1.47.jar,右击lib,add as library。
- 加载驱动
- 连接数据库 DriverManager
- 获得执行sql的对象 statement
- 获得返回的结果值
- 释放连接
package com.zr.lesson01;
import java.sql.*;
public class JdbcDemo01 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//加载驱动
Class.forName("com.mysql.jdbc.Driver");
//用户信息和Url
String url = "jdbc:mysql://localhost:3306/jdbcStudy?useUnicode=true&characterEncoding=utf8&useSSL=false";
String username = "root";
String password = "123456";
//连接成功 数据库对象 DriverManager驱动管理
Connection connection = DriverManager.getConnection(url, username, password);
//执行sql的对象
Statement statement = connection.createStatement();
//执行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("password"));
System.out.println("email="+resultSet.getObject("email"));
System.out.println("birthday="+resultSet.getObject("birthday"));
System.out.println("======================================");
}
//释放连接 耗资源 用完就关掉
resultSet.close();
statement.close();
connection.close();
}
}
//MySQL默认端口号3306
//Oracle ---1521
//jdbc:oracle:thin:@localhost:1521:sid
connection.commit(); //事务提交
connection.rollback(); //事务回滚
connection.setAutoCommit(true); //开启事务提交
statement.executeQuery(); //查询操作返回 resultset
statement.executeUpdate(); //更新,插入,删除都用这个,返回一个受影响的行数
statement.execute(); //执行任何sql
resultset 查询的结果集,封装了所有的查询结果集
resultSet.getObject();//在不知道列类型的情况下使用
//知道列的指定类型
resultSet.getString();
resultSet.getInt();
resultSet.getDate();
resultSet.beforeFirst();//移动到最前面
resultSet.afterLast();//移动到最后面
resultSet.next();//移动到下一个
resultSet.previous();//移动到前一个
resultSet.absolute(row);//移动到指定行
Statement对象
jdbc中的statement对象用于向数据库发送sql语句,想完成对数据库的增删改查只需发送相应的sql语句即可。
executeUpdate执行完后,返回一个整数(即sql语句导致几行数据发生了变化)。
executeQuery执行完后,返回代表查询结果的resultset对象。
CRUD操作:create,使用Statement(sql)方法完成对数据库的添加操作,示例如下:
Statement st = connection.createStatement;
String sql = "insert into user(...) values(...) "
int num = st.executeUpdate(sql);
if(num>0){
System.out.println("插入成功!")
}
CRUD操作:delete,使用Statement(sql)方法完成对数据库的删除操作,示例如下:
Statement st = connection.createStatement;
String sql = "delete from user wherte id=1"
int num = st.executeUpdate(sql);
if(num>0){
System.out.println("删除成功!")
}
CRUD操作:update,使用Statement(sql)方法完成对数据库的修改操作,示例如下:
statement st = connection.Statement;
String sql = "update user set name=`` where id=1"
int num = st.executeUpdate;
if(num>0){
System.out.println("修改成功!");
}
CRUD操作:read,使用Statement(sql)方法完成对数据库的查询操作,示例如下:
Statement st = connection.createStatement;
String sql = "select * from user "
Resultset rs = st.executeQuery(sql);
if(rs.next()){
//根据获取的数据类型,分别调用rs的相应方法映射到Java对象中
}
工具类实现
先创建一个jdbcStudy数据库,再创建一个users用户表,表中的字段为id,name,password,emain,birthday
配置MySQL数据库文件,创建工具类
配置文件
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcStudy?useunicode=true&characterEncoding=utf8&useSSL=false
username=root
password=123456
工具类
package com.zr.lesson02.utils;
//工具类
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 {
//读取资源
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");
//驱动只用加载一次
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,username,password);
}
//释放连接
public static void release(Connection con, Statement st, ResultSet rs) throws SQLException {
if (rs!=null){
rs.close();
}
if (st!=null){
st.close();
}
if (con!=null){
con.commit();
}
}
}
增加数据
package com.zr.lesson02.utils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
//插入数据
public class TestInsert {
public static void main(String[] args) throws Exception {
Connection con = null;
Statement st = null;
ResultSet rs = null;
try {
con = JdbcUtils.getConnection(); //获取数据库连接
st = con.createStatement();//创建执行sql的对象
String sql = "insert into users values(5,'赵云','111111','111@qq.com','2020-01-01')";
int i = st.executeUpdate(sql);//执行sql
if (i>0){
System.out.println("插入成功!");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
JdbcUtils.release(con,st,rs);
}
}
}
删除数据
package com.zr.lesson02.utils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
//删除数据
public class TestDelete {
public static void main(String[] args) throws SQLException {
Connection con = null;
Statement st = null;
ResultSet rs = null;
try {
con = JdbcUtils.getConnection();//获取数据库连接
st = con.createStatement();//创建执行sql的对象
String sql = "delete from users where id=5";
int i = st.executeUpdate(sql);
if (i>0){
System.out.println("删除创建!");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
JdbcUtils.release(con,st,rs);
}
}
}
修改数据
package com.zr.lesson02.utils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
//修改数据
public class TestUpdate {
public static void main(String[] args) throws SQLException {
Connection con = null;
Statement st = null;
ResultSet rs = null;
try {
con = JdbcUtils.getConnection();//获取数据库连接
st = con.createStatement();//创建执行sql的对象
String sql = "update users set name='韩信' where id=4";
int i = st.executeUpdate(sql);
if (i>0){
System.out.println("更新成功!");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
JdbcUtils.release(con,st,rs);
}
}
}
添加数据
package com.zr.lesson02.utils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
//查询数据
public class TestSelect {
public static void main(String[] args) throws SQLException {
Connection con = null;
Statement st = null;
ResultSet rs = null;
try {
con = JdbcUtils.getConnection();//获取数据库连接
st = con.createStatement();//创建执行sql的对象
String sql = "select * from users";
rs = st.executeQuery(sql);
//if只能查出一条数据 这里查询所有用户信息使用while
while (rs.next()){
System.out.println("id="+rs.getInt("id"));
System.out.println("name="+rs.getString("name"));
System.out.println("password="+rs.getString("password"));
System.out.println("email="+rs.getString("email"));
System.out.println("birthday="+rs.getDate("birthday"));
System.out.println("==========================");
}
System.out.println("查询成功!");
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
JdbcUtils.release(con,st,rs);
}
}
}
sql注入
sql存在漏洞,会被攻击导致数据泄露,sql会被拼接。
package com.zr.lesson02.utils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
//sql注入
public class SqlInjection {
public static void main(String[] args) throws SQLException {
//正常登录 数据库中有的用户和密码
//login("韩信","111111");
//sql注入 会输出所有密码为123456的人的信息
login("'or'1=1","123456");
//sql注入 会查询所有信息
//login("'or'1=1","'or='1=1");
}
//登录业务
public static void login(String username,String password) throws SQLException {
Connection con = null;
Statement st = null;
ResultSet rs = null;
try {
con = JdbcUtils.getConnection();//获取数据库连接
st = con.createStatement();//创建执行sql的对象
//select * from users where name=''or'1=1' and password='123456'
//select * from users where name=''or'1=1' and password=''or'1=1'
String sql = "select * from users where name='"+username+"' and password='"+password+"'";
rs = st.executeQuery(sql);
//if只能查出一条数据 这里查询所有用户信息使用while
while (rs.next()){
System.out.println("id="+rs.getInt("id"));
System.out.println("name="+rs.getString("name"));
System.out.println("password="+rs.getString("password"));
System.out.println("email="+rs.getString("email"));
System.out.println("birthday="+rs.getDate("birthday"));
System.out.println("==========================");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
JdbcUtils.release(con,st,rs);
}
}
}
PreparedStatement对象
PreparedStatement可以防止sql注入,而且效率更高。实例如下:
增加数据:
package com.zr.lesson03;
import com.zr.lesson02.JdbcUtils;
import java.util.Date;
import java.sql.*;
//PreparedStatement 插入
public class TestInsert {
public static void main(String[] args) throws SQLException {
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
con = JdbcUtils.getConnection();
//区别
String sql = "insert into users values(?,?,?,?,?)";//使用?占位符 代替参数
ps = con.prepareStatement(sql);//预编译 先写sql 然后不执行
//手动给参数赋值
ps.setInt(1,5);
ps.setString(2,"李白");
ps.setString(3,"123333");
ps.setString(4,"813794474@qq.com");
//sql.Date 数据库 java.sql.date()
//util.Date Java new date().gettime() 获得时间戳
ps.setDate(5,new java.sql.Date(new Date().getTime()));
//执行
int i = ps.executeUpdate();
if (i>0){
System.out.println("插入成功!");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
JdbcUtils.release(con,ps,rs);
}
}
}
删除数据:
package com.zr.lesson03;
import com.zr.lesson02.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
//PreparedStatement 删除
public class TestDelete {
public static void main(String[] args) throws SQLException {
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
con = JdbcUtils.getConnection();
//区别
String sql = "delete from users where id=?";//使用?占位符 代替参数
ps = con.prepareStatement(sql);//预编译 先写sql 然后不执行
//手动给参数赋值
ps.setInt(1,5);
//执行
int i = ps.executeUpdate();
if (i>0){
System.out.println("删除成功!");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
JdbcUtils.release(con,ps,rs);
}
}
}
修改数据:
package com.zr.lesson03;
import com.zr.lesson02.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
//PreparedStatement 修改
public class TestUpdate {
public static void main(String[] args) throws SQLException {
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
con = JdbcUtils.getConnection();
//区别
String sql = "update users set name = ? where id = ?;";//使用?占位符 代替参数
ps = con.prepareStatement(sql);//预编译 先写sql 然后不执行
//手动给参数赋值
ps.setString(1,"关羽");
ps.setInt(2,3);
//执行
int i = ps.executeUpdate();
if (i>0){
System.out.println("修改成功!");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
JdbcUtils.release(con,ps,rs);
}
}
}
查询数据:
package com.zr.lesson03;
import com.zr.lesson02.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
//查询
public class TestSelect {
public static void main(String[] args) throws SQLException {
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
con = JdbcUtils.getConnection();
String sql = "select * from users where id=?";
ps = con.prepareStatement(sql);
ps.setInt(1,3);
rs = ps.executeQuery();
if (rs.next()){
System.out.println("name="+rs.getString("name"));
System.out.println("password="+rs.getString("password"));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
JdbcUtils.release(con,ps,rs);
}
}
}
事务
要么都成功,要么都失败。
ACID原则:原子性(要么都成功,要么都失败),一致性(保持最终结果的一致性),持久性(一旦提交不可逆,持久到数据库),隔离性(多个进程互不干扰)。
隔离性的问题:
- 脏读:一个事务读取了另一个没有提交的事务
- 虚读(幻读):在一个事务内读取到了别人插入的数据,导致前后读出来的数据不一致
- 不可重复读:在同一个事务内,重复读取了表中的数据,表数据发生了改变
package com.zr.lesson04;
import com.zr.lesson02.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
//模拟转账成功
public class TestTransaction {
public static void main(String[] args) throws SQLException {
Connection con = null;
PreparedStatement st = null;
ResultSet rs = null;
try {
con = JdbcUtils.getConnection();
//关闭数据库的自动提交功能,自动开启事务
con.setAutoCommit(false);
//执行业务
String sql1 ="update account set money = money-100 where name = 'libai'";
st = con.prepareStatement(sql1);
st.executeUpdate();
String sql2 ="update account set money = money+100 where name = 'hanxin'";
st = con.prepareStatement(sql2);
st.executeUpdate();
//业务完毕 提交事务
con.commit();
System.out.println("成功!");
} catch (SQLException throwables) {
try {
con.rollback(); //失败就回滚事务
} catch (SQLException e) {
e.printStackTrace();
}
throwables.printStackTrace();
}finally {
JdbcUtils.release(con,st,rs);
}
}
}
模拟转账失败
package com.zr.lesson04;
import com.zr.lesson02.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
//模拟转账失败
public class TestTransaction02 {
public static void main(String[] args) throws SQLException {
Connection con = null;
PreparedStatement st = null;
ResultSet rs = null;
try {
con = JdbcUtils.getConnection();
//关闭数据库的自动提交功能,自动开启事务
con.setAutoCommit(false);
//执行业务
String sql1 ="update account set money = money-100 where name = 'libai'";
st = con.prepareStatement(sql1);
st.executeUpdate();
int x=1/0;//报错
String sql2 ="update account set money = money+100 where name = 'hanxin'";
st = con.prepareStatement(sql2);
st.executeUpdate();
//业务执行完毕 提交事务
con.commit();
System.out.println("成功!");
} catch (Exception e) {
//默认会自动回滚 也可以显式定义
/* try {
con.rollback(); //失败就回滚事务
} catch (SQLException e2) {
e2.printStackTrace();
}*/
e.printStackTrace();
}finally {
JdbcUtils.release(con,st,rs);
}
}
}
数据库连接池
数据库连接---执行完毕---释放 连接释放是十分浪费系统资源的。
池化技术:准备一些预先的资源,过来连接已经准备好的。
编写连接池,实现一个接口DataSource。
开源数据源实现:
- DBCP
- C3P0
- Durid(阿里巴巴)
DBCP
使用这些数据库连接池之后,我们在项目开发中就不需要编写数据库连接的代码了。
DBCP:lib下导入 commens-dbcp-1.4.jar和commens-pool-1.6.jar
创建dbconfig.properties文件
#连接设置
driverClassname=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcStudy?useunicode=true&characterEncoding=utf8&useSSL=false
username=root
password=123456
#初始化连接
initialSize=10
#最大连接数量
maxActive=50
#最大空闲连接
maxIdle=20
#超时等待时间 毫秒
maxWait=60000
connectionProperties=useUnicode=true;characterEncoding=utf8
defaultAutoCommit=true
defaultReadOnly=
defaultTransactionIsolation=READ_UNCOMMITTED
创建DBCP工具类
package com.zr.lesson05;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class JdbcUtils_DBCP {
private static DataSource dataSource = null;
static{
try{
InputStream in = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("dbconfig.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 con, Statement st, ResultSet rs){
if (con!=null){
try {
con.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (st!=null){
try {
con.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (rs!=null){
try {
con.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
测试插入数据
package com.zr.lesson05;
import com.zr.lesson02.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
public class TestDBCP {
public static void main(String[] args) throws SQLException {
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
con = JdbcUtils_DBCP.getConnection();
//区别
String sql = "insert into users values(?,?,?,?,?)";//使用?占位符 代替参数
ps = con.prepareStatement(sql);//预编译 先写sql 然后不执行
//手动给参数赋值
ps.setInt(1, 5);
ps.setString(2, "李白");
ps.setString(3, "123333");
ps.setString(4, "813794474@qq.com");
//sql.Date 数据库 java.sql.date()
//util.Date Java new date().gettime() 获得时间戳
ps.setDate(5, new java.sql.Date(new Date().getTime()));
//执行
int i = ps.executeUpdate();
if (i > 0) {
System.out.println("插入成功!");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
JdbcUtils_DBCP.release(con, ps, rs);
}
}
}
C3P0
C3P0:lib下导入c3p0-0.9.5.5.jar和mchange-commens-java-0.2.19.jar
先创建c3p0-config.xml文件,再创建JdbcUtils_C3P0工具类
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- 默认配置,如果没有指定则使用这个配置 -->
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcStudy</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="acquirIncrement">5</property>>
<property name="initialPoolSize">10</property>
<property name="maxPoolSize">20</property>
<property name="minPoolSize">5</property>
</default-config>
<!-- 命名的配置,可以通过方法调用实现 -->
<named-config name="Mysql">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcStudy</property>
<property name="user">root</property>
<property name="password">123456</property>
<!-- 如果池中数据连接不够时一次增长多少个 -->
<property name="acquireIncrement">5</property>
<!-- 初始化数据库连接池时连接的数量 -->
<property name="initialPoolSize">10</property>
<!-- 数据库连接池中的最大的数据库连接数 -->
<property name="maxPoolSize">25</property>
<!-- 数据库连接池中的最小的数据库连接数 -->
<property name="minPoolSize">5</property>
</named-config>
</c3p0-config>
创建C3P0工具类
package com.zr.lesson05;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class JdbcUtils_C3P0 {
private static ComboPooledDataSource dataSource = null;
static{
try{
/*//代码配置
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 con, Statement st, ResultSet rs){
if (con!=null){
try {
con.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (st!=null){
try {
con.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (rs!=null){
try {
con.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
测试插入代码
package com.zr.lesson05;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
public class TestC3P0 {
public static void main(String[] args) throws SQLException {
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
con = JdbcUtils_C3P0.getConnection();
//区别
String sql = "insert into users values(?,?,?,?,?)";//使用?占位符 代替参数
ps = con.prepareStatement(sql);//预编译 先写sql 然后不执行
//手动给参数赋值
ps.setInt(1, 6);
ps.setString(2, "李白");
ps.setString(3, "123333");
ps.setString(4, "813794474@qq.com");
//sql.Date 数据库 java.sql.date()
//util.Date Java new date().gettime() 获得时间戳
ps.setDate(5, new java.sql.Date(new Date().getTime()));
//执行
int i = ps.executeUpdate();
if (i > 0) {
System.out.println("插入成功!");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
JdbcUtils_C3P0.release(con, ps, rs);
}
}
}
结论:无论使用什么数据源,本质还是一样的,DataSource不变,方法就不会变。
MySql学习笔记--详细整理--下的更多相关文章
- MySql学习笔记--详细整理--上
目录 MySql MySql安装 连接数据库 操作数据库 数据库的列类型 数据库的字段属性 创建数据库 修改删除表 数据管理 外键 DML语言 添加 修改 删除 DQL查询数据(重点) 查询 去重 w ...
- mysql学习笔记(window下简单使用+Navict)
之前安装过mysql.最近刚好要重新翻出来看看 发现又忘记了那些命令.还是要百度.所以不如自己整理下 尽管网上有很多相关的介绍.当时想对的不如自己整理出来的舒服 首先是下载安装.网上有很多就不一一罗列 ...
- mysql学习笔记(Centos下rpm编译配置+远程访问)
新工作以来,博主感觉天天都很忙,博客已经好久没有写了 从昨天开始弄centos服务器中搭建mysql5.6,由于yum最新版本只有5.1的所以折腾到现在 首先看看是否已安装过其他版本的mysql [r ...
- mysql basic operation,mysql总结,对mysql经常使用语句的详细总结,MySQL学习笔记
mysql> select * from wifi_data where dev_id like "0023-AABBCCCCBBAA" ; 1.显示数据库列表.show d ...
- 【mysql学习笔记整理】
/*mysql学习笔记整理*/ /*常用的数据库操作对象*/ #库的操作#创建#数据库的创建USE mysql;CREATE DATABASE db_x;#删除#删除数据库DROP DATABASE ...
- 一千行MySQL学习笔记 (转)
出处: 一千行MySQL学习笔记 /* 启动MySQL */ net start mysql /* 连接与断开服务器 */ mysql -h 地址 -P 端口 -u 用户名 -p 密码 /* 跳过权 ...
- Mysql学习笔记(三)对表数据的增删改查。
正文内容. 这一部分是最简单的,也是最麻烦的.简单是因为其实只包括增删该插四个部分.大体上看,增加数据.删除数据.修改数据.查询数据都不麻烦啊,我们日常都是常用的.这个谁不会呢?以前在培训机构学mys ...
- MySQL学习笔记-数据库文件
数据库文件 MySQL主要文件类型有如下几种 参数文件:my.cnf--MySQL实例启动的时候在哪里可以找到数据库文件,并且指定某些初始化参数,这些参数定义了某种内存结构的大小等设置,还介绍了参数类 ...
- 数据库MySQL学习笔记高级篇
数据库MySQL学习笔记高级篇 写在前面 学习链接:数据库 MySQL 视频教程全集 1. mysql的架构介绍 mysql简介 概述 高级Mysql 完整的mysql优化需要很深的功底,大公司甚至有 ...
随机推荐
- [SuProxy]Ngnix+Lua 实现SSH2,LDAP,ORACLE,SQLSERVER等TCP/IP协议分析,劫持,代理,会话及负载
目录 目录 目录 前言 介绍 安装 下载并拷贝 使用LuaRocks安装 运行测试 使用简介 处理器(processor)创建 通道(channel)创建 负载均衡 会话信息和会话管理 Event H ...
- D. Design Tutorial: Inverse the Problem 解析含快速解法(MST、LCA、思維)
Codeforce 472D Design Tutorial: Inverse the Problem 解析含快速解法(MST.LCA.思維) 今天我們來看看CF472D 題目連結 題目 給你一個\( ...
- C# 实现十六进制Unicode编码字符串转换为汉字
网上找了几个方法,但是运行之后会报错,提示要解析的字符串格式不正确.然后我猜想可能是传入的字符串 \u60a8\u4eca\u65e5\u5df2\u7b7e\u5230 中带"\" ...
- RS485转以太网的概述和应用领域
如今随着物联网技术的不断发展,各种接口更新换代的速度非常的快,RS485转以太网的主要作用就是提供串口转TCP/IP网络接口的功能,它可以将RS232/485/422串口转换成TCP/IP网络接口,实 ...
- Java学习的第二十九天
1. 如果类中的某个属性不希望被序列化则需要transient关键字 序列化一组对象 2.无问题 3.明天学习打印流
- TCP连接性能指标之TCP关闭过程(四次挥手)
TCP关闭过程(四次挥手): ESTABLISHED: 当前建立连接状态 CLOSE_WAIT:Server端收到来自Client端的FIN包后,发送ACK回Client端,进入CLOSE_WAIT ...
- C#+Arduino Uno 实现声控系统完全实施手册
话不多说先上视频,一看就懂 另外可参考这里:https://www.cnblogs.com/dehai/p/4285749.html ,这个近6年前的帖子 程序结构 程序分成上位机(PC端)与下位机( ...
- Charles使用part1——基本功能介绍
一. 安装与破解: 官网地址:https://www.charlesproxy.com/download/ 破解自行解决. 二. 启动与配置: 启动 Charles 后,第一次 Charles 会请求 ...
- P6064 [USACO05JAN]Naptime G
最近做了多少道 usaco 了,连 FJ 都认识我了呀 题意描述 传送门 给你 \(N\) 段时间其中 \(B\) 段时间你要用来睡眠,再给你每个时间睡眠可获得的效用值 \(U_i\). 可惜的是你每 ...
- 超实用的14个 Spring MVC “隐藏”技巧,用了都说好!
通常,在Spring MVC中,我们编写一个控制器类来处理来自客户端的请求.然后,控制器调用业务类来处理与业务相关的任务,然后将客户端重定向到逻辑视图名称,该名称由Spring的调度程序Servlet ...