MySQL安装+基本的增删改查+JDBC的介绍和使用_20211220

MySQL

一. 安装教程
1. 安装建议: 
	1.1 尽量不要使用exe安装.(因为卸载麻烦, 安装数据会进入注册表).
	1.2 尽量使用压缩包安装.(卸载时把压缩包删除即可).

2. mySql 5.7(64位下载地址): https://dev.mysq.com/get/Downloads/MySQL-5.7/mysql-5.7.19-winx64.zip
------------------------------------------------------------------------------------
    
3.安装mysql5过程(同时安装58, 实测成功⭐⭐): 
/* 参考:推荐Win下同时安装MySQL5和MySQL8并存⭐(安装两个mysql需不同命名->mysqld -install [命名]): https://blog.csdn.net/qq_32793985/article/details/105807328  */
 -> 3.1 解压, 放在电脑的某个目录下.
 -> 3.2 设置环境变量(path中添加: D:\MyDevTools\Mysql5\mysql-5.7.19\bin, 就是bin所在的地址).
 -> 3.3 新建mysql配置文件my.ini, 文件内容如下:
     	[mysqld]
        # 设置mysql的安装目录
        basedir=D:\MyDevTools\Mysql5\mysql-5.7.19\
        # 设置mysql数据库的数据的存放目录
        datadir=D:\MyDevTools\Mysql5\mysql-5.7.19\data\
        # 设置3305端口
        port=3305
        # 跳过密码验证
        # skip-grant-tables
-> 3.4 启动管理员模式下的cmd,并将路径切换至mysql下的bin目录,执行初始化命令:mysqld --initialize --console;  (注意这里会生成一串随机密码,一定要记住!)
-> 3.5 执行数据库安装命令: mysqld --install MYSQL5; 
(注意这里安装的时候端口是3305, 名称是MYSQL5,如果直接使用mysqld --install则默认名称为mysql. )
-> 3.6 然后启动mysql服务(启动命令: net start MYSQL5), 
	   然后登录输入命令:mysql -u root -P 3305 -h localhost -p
       (-p 后直接确定, 然后输入密码, 就是上面获取的随机密码).
-> 3.7 进入界面后更改root密码:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '密码';
-> 3.8 最后输入 flush privileges; 刷新权限[注意mysql命令后的分号不要漏掉.]
-> 3.9 显示当前存在的数据库: show databases;  退出: exit;
------------------------------------------------------------------------------------
    
4.安装mysql8过程: 
 -> 4.1解压, 放在电脑的某个目录下.
 -> 4.2设置环境变量(path中添加: D:\MyDevTools\Mysql5\mysql-5.7.19\bin, 就是bin所在的目录).
 -> 4.3新建mysql配置文件my.ini, 文件内容如下:
            [mysql]
            # 设置mysql客户端默认字符集
            default-character-set=utf8
            [mysqld]
            # 设置3306端口
            port = 3306
            # 设置mysql的安装目录
            basedir = D:\\MyDevTools\\Mysql8\\mysql-8.0.22-winx64\\
            # 设置mysql数据库的数据的存放目录
            datadir = D:\\MyDevTools\\Mysql8\\mysql-8.0.22-winx64\\data
            # 允许最大连接数
            max_connections=20
            # 服务端使用的字符集默认为8比特编码的latin1字符集
            character-set-server=utf8
            # 创建新表时将使用的默认存储引擎
            default-storage-engine=INNODB
            # 创建模式
            sql_mode = NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
 -> 4.4 启动管理员模式下的cmd, 并将路径切换至mysql下的bin目录, 执行初始化命令:mysqld --initialize --console(注意这里会生成一串随机密码,一定要记住!)
 -> 4.5 执行安装命令:  mysqld --install
 -> 4.6 启动mysql服务: net start mysql
 -> 4.7 mysql用户登录: mysql -u root -p, 然后输入上面获取的随机密码.
 -> 4.8 修改密码: ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '密码';
 -> 4.9 刷新权限: flush privileges; 
 -> 4.10 显示当前存在的数据库: show databases;  退出: exit;
/* 【问题1】安装MySql时出现: The service already exists! The current server installed;
   【解决方法】1.管理员运行CMD;    2.执行sc query mysql;   3.执行sc delete mysql;
   
   【问题2】安装MySql时出现: [SC] DeleteService 失败 1072:  指定的服务已标记为删除。
   【解决方法】打开任务管理器, 把MySQL进程停止, 并且关闭任务管理器的界面!!!  */
------------------------------------------------------------------------------------
    
5.安装NavicatSQLyog来操作数据库(参考链接: https://blog.csdn.net/liangllhahaha/article/details/89508826);

初级教程
二、数据值和列类型
数值类型字符串类型日期和时间型数值类型
tinyint1字节char[(M)]M字符dateYYYY-MM-DD
smallint2字节varchar[(M)]可变长度timehh:mm:ss
mediumint3字节tinytext2^8-1字节datetimeYYYY-…:mm:ss
int4字节text2^16-1字节timestamp时间戳(毫秒)
bigint8字节yearYYYY
float4字节--------------------------------------------------------------
double8字节NULL值
decimal[(m, d)]m个字节“没有值” 或 “未知值”别用于算术运算!
  • 数据字段属性(常见的⭐⭐)
1.UnSigned  //无符号的, 声明该数据列不允许负数.
2.ZEROFILL  //0填充的, 不足位数的用0来填充 , 如int(3),5则为005
3.Auto_InCrement  
/* 1. 自动增长的, 每添加一条数据, 自动在上一个记录数上加 1(默认), 
   2. 通常用于设置主键, 且为整数类型
   3. 可定义起始值和步长:
当前表设置步长(AUTO_INCREMENT=100) : 只影响当前表
SET @@auto_increment_increment=5 ; 影响所有使用自增的表(全局)  */ 
4.NULL 和 NOT NULL  //默认为NULL, 即没有插入该列的数值.  如果设置为NOT NULL , 则该列必须有值
5.DEFAULT  //默认的, 用于设置默认值.

    
/*每一个表,都必须存在以下五个字段!未来做项目用的, 表示一个记录存在的意义! (阿里巴巴规范)
id 主键
`version` 乐观锁
is _delete 伪删除
gmt_create 创建时间
gmt_update 修改时间*/

三、一些最重要的 SQL 命令
  • 3.1 结构化查询语句分类
名称解释命令
DDL (数据定义语言)定义和管理数据对象,如数据库,数据表等CREATE、DROP、ALTER
DML (数据操作语言⭐)用于操作数据库对象中所包含的数据INSERT、UPDATE、DELETE
DQL (数据查询语言⭐)用于查询数据库数据SELECT
DCL (数据控制语言)用于管理数据库的语言,包括管理权限及数据更改GRANT、commit、rollback

注意: 反引号是用于区别MySQL保留字与普通字符而引入的 (键盘esc下面的键, 注意区别``和’’).

  • DDL_数据库和表的操作 (了解!)

    1.数据库的操作_查改增删
    -- 1.1 查询所有数据库
    show databases;
    -- 1.2 创建新数据库
    CREATE DATABASE [if not exists] 数据库名;
    -- 1.3 删除数据库
    DROP DATABASE [if exists] 数据库名;
    -- 使用数据库
    use `数据库名`;
    
    
    2.数据库表的操作
    -- 2.1 创建表
    create table [if not exists] `表名`(
      '字段名1' 列类型 [属性][索引][注释],
      '字段名2' 列类型 [属性][索引][注释],
      '...',
      '字段名n' 列类型 [属性][索引][注释]
    )[表类型][表字符集][注释];
    -- 2.2 改变数据库表
    修改表名 : ALTER TABLE 旧表名 RENAME AS 新表名
    添加字段 : ALTER TABLE 表名 ADD 字段名 列属性[属性]
    修改字段 : ALTER TABLE 表名 MODIFY 字段名 列类型[属性]
    		  ALTER TABLE 表名 CHANGE 旧字段名 新字段名 列属性[属性]
    删除字段 : ALTER TABLE 表名 DROP 字段名
    -- 2.3 删除表 
    DROP TABLE [IF EXISTS] 表名
    
    
    3.外键(了解即可)
    因为阿里说:【强制】不得使用外键与级联,一切外键概念必须在应用层解决.
             【理由】每次做DELETE 或者UPDATE都必须考虑外键约束,会导致开发的时候很痛苦,测试数据极为不方便。
    
  • DML_数据的改增删操作(⭐)

    -- 1. UPDATE: 更新数据库中的数据 (后面一定要接where条件,否则后果很严重!)
    UPDATE 表名
    SET column1=value1,column2=value2,... WHERE [条件:some_column=some_value];
    
    -- 2. INSERT INTO: 向数据库中插入新数据
    INSERT INTO 表名 (字段1,字段2,字段3,...)
    VALUES (value1,value2,value3,...);
    
    -- 3.1 DELETE: 从数据库中删除数据 (后面一定要接where条件,否则后果很严重!)
    DELETE FROM 表名 WHERE [条件:some_column=some_value];
    -- 3.2 TRUNCATE: 删除数据库表数据
    TRUNCATE TABLE '表名'
    -- 1.结论: truncate删除数据, 自增当前值会恢复到初始值重新开始; 不会记录日志.
    -- 2.同样使用DELETE清空不同引擎的数据库表数据.重启数据库服务后: 
    -- InnoDB : 自增列从初始值重新开始 (因为是存储在内存中,断电即失)
    -- MyISAM : 自增列依然从上一个自增数据基础上开始 (存在文件中,不会丢失)
    
  • DQL( Data Query Language )_数据的查操作(最重要⭐⭐)

    • SELECT语法结构:

      -- (注意 : [ ] 括号代表可选的 , { }括号代表必选得.)
      SELECT [ALL | DISTINCT]
      {* | table.* | [table.field1[as alias1][,table.field2[as alias2]][,...]]}
      FROM table_name [as table_alias]
        [left | right | inner join table_name2]  -- 联合查询
        [WHERE ...]  -- 指定结果需满足的条件
        [GROUP BY ...]  -- 指定结果按照哪几个字段来分组
        [HAVING]  -- 过滤分组的记录必须满足的次要条件
        [ORDER BY ...]  -- 指定查询记录按一个或多个条件排序
        [LIMIT {[offset,]row_count | row_countOFFSET offset}];
        -- 指定查询的记录从哪条至哪条
      
    -- 1.1 SELECT: 从数据库中提取数据
    SELECT 字段1,字段2,... FROM 表名;
    
    
    -- 2.常用语法
    -- 常用运算符一: =, <>或!=, >和<, >=和<=, between, and, or
    UPDATE grade SET gradename = '高中' WHERE gradeid = 1; -- 修改年级信息
    -- 常用运算符二: and[&&], or[||], not[!]
    SELECT studentno,studentresult
    FROM result
    WHERE NOT studentno=1000;
    -- 常用运算符三: as(可以为字段或表取别名), 
    SELECT studentno AS 学号,studentname AS 姓名 FROM student AS s;
    -- distinct([了解]去除重复的数据,默认是ALL).
    SELECT DISTINCT studentno FROM result;
    
    
    -- 3.1模糊查询一: like, %[代表0到任意个字符], _[一个字符]
    SELECT studentno,studentname 
    FROM student
    WHERE studentname LIKE '刘_'; -- 查询姓刘的同学,后面只有一个字的.
    -- 3.2模糊查询一: is null,  is not null,  between,  in
    SELECT studentno,studentname 
    FROM student
    WHERE studentno IN (1000,1001,1002); -- 查询学号为1000,1001,1002的学生姓名
    
    
    -- 4. 联表查询
    LEFT JOIN: [左外连接,左表为主表.]即使右表中没有匹配,也从左表中返回所有的行.
    RIGHT JOIN: [右外连接,右表为主表.]即使左表中没有匹配,也从右表中返回所有的行.
    INNER JOIN: [内连接]如果表中有至少一个匹配,则返回行.
    自连接(了解)
    -- on和wehere的使用: 
    -- join [表名] on [判断条件];   =>连接查询(一般用了join则使用on),  
    -- where [条件可以使具体的值或子查询语句]  =>等值查询
    
    -- 5.1 分页: limit [a[, b]]
    -- 在limit中, a=(n-1)*pageSize, b=pageSize(页面大小),
    -- 前端数据->后端: n为当前页码;  
    -- 后端数据->前端: pageSize;  dataTotal为数据记录总数;  pageTotal=dataTotal/pageSize;
    select studentno,studentname from student limit 0,5;
    
    -- 5.2 分组和排序: 
    -- group by 字段名;  
    -- order by 字段名 asc(升序)/desc(降序)
    -- having  (=>过滤分组后的信息, 条件和where是一样的, 位置不同.)
    SELECT Studentno,StudentResult
    FROM result 
    ORDER BY StudentResult desc
    
    -- 6.子查询和嵌套
    -- 在上面SQL基础上,添加需求:课程为 高等数学-2
    SELECT r.studentno,studentname FROM student s
    INNER JOIN result r ON s.`StudentNo`=r.`StudentNo`
    WHERE StudentResult>=80 AND subjectno=(
      SELECT subjectno FROM `subject`
      WHERE subjectname = '高等数学-2'
    )
    -- 使用子查询 -> 分步写简单sql语句,然后将其嵌套起来
    SELECT studentno,studentname FROM student WHERE studentno IN(
      SELECT studentno FROM result WHERE StudentResult>=80 AND subjectno=(
        SELECT subjectno FROM `subject` WHERE subjectname = '高等数学-2'
     )
    )
    
    -- 7.1 聚合函数(重要⭐)
    COUNT() -- 返回满足Select条件的记录总和数,如 select count(*) 【不建议使用 *,效率低】.
    SUM() -- 返回数字字段或表达式列作统计,返回一列的总和。
    AVG() -- 通常为数值字段或表达列作统计,返回一列的平均值
    MAX() -- 可以为数值字段,字符字段或表达式列作统计,返回最大的值。
    MIN() -- 可以为数值字段,字符字段或表达式列作统计,返回最小的值。
    SELECT COUNT(studentname) FROM student;
    SELECT COUNT(*) FROM student;
    SELECT COUNT(1) FROM student;  /*推荐*/
    
    
    -- 7.2 MYSQL常用函数(了解部分):
    -- 数据函数
    SELECT ABS(-8);  /*绝对值*/
    SELECT CEILING(9.4); /*向上取整*/
    SELECT FLOOR(9.4);  /*向下取整*/
    SELECT RAND();  /*随机数,返回一个0-1之间的随机数*/
    SELECT SIGN(0); /*符号函数: 负数返回-1,正数返回1,0返回0*/
    
    -- 日期和时间函数⭐
    SELECT CURRENT_DATE();  /*获取当前日期: 2021-12-02*/
    SELECT CURDATE();  /*获取当前日期: 2021-12-02*/
    SELECT NOW();  /*获取当前日期和时间: 2021-12-02 01:16:33*/
    SELECT LOCALTIME();  /*获取(本地)当前日期和时间: 2021-12-02 01:17:00*/
    SELECT SYSDATE();  /*获取(系统)当前日期和时间: 2021-12-02 01:17:25*/
    -- 获取年月日,时分秒
    SELECT YEAR(NOW());
    SELECT MONTH(NOW());
    SELECT DAY(NOW());
    SELECT HOUR(NOW());
    SELECT MINUTE(NOW());
    SELECT SECOND(NOW());
    
    -- 系统信息函数
    SELECT VERSION();  /*版本*/
    SELECT USER();   /*用户*/
    
    -- CONCAT()函数: 拼接字符串
    SELECT CONCAT('姓名:',studentname) AS 新姓名 FROM student;
    
    
    -- 8. MD5加密函数-> MD5(str)
    insert into `testmd5` (`id`, `name`, `pwd`) values(5,'xiao',MD5('123456'));
    
四.事务
  • 什么是事务?
    • 事务就是将一组SQL语句放在同一批次内去执行.
    • 如果一个SQL语句出错,则该批次内的所有SQL都将被取消执行.
    • MySQL事务处理只支持InnoDB和BDB数据表类型.
事务的ACID原则:  
-- 1.原子性(Atomic)
    整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。
    //事务在执行过程中发生错误,会被回滚(ROLLBACK)到事务开始前的状态,就像这个事务从来没有执行过一样。
    
-- 2.一致性(Consist)
    一个事务可以封装状态改变(除非它是一个只读的)//事务必须始终保持系统处于一致的状态,不管在任何给定的时间并发事务有多少。也就是说:如果事务是并发多个,系统也必须如同串行事务一样操作。其主要特征是保护性和不变性(Preserving an Invariant),以转账案例为例,假设有五个账户,每个账户余额是100元,那么五个账户总额是500元,如果在这个5个账户之间同时发生多个转账,无论并发多少个,比如在A与B账户之间转账5元,在C与D账户之间转账10元,在B与E之间转账15元,五个账户总额也应该还是500元,这就是保护性和不变性。
    
-- 3.隔离性(Isolated)
    隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。
    //如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据。
    
-- 4.持久性(Durable)
    在事务完成以后,该事务对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
  • 转账案例

    /* 课堂测试题目: 
    A在线买一款价格为500元商品,网上银行转账.
    A的银行卡余额为2000,然后给商家B支付500. 
    商家B一开始的银行卡余额为10000.
    创建数据库shop和创建表account并插入2条数据.  */
    CREATE DATABASE `shop`CHARACTER SET utf8 COLLATE utf8_general_ci;
    USE `shop`;
    CREATE TABLE `account` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(32) NOT NULL,
        `cash` DECIMAL(9,2) NOT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=INNODB DEFAULT CHARSET=utf8
    
    INSERT INTO account (`name`,`cash`) VALUES('A',2000.00),('B',10000.00);
    
    -- 转账实现
    SET autocommit = 0; -- 关闭自动提交
    START TRANSACTION;  -- 开始一个事务,标记事务的起始点
    ----------------------- 一组sql ---------------------------
    UPDATE account SET cash=cash-500 WHERE `name`='A';
    UPDATE account SET cash=cash+500 WHERE `name`='B';
    ----------------------------------------------------------
    COMMIT; -- 提交事务
    rollback; -- 回滚
    SET autocommit = 1; -- 恢复自动提交
    
五.索引

注意: 复制狂神笔记中的SQL语句来执行时, 如果执行不成功 => 其实是换行的地方复制了一些看不见的字符, 需要把"换行的地方"都先删除连接头尾文字, 再手动敲过换行即可;

1.索引准则
索引不是越多越好
不要对经常变动的数据加索引
小数据量的表建议不要加索引
索引一般应加在查找条件的字段

2.索引操作
-- 创建索引(搜索键)
CREATE INDEX
-- 删除索引
DROP INDEX
六.MySQL权限管理与备份
6.1 权限管理
略
    
6.2 数据库备份
Navicat -> 转储SQL文件(可以选择导出仅结构 或 数据和结构;)

七.数据库设计与实现

注意:

MySql数据库中不区分大小写, 所以不会使用驼峰命名, 二是使用下划线来分割, 比如user_name;

7.1 三大范式
数据库范式分为1NF,2NF,3NF,BCNF,4NF,5NF一般我们在设计数据库结构的时候最多只要满足到BCNF就可以
了。符合高一级的范式必定符合低一级的范式。

第一范式(1NF): 字段是最小的的单元不可再分;
第二范式(2NF): 满足1NF,表中的字段必须完全依赖于全部主键而非部分主键 (必须完全依赖, 一般我们都会做到);
第三范式(3NF): 满足2NF,非主键外的所有字段必须互不依赖(排除传递函数依赖);

/* 注意:
1.为满足某种商业目标 , 数据库性能比规范化数据库更重要;
2.在数据规范化的同时 , 要综合考虑数据库的性能;
3.通过在给定的表中添加额外的字段,以大量减少需要从中搜索信息所需的时间;
4.通过在给定的表中插入计算列,以方便查询;
*/
八.数据库原生连接和JDBC
  • JDBC介绍

    1.JDBC是什么: SUN公司为了简化、统一对数据库的操作,定义了一套Java操作数据库的规范(接口),称之为JDBC。
    1.1 JDBC全称为:Java Data Base Connectivity(java数据库连接),它主要由接口组成。
    1.2 使用前的环境准备:
        -- 组成JDBC的2个包:java.sql、javax.sql;
    	-- 发JDBC应用需要以上2个包的支持外,还需要导入相应JDBC的数据库实现(即数据库驱动,如mysql-connector-java-5.1.47.jar);
    
    // JDBC的使用: ①加载数据库驱动程序[Class.forName()]-> ②获取数据库连接[DriverManager类]-> ③向数据库发送sql语句[Statement类]-> ④处理数据库返回结果[ResultSet] ->⑤释放资源
    2.JDBC对象说明;
    2.1 DriverManager;
    //首先-> Class.forName加载完驱动类: Class.forName("com.mysql.jdbc.Driver");;
    Jdbc程序中的DriverManager用于加载驱动,并创建与数据库的链接,这个API的常用方法:
    -- DriverManager.registerDriver(new Driver());//不推荐使用;
    -- DriverManager.getConnection(url, user, password);//推荐
    
    2.2 Connection;
    //Jdbc程序中的Connection,它用于代表数据库的链接; 客户端与数据库所有交互都是通过connection对象完成的,这个对象的常用方法:
    createStatement(): 创建向数据库发送sql的statement对象;
    prepareStatement(sql): 创建向数据库发送预编译sql的PrepareSatement对象;
    setAutoCommit(boolean autoCommit): 设置事务是否自动提交;
    commit(): 在链接上提交事务;
    rollback(): 在此链接上回滚事务;
        
    2.3 Statement;(次要, 使用该类可能被sql注入)
    //Jdbc程序中的Statement对象用于向数据库发送SQL语句, Statement对象常用方法:
    executeQuery(String sql) :用于向数据发送查询语句;
    executeUpdate(String sql):用于向数据库发送insert、update或delete语句;
    execute(String sql):用于向数据库发送任意sql语句;
    addBatch(String sql) :把多条sql语句放到一个批处理中;
    executeBatch():向数据库发送一批sql语句执行;
    
    2.4 PrepareSatement;(重要, 使用该类可以防止sql注入)
    -- PreperedStatementStatement的子类,可以避免SQL注入的问题;
    -- Statement会使数据库频繁编译SQL,可能造成数据库缓冲区溢出。PreparedStatement可对SQL进行预编译,从而提高数据库的执行效率。并且PreperedStatement对于sql中的参数,允许使用占位符的形式进行替换,简化sql语句的编写。
    
    2.5 ResultSet;
    //Jdbc程序中的ResultSet用于代表Sql语句的执行结果。Resultset封装执行结果时,采用的类似于表格的方式。ResultSet 对象维护了一个指向表格数据行的游标,初始的时候,游标在第一行之前,调用ResultSet.next()方法,可以使游标指向具体的数据行,进行调用方法获取该行的数据。
    ResultSet既然用于封装执行结果的,所以该对象提供的都是用于获取数据的get方法:
    -- 获取任意类型的数据: 
    getObject(int index);
    getObject(string columnName);
    -- 获取指定类型的数据,例如: 
    getString(int index);
    getString(String columnName);
    -- ResultSet还提供了对结果集进行滚动的方法: 
    next():移动到下一行;
    Previous():移动到前一行;
    absolute(int row):移动到指定行;
    beforeFirst():移动resultSet的最前面;
    afterLast() :移动到resultSet的最后面;
    
    2.6 **释放资源**:
       -- Jdbc程序运行完后,切记要释放程序在运行过程中,创建的那些与数据库进行交互的对象,这些对象通常是ResultSet, StatementConnection对象,特别是Connection对象,它是非常稀有的资源,用完后
    必须马上释放,如果Connection不能及时、正确的关闭,极易导致系统宕机。
       -- Connection的使用原则是尽量晚创建,尽量早的释放。为确保资源释放代码能运行,资源释放代码也一定要放在finally语句中。
    
  • 使用JDBC连接数据库

    //步骤1: 创建文件jdbc.properties;
    driver=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3305/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true
    username=root
    password=root
    //------------------------------------------------------------------------------
    //步骤2: 创建工具类utils:;
    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();
            }
        }
    
    
        /**
         * 返回一个数据库连接
         * @return
         * @throws SQLException
         */
        public static Connection getConnection() throws SQLException {
            return DriverManager.getConnection(url,username,password);
        }
    
        /**
         * 释放连接资源
         * @param con
         * @param st
         * @param rs
         */
        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 {
                    st.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if (rs != null){
                try {
                    rs.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
    }
    
    //------------------------------------------------------------------------------
    //步骤3: 增删改查的实现
    //查询实现
    public class TestSelect {
        public static void main(String[] args) {
            Connection con = null;
            PreparedStatement st = null;
            ResultSet rs = null;
            try {
                con = JdbcUtils.getConnection();
                String sql = "select * from jdbcstudy.users where id=?";
                st = con.prepareStatement(sql);
                st.setInt(1,3);
                rs = st.executeQuery();
                if (rs.next()) {
                    System.out.println("id="+rs.getObject("id"));
                    System.out.println("NAME="+rs.getObject("NAME"));
                    System.out.println("PASSWORD="+rs.getObject("PASSWORD"));
                    System.out.println("email="+rs.getObject("email"));
                    System.out.println("birthday="+rs.getObject("birthday"));
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                JdbcUtils.release(con,st,rs);
            }
        }
    }
    
    //增加实现
    public class TestInsert {
        public static void main(String[] args) {
            Connection con = null;
            PreparedStatement st = null;
            try {
                con = JdbcUtils.getConnection();
                // 使用? 占位符代替参数
                String sql = "insert into jdbcstudy.users(id,`NAME`,`PASSWORD`,`email`,`birthday`) values(?,?,?,?,?)";
                // 预编译sql, 先写sql, 然后不执行
                st = con.prepareStatement(sql);
                // 手动给参数赋值
                st.setInt(1,5);
                st.setString(2,"xiaoming");
                st.setString(3,"123456");
                st.setString(4,"123456@qq.com");
                // 注意点: 数据库用java.sql.Date; Java使用java.util.Date;
                st.setDate(5,new java.sql.Date(new Date().getTime()));
                // 执行
                int num = st.executeUpdate();
                if (num > 0){
                    System.out.println("插入成功!");
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                JdbcUtils.release(con,st,null);
            }
        }
    }
    
九.数据常用连接池
  • 1.连接池

    1.dbcp_数据库连接池;
    ->1.1 需要的jar文件: 
    Commons-dbcp.jar:连接池的实现;
    Commons-pool.jar:连接池实现的依赖库;
    //(Tomcat 的连接池正是采用该连接池来实现的。该数据库连接池既可以与应用服务器整合使用,也可由应用程序独立使用)
        
    2.c3p0_数据库连接池:
    2.1 需要的jar文件:
    c3p0.jar;
    mchange-commons-java.jar;
    //c3p0与dbcp区别: dbcp没有自动回收空闲连接的功能, c3p0有自动回收空闲连接功能;
    
    3.druid_数据库连接池(阿里巴巴);
    
    /* 连接池常用概念:
    最小连接数,
    最大连接数,
    */
    

    注意:

    1.编写连接池需实现java.sql.DataSource接口;

  • 2.连接池代码使用

    • 2.1 dbcp_数据库连接池的使用

      //步骤1: 导入相关的2个jar包 -> 加入dbcp的配置文件dbcpconfig.properties
      #连接设置
      driverClassName=com.mysql.jdbc.Driver
      url=jdbc:mysql://localhost:3305/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true
      username=root
      password=root
      
      #<!-- 初始化连接 -->
      initialSize=10
      #最大连接数量
      maxActive=50
      #<!-- 最大空闲连接 -->
      maxIdle=20
      #<!-- 最小空闲连接 -->
      minIdle=5
      #<!-- 超时等待时间以毫JdbcUtils秒为单位 6000毫秒/1000等于60-->
      maxWait=60000
      #JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;]
      #注意:"user""password" 两个属性会被明确地传递,因此这里不需要包含他们。
      
      connectionProperties=useUnicode=true;characterEncoding=UTF8
      #指定由连接池所创建的连接的自动提交(auto-commit)状态。
      defaultAutoCommit=true
      #driver default 指定由连接池所创建的连接的只读(read-only)状态。
      #如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)
      defaultReadOnly=
      #driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
      #可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED,
      REPEATABLE_READ, SERIALIZABLE
      defaultTransactionIsolation=READ_UNCOMMITTED
      
      //-----------------------------------------------------------------------------
      //步骤2: 编写工具类
      public class JdbcUtils_DBCP {
          private static DataSource dataSource = null;
          static {
              try{
                  InputStream in = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
                  Properties properties = new Properties();
                  properties.load(in);
                  //1. 创建数据源 (工厂模式 -> 创建)
                  dataSource = BasicDataSourceFactory.createDataSource(properties);
      
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      
          /**
           * 返回一个数据库连接
           * @return
           * @throws SQLException
           */
          public static Connection getConnection() throws SQLException {
              return dataSource.getConnection();
          }
      
          /**
           * 释放连接资源
           * @param con
           * @param st
           * @param rs
           */
          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 {
                      st.close();
                  } catch (SQLException throwables) {
                      throwables.printStackTrace();
                  }
              }
              if (rs != null){
                  try {
                      rs.close();
                  } catch (SQLException throwables) {
                      throwables.printStackTrace();
                  }
              }
          }
      }
      
    • 2.2 c3p0_数据库连接池的使用

      //步骤1: 导入相关的2个jar包 -> 加入C3P0的配置文件c3p0-config.xml
      <?xml version="1.0" encoding="UTF-8"?>
      <c3p0-config>
          <!--  C3P0的缺省(默认)配置: 
      		如果在代码中“ComboPooledDataSource ds = new ComboPooledDataSource();”这样写就表示使用的是C3P0的缺省(默认)配置信息来创建数据源  -->
          <default-config>
              <property name="driverClass">com.mysql.jdbc.Driver</property>
              <property name="jdbcUrl">jdbc:mysql://localhost:3305/jdbcStudy?useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=true</property>
              <property name="user">root</property>
              <property name="password">root</property>
              <property name="acquireIncrement">5</property>
              <property name="initialPoolSize">10</property>
              <property name="minPoolSize">5</property>
              <property name="maxPoolSize">20</property>
          </default-config>
          <!--  C3P0的命名配置: 
      	如果在代码中“ComboPooledDataSource ds = new ComboPooledDataSource("MySQL");”这样写就表示使用的是name是MySQL的配置信息来创建数据源  -->
          <named-config name="MySQL5">
              <property name="driverClass">com.mysql.jdbc.Driver</property>
              <property name="jdbcUrl">jdbc:mysql://localhost:3305/jdbcStudy?useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=true</property>
              <property name="user">root</property>
              <property name="password">root</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>
      //-----------------------------------------------------------------------------
      //步骤2: 编写工具类
      public class JdbcUtils_C3P0 {
          private static ComboPooledDataSource dataSource = null;
          static {
              try{
                  //1.创建数据源
                  dataSource = new ComboPooledDataSource();//获取默认的数据源
      //            dataSource = new ComboPooledDataSource("MySQL5");//获取对应的数据源
                  //2.Java代码配置_创建数据源
                  /* dataSource.setDriverClass();
                  dataSource.setJdbcUrl();
                  dataSource.setUser();
                  dataSource.setPassword();
                  dataSource.setMinPoolSize();
                  dataSource.setMaxPoolSize(); */
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      
          /**
           * 返回一个数据库连接
           * @return
           * @throws SQLException
           */
          public static Connection getConnection() throws SQLException {
              return dataSource.getConnection();
          }
          
          /**
           * 释放连接资源
           * @param con
           * @param st
           * @param rs
           */
          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 {
                      st.close();
                  } catch (SQLException throwables) {
                      throwables.printStackTrace();
                  }
              }
              if (rs != null){
                  try {
                      rs.close();
                  } catch (SQLException throwables) {
                      throwables.printStackTrace();
                  }
              }
          }
      }
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值