AI智能
改变未来

MySql学习笔记–详细整理–下

[toc]

索引

MySQL官方对索引的定义为:索引(index)是帮助MySQL高效获取数据的的数据结构,提取句子主干,就可以得到作用的本质,索引是数据结构。

索引的分类

  • 主键索引:PRIMARY KEY唯一的标识,主键不可重复,只能由一个列作为索引
  • 唯一索引:UNIQUE KEY
      避免重复的列出现,唯一索引可以重复,多个列都可以标识为唯一索引
  • 常规索引:KEY/INDEX
      默认的,index,key关键字设置
  • 全文索引:FullText
      在特定的数据库引擎下才有
    • 快速定位数据

    基础语法

    --索引的使用--在创建表的时候给字段增加索引 或创建完表后增加USE schoolSHOW 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 INTBEGINDECLARE num INT DEFAULT 1000000;DECLARE i INT DEFAULT 0;WHILE i<num DOINSERT 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 -p123456use 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");//用户信息和UrlString 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();//执行sqlString 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(); //查询操作返回 resultsetstatement.executeUpdate(); //更新,插入,删除都用这个,返回一个受影响的行数statement.execute(); //执行任何sqlresultset 查询的结果集,封装了所有的查询结果集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.Driverurl=jdbc:mysql://localhost:3306/jdbcStudy?useunicode=true&characterEncoding=utf8&useSSL=falseusername=rootpassword=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);//执行sqlif (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只能查出一条数据  这里查询所有用户信息使用whilewhile (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只能查出一条数据  这里查询所有用户信息使用whilewhile (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.Driverurl=jdbc:mysql://localhost:3306/jdbcStudy?useunicode=true&characterEncoding=utf8&useSSL=falseusername=rootpassword=123456#初始化连接initialSize=10#最大连接数量maxActive=50#最大空闲连接maxIdle=20#超时等待时间 毫秒maxWait=60000connectionProperties=useUnicode=true;characterEncoding=utf8defaultAutoCommit=truedefaultReadOnly=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不变,方法就不会变。

  • 赞(0) 打赏
    未经允许不得转载:爱站程序员基地 » MySql学习笔记–详细整理–下