如何彻底卸载MySQL
内容为:
1、控制面板里的增加删除程序内进行删除
2、删除MySQL文件夹
3、开始->运行-> regedit 看看注册表里这几个地方删除没有
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Eventlog\Application\MySQL 目录删除
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet002\Services\Eventlog\Application\MySQL 目录删除
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application\MySQL 目录删除(我卸载的时候没有找到,略过后仍达到完全卸载的目的。)
4、这一条是很关键的
C:\ProgramData\下有一个 mysql 目录 也要必须删除
注意:AC:\ProgramData这个文件夹是隐藏的,需要打开个文件夹选择菜单栏 工具→文件夹选项→查看→隐藏文件和文件夹 一项选上 显示所有文件和文件夹 确定
以上4步完成,
5.重启 OK!再次安装吧
1. 你知道的存储数据的方式有哪些?
变量, 常量, 数组, 集合:
它们只能临时存储数据, 当程序执行结束后, 数据就丢失了.
IO流:
可以实现对数据永久存储, 但是不方便用户进行精细化管理和操作.
数据库:
数据库指的就是存储数据的仓库, 其本质是一个文件系统, 可以对数据有规律的存储,
方便用户进行增删改查(CURD, Create: 增, Update: 改, Read: 读, Delete: 删).
//记忆: 数据库才是实际开发, 我们真正存储数据的地方.
2. 我们常说的数据库其实指的是数据库管理系统(DBMS: DataBase Managerment System), 那么数据库和DBMS之间有什么关系呢?
DBMS: //类似于IDEA
数据库: //类似于IDEA中的项目
数据表: //类似于项目中的类.
表数据: //类似于通过类创建的JavaBean对象
3. 常用的DBMS有哪些?
MySQL, Oracle, SQLServer, DB2, SQLite, SyBase.
4. 在window操作系统中安装MySQL
卸载: //友善提醒: 如果你的数据库需要备份, 卸载之前一定要先备份数据库.
1. 直接去控制面板卸载, 不要直接删除mysql文件夹, 因为有注册表没有直接删除.
//快速打开控制面板: window徽标键 + 字母r -> control -> 回车
2. 删除MySQL文件夹.
3. 如果你的操作系统不是纯净版的, 卸载后可能有些注册信息需要手动删除, 详见: 资料/如何彻底卸载mysql.txt
安装: //必须安装64位, 如果你的操作系统不是64位, 换系统.
1. 傻瓜式安装, 双击安装包以后, 下一步下一步即可.
2. 安装路径一定要合法:
A. 安装路径不要出现中文, 空格, 特殊符号等.
B. 最好不要直接安装到盘符目录下.
3. 具体的安装动作详见: MySQL安装图解.pdf
细节: 安装之前最好关闭你电脑的防火墙, 有些电脑不管防火墙可能装不成功.
5. MySQL如何登陆和退出:
登陆:
方式一: 明文登陆
window微标键 + 字母r -> cmd -> 回车 -> mysql -uroot -p密码 -> 回车
方式二: 暗文登陆
window微标键 + 字母r -> cmd -> 回车 -> mysql -u root -p -> 回车 -> 输入密码 -> 回车
退出:
exit
quit
登陆MySQL的时候可能会遇到的两个小问题:
1. 10061, 看到这个错误码, 一定是你的 MySQL服务没有开启, 开启它即可.
方式一: 手动开启
window微标键 + 字母r -> cmd -> 回车 ->services.msc -> 找到 mysql 服务, 然后开.
方式二: DOS指令
net start mysql服务名
2. using password yes, 看到这个错, 说明你录入的用户名或者密码不对, 正确录入即可.
6. JDBC简介
概述:
全称叫Java DataBase Connectivity(Java数据库连接), 就是通过Java语言来操作不同的数据库的技术, 本质就是一些类和接口.
//DriverManager, Connection, Statement, PreparedStatement, ResultSet, Driver
/*
集合: 就是Java语言用来存储 多个同类型数据的容器, 本质就是一些类和接口.
Collcetion, Set, List, Map, ArrayList, HashSet, HashMap
IO流: 就是Java语言用来 进行文件传输的技术, 本质就是一些类和接口.
InputStream, OutputStream, Reader, Writer, FileInputStream, BufferedInputStream, Serializable
结论: 集合的顶层都是接口, IO流的顶层都是抽象类.
*/
作用:
1. 连接数据库.
2. 向数据库发送SQL语句.
3. 接收数据库返回的执行结果, 并进行相应的处理.
驱动:
就是两个设备间进行通信的桥梁. //Java 和 MySQL之间进行交互, 也需要通过 驱动实现.
//这里的驱动指的是: 数据库厂商提供的 jar包.
原理:
专业版:
有Sun公司制定规则(就是一些类和接口), 具体的体现和实现交给: 各个数据库生产商来做.
大白话:
我们知道, Java操作MySQL需要使用MySQL提供的驱动, Java操作SQLServer数据库, 需要使用SQLServer提供的驱动, 但是我们知道,
数据库厂商不同, 提供的驱动也不尽相同, 这就要求Java程序员必须熟悉市场上常用的各个数据库的驱动的, 这样做会提高程序的
学习门槛, 因为Java本身就已经提供了好多的类和接口, 此时程序员还需要额外记忆大量的其他的类和接口, 学习难度增大, 后来
Sun公司就发现了这个问题, 于是就把各个数据库生厂商叫到一起进行协商, 决定: 由Sun公司提供统一的规则, 而具体的体现和
实现交给各个数据库厂商来实现, 这些Sun公司提供统一的规则, 就是: JDBC, 本质就是一些类和接口.
7. JDBC的入门案例
1. 准备数据库和数据表.
#创建数据库
create database day15;
#使用数据库
use day15;
#创建分类表
create table category(
cid int PRIMARY KEY AUTO_INCREMENT ,
cname varchar(20)
);
2. 添加表数据.
#初始化数据
insert into category values(null, '家电');
insert into category values(null, '服饰');
insert into category values(null, '化妆品');
3. 通过JDBC查询上述数据表中的所有数据, 并打印到控制台上.
//需要先做的事儿: 导入驱动, 即: 导入MySQL数据库厂商提供的, 针对于MySQL数据库的jar包
1. 注册驱动.
2. 获取连接对象.
3. 根据连接对象, 获取可以执行SQL语句的对象.
4. 执行SQL语句, 获取结果集.
//结果集: 就是SQL语句执行结束后, 返回的结果, 就叫: 结果集.
5. 操作结果集.
6. 释放资源.
8. JDBC涉及的API简介之 DriverManager
概述:
它是一个类 , 表示驱动管理者, 可以用来注册驱动 和 获取连接对象.
作用:
1. 注册驱动.
public static void registerDriver(new Driver());
/*
上述注册驱动的方式, 会导致MySQL驱动注册两次, 所以我们通过反射的方式加载字节码文件, 这样的话 驱动只注册一次.
案例代码如下:
Class.forName("com.mysql.jdbc.Driver");
*/
2. 获取连接对象.
public Connection getConnection(String url, String username, String password);
/*
参数解释:
参数1: 数据库连接字符串, 格式如下:
jdbc:mysql://要连接的MySQL的ip:3306/要操作的数据库的名字
jdbc:mysql://localhost:3306/day15
jdbc:mysql://127.0.0.1:3306/day15
如果操作本地数据库, 则上述的格式可以优化为: jdbc:mysql:///day15
参数2: 要连接的数据库的账号
参数3: 要连接的数据库的密码
*/
9. JDBC涉及的API简介之 Connection
概述:
它是一个接口, 表示: 连接对象(会话对象), 负责Java语言 和 数据库(例如:MySQL)之间交互的.
作用:
1. 获取可以执行SQL语句的对象.
public Statement createStatement();
//获取可以执行SQL语句的对象(Statement, 不具有预编译功能)
public PreparedStatement prepareStatement(String sql);
//获取可以执行SQL语句的对象(PreparedStatement, 具有预编译功能)
2. 可以操作事务. //目前先了解.
public void setAutoCommit(boolean flag); //设置自动提交, 相当于开启/关闭事务.
public void commit(); //提交事务
public void rollback(); //事务回滚.
public void setTransactionIsolation(int level); //设置隔离级别.
10. JDBC涉及的API简介之 Statement
概述:
它是接口, 具有执行SQL语句功能的对象, 可以执行SQL语句, 获取结果集.
作用:
1. 执行SQL语句, 获取结果.
public ResultSet executeQuery(String sql); //执行查询语句, 获取结果集.
public int executeUpdate(String sql); //执行更新语句(增删改), 获取结果集.
2. 执行批处理. //目前了解.
public void addBatch(); //添加到批处理中
public int[] executeBatch(); //执行批处理.
public void clearBatch(); //清空批处理.
11. JDBC涉及的API简介之 ResultSet
概述:
它是接口, 表示查询语句执行结束后, 返回的结果.
作用:
可以用来存储查询语句执行结束后, 返回的结果, 方便用户操作.
public boolean next(); //判断结果集中是否有下一个元素. 类似于: Iterator#hasNext();
public Xxx getXxx(String columnName); //根据列名, 获取该列的值. Xxx表示数据类型.
public Xxx getXxx(int columnNumber); //根据列的编号, 获取该列的值, Xxx表示数据类型.
12. JDBC的CURD(增删改查)操作.
1. 创建用户表users, 添加表数据.
#创建用户表
CREATE TABLE users(
uid INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(20),
PASSWORD VARCHAR(20)
);
#添加表数据
INSERT INTO users VALUES(NULL, 'admin01', 'pw111');
INSERT INTO users VALUES(NULL, 'admin02', 'pw222');
INSERT INTO users VALUES(NULL, 'admin03', 'pw333');
#查询表数据
SELECT * FROM users;
2. 通过JDBC操作users表, 进行CURD操作.
13. JDBCUtils工具类的抽取和使用.
略.
14. SQL注入攻击问题
概述:
实际开发中, 如果SQL语句的部分内容是要求用户录入的, 而用户录入某些非法字符或者我们所不希望看到的内容, 此时就有可能
改变SQL语句的判断条件, 从而引发问题, 这种情况就叫做: SQL注入攻击问题.
问题演示:
//示例: 模拟登陆的SQL语句.
select * from users where username='用户录入的账号' and password='用户录入的密码';
//此时用户录入的数据如下;
用户录入的用户名: sdlfjsldf
用户录入的密码: ' or '1=1 //此时就会发生SQL注入攻击问题.
Java代码演示SQL注入攻击问题:
SQL注入攻击问题解决: 预编译.
15. PreparedStatement预编译功能的CURD操作.
16. 数据库连接池
概述:
实际开发中, 当我们需要使用到大量生命周期短的连接对象时, 频繁的创建和销毁连接对象是非常消耗系统资源的,
针对于这种情况, 我们可以创建一个池子出来, 里边放一些连接对象, 用的时候从里边拿, 用完之后在还回去.
这个池子就叫: 数据库连接池, 这样做的目的是: 节约资源, 提高效率.
分类:
DBCP: Apache提供的, 不能自动回收空闲连接.
C3P0: Apache提供的, 能自动回收空闲连接. //只讲解这个.
//Java框架的底层如果涉及到 数据库连接池部分的内容了, 基本上用的都是: C3P0数据库连接池.
Druid: 阿里巴巴公司提供的, 采用 分布式事务思想实现.
演示C3P0的使用:
案例一: 入门案例.
步骤:
1. 复制c3p0-config.xml配置文件到当前项目(模块)的src目录下.
2. 导入c3p0数据库连接池的jar包.
3. 创建数据库连接池对象, 无需关联和指定配置文件, 因为 C3P0数据库连接池会自动加载并识别配置文件的信息.
4. 从数据库连接池对象中获取连接对象(Connection)
5. 正常的 conn.close()关闭连接对象即可, 因为连接池已经重构了 Connection#close()方法,
所以此时调用close()并不是 销毁连接对象, 而是 自动归还.
/*
弊端:
用连接池的效率还没有我们以前写的代码效率高.
原因:
因为你是每执行一次这个类, 就创建一个连接池对象, 且要填充5个连接对象,但是在这个类中,
你才用到了1个连接对象, 剩下的4个连接对象都是闲置的, 这样做肯定不行, 那如何优化呢?
解决方案:
把创建连接池对象的操作封装到工具类中, 然后在项目中需要用到连接池的地方, 直接给连接池对象即可,
只要保证整个项目(模块)共用一个连接池对象即可.
*/
案例二: C3P0Utils工具类的抽取和使用
# **************************** 以下是演示 SQL注入攻击问题 **************************** /* SQL注入攻击问题: 概述: 用户录入非法字符, 从而改变了我们SQL语句的判断条件, 引发的安全问题, 就叫SQL注入攻击问题. 示例(问题演示): 需求: 模拟用户登录. 格式: select * from users where username='用户录入的账号' and password='用户录入的密码'; 普通用户: 用户名: admin01 密码: 123 屌丝用户: 用户名: sdlfjsldf 密码: ' or '1=1 资深老屌丝: 用户名: sdlfjsldf 密码: ' or '1=1';drop database day15;' */ SELECT * FROM users WHERE username='sdlfjsldf' AND PASSWORD='' OR '1=1';DROP DATABASE day15;'';
jdbc操作MySQL
idea
1.创建一个Java项目
2.在项目下创建一个lib 或者libs文件夹存放驱动包

3.将驱动包复制进去


eclipse
同理创文件夹
复制包

package com.it.demo01_jdbc; import com.mysql.jdbc.Driver; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; /* 案例: 演示JDBC操作数据库表, 入门. */ public class Demo01_QuickStart { public static void main(String[] args) throws Exception { //需要先做的事儿: 导入驱动, 即: 导入MySQL数据库厂商提供的, 针对于MySQL数据库的jar包 //1. 注册驱动. //DriverManager.registerDriver(new Driver()); //这种方式会导致驱动注册两次, 改为通过反射实现. Class.forName("com.mysql.jdbc.Driver"); //这种方式只会注册一次驱动 //2. 获取连接对象. Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/day15", "root", "123456"); //3. 根据连接对象, 获取可以执行SQL语句的对象. Statement stat = conn.createStatement(); //4. 执行SQL语句, 获取结果集. ////结果集: 就是SQL语句执行结束后, 返回的结果, 就叫: 结果集. String sql = "SELECT * FROM category;"; ResultSet rs = stat.executeQuery(sql); while (rs.next()) { //判断是否还有下一个结果集. //从结果集在栈中获取数据. int cid = rs.getInt("cid"); //列名, 掌握 //int cid = rs.getInt(1); //列的编号, 了解 String cname = rs.getString("cname"); //5. 操作结果集. System.out.println("cid: "+ cid + ", cname: " + cname); } //6. 释放资源. rs.close(); stat.close(); conn.close(); } }
package com.it.demo01_jdbc; import org.junit.Test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; /* 案例: 操作day15数据库的 users表, 进行CURD操作. */ public class Demo02_CURD { /** * 演示JDBC之 查询数据 */ @Test public void read() throws Exception { //1. 注册驱动. Class.forName("com.mysql.jdbc.Driver"); //2. 获取连接对象. Connection conn = DriverManager.getConnection("jdbc:mysql:///day15", "root", "123"); //3. 根据连接对象, 获取可以执行SQL语句的对象. Statement stat = conn.createStatement(); //4. 执行SQL语句, 获取结果集. String sql = "select * from users;"; ResultSet rs = stat.executeQuery(sql); //5. 操作结果集. while (rs.next()) { int uid = rs.getInt("uid"); String username = rs.getString("username"); String password = rs.getString("password"); System.out.println(uid + "..." + username + "..." + password); } //6. 释放资源. rs.close(); stat.close(); conn.close(); } /** * 演示JDBC之 增加数据 */ @Test public void add() throws Exception { //1. 注册驱动. Class.forName("com.mysql.jdbc.Driver"); //2. 获取连接对象. Connection conn = DriverManager.getConnection("jdbc:mysql:///day15", "root", "123"); //3. 根据连接对象, 获取可以执行SQL语句的对象. Statement stat = conn.createStatement(); //4. 执行SQL语句, 获取结果集. String sql = "insert into users values(null, 'admin04', 'pw444');"; int num = stat.executeUpdate(sql); //5. 操作结果集. System.out.println(num > 0 ? "添加成功" : "添加失败"); //6. 释放资源. stat.close(); conn.close(); } /** * 演示JDBC之 修改数据 */ @Test public void update() throws Exception { //1. 注册驱动. Class.forName("com.mysql.jdbc.Driver"); //2. 获取连接对象. Connection conn = DriverManager.getConnection("jdbc:mysql:///day15", "root", "123"); //3. 根据连接对象, 获取可以执行SQL语句的对象. Statement stat = conn.createStatement(); //4. 执行SQL语句, 获取结果集. String sql = "update users set password='password444' where uid=4;"; int num = stat.executeUpdate(sql); //5. 操作结果集. System.out.println(num > 0 ? "修改成功" : "修改失败"); //6. 释放资源. stat.close(); conn.close(); } /** * 演示JDBC之 删除数据 */ @Test public void delete() throws Exception { //1. 注册驱动. Class.forName("com.mysql.jdbc.Driver"); //2. 获取连接对象. Connection conn = DriverManager.getConnection("jdbc:mysql:///day15", "root", "123"); //3. 根据连接对象, 获取可以执行SQL语句的对象. Statement stat = conn.createStatement(); //4. 执行SQL语句, 获取结果集. String sql = "delete from users where uid=4;"; int num = stat.executeUpdate(sql); //5. 操作结果集. System.out.println(num > 0 ? "删除成功" : "删除失败"); //6. 释放资源. stat.close(); conn.close(); } }
package com.it.utils; import java.sql.*; /* 案例: 自定义的针对于JDBC操作的工具类. */ public class JDBCUtils { //1. 构造方法私有化. private JDBCUtils() { } //2. 成员方法都是静态的. //3. 注册驱动, 在静态代码块中完成(执行特点: 随着类的加载而执行) static { try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } //4. 对外提供一个获取连接对象的方法 public static Connection getConnection() throws SQLException { return DriverManager.getConnection("jdbc:mysql:///day15", "root", "123"); } //5. 释放资源. //针对于查询语句 public static void release(Connection conn, Statement stat, ResultSet rs) { try { if (conn != null) { conn.close(); conn = null; //GC优先回收null对象. } } catch (SQLException e) { e.printStackTrace(); } finally { try { if (stat != null) { stat.close(); stat = null; } } catch (SQLException e) { e.printStackTrace(); } finally { try { if (rs != null) { rs.close(); rs = null; } } catch (SQLException e) { e.printStackTrace(); } } } } //针对于更新语句 public static void release(Connection conn, Statement stat) { try { if (conn != null) { conn.close(); conn = null; //GC优先回收null对象. } } catch (SQLException e) { e.printStackTrace(); } finally { try { if (stat != null) { stat.close(); stat = null; } } catch (SQLException e) { e.printStackTrace(); } } } } package com.it.demo01_jdbc; import com.it.utils.JDBCUtils; import org.junit.Test; import javax.sql.rowset.JdbcRowSet; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; /* 案例: 操作day15数据库的 users表, 进行CURD操作, 使用自定义的JDBCUtils工具类实现. */ public class Demo03_UseUtils { /** * 演示JDBC之 查询数据 */ @Test public void read() throws Exception { //1. 注册驱动. //2. 获取连接对象. Connection conn = JDBCUtils.getConnection(); //3. 根据连接对象, 获取可以执行SQL语句的对象. Statement stat = conn.createStatement(); //4. 执行SQL语句, 获取结果集. String sql = "select * from users;"; ResultSet rs = stat.executeQuery(sql); //5. 操作结果集. while (rs.next()) { int uid = rs.getInt("uid"); String username = rs.getString("username"); String password = rs.getString("password"); System.out.println(uid + "..." + username + "..." + password); } //6. 释放资源. JDBCUtils.release(conn, stat, rs); } /** * 演示JDBC之 增加数据 */ @Test public void add() throws Exception { //1. 注册驱动. //2. 获取连接对象. Connection conn = JDBCUtils.getConnection(); //3. 根据连接对象, 获取可以执行SQL语句的对象. Statement stat = conn.createStatement(); //4. 执行SQL语句, 获取结果集. String sql = "insert into users values(null, 'admin04', 'pw444');"; int num = stat.executeUpdate(sql); //5. 操作结果集. System.out.println(num > 0 ? "添加成功" : "添加失败"); //6. 释放资源. JDBCUtils.release(conn, stat); } /** * 演示JDBC之 修改数据 */ @Test public void update() throws Exception { //1. 注册驱动. Class.forName("com.mysql.jdbc.Driver"); //2. 获取连接对象. Connection conn = JDBCUtils.getConnection(); //3. 根据连接对象, 获取可以执行SQL语句的对象. Statement stat = conn.createStatement(); //4. 执行SQL语句, 获取结果集. String sql = "update users set password='password444' where uid=4;"; int num = stat.executeUpdate(sql); //5. 操作结果集. System.out.println(num > 0 ? "修改成功" : "修改失败"); //6. 释放资源. JDBCUtils.release(conn, stat); } /** * 演示JDBC之 删除数据 */ @Test public void delete() throws Exception { //1. 注册驱动. Class.forName("com.mysql.jdbc.Driver"); //2. 获取连接对象. Connection conn = JDBCUtils.getConnection(); //3. 根据连接对象, 获取可以执行SQL语句的对象. Statement stat = conn.createStatement(); //4. 执行SQL语句, 获取结果集. String sql = "delete from users where uid=4;"; int num = stat.executeUpdate(sql); //5. 操作结果集. System.out.println(num > 0 ? "删除成功" : "删除失败"); //6. 释放资源. JDBCUtils.release(conn, stat); } }
package com.ith.demo01_jdbc; import com.it.utils.JDBCUtils; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; import java.util.Scanner; /* 案例: 演示SQL注入攻击问题. 需求: 提示用户录入他/她的用户名或者密码, 然后查询数据库, 判断用户是否登录成功, 并提示. */ public class Demo04_SQL注入攻击 { public static void main(String[] args) throws Exception { //1. 提示用户录入他/她的用户名或者密码, 并接收. Scanner sc = new Scanner(System.in); System.out.println("请录入您的账号: "); String username = sc.nextLine(); System.out.println("请录入您的密码: "); String password = sc.nextLine(); //以下是标准的 JDBC代码 //2. 注册驱动. //3. 获取连接对象. Connection conn = JDBCUtils.getConnection(); //4. 根据连接对象, 获取可以执行SQL语句的对象. Statement stat = conn.createStatement(); //5. 执行SQL语句, 获取结果集. String sql = "select * from users where username='" + username + "' and password='" + password + "';"; ResultSet rs = stat.executeQuery(sql); //6. 操作结果集. System.out.println(rs.next() ? "登录成功" : "登录失败, 用户名或者密码错误!"); //7. 释放资源. JDBCUtils.release(conn, stat, rs); } }
package com.itdemo01_jdbc; import com.it.utils.JDBCUtils; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Statement; import java.util.Scanner; /* 案例: 演示SQL注入攻击问题. 需求: 提示用户录入他/她的用户名或者密码, 然后查询数据库, 判断用户是否登录成功, 并提示. SQL注入攻击产生原因: 因为用户录入的非法字符, 被我们的SQL语句识别为关键字或者特殊符号了, 导致我们的SQL语句的判断条件发生变化. 解决方案: 核心思想: 不管用户录入什么内容, 我们都当做普通字符处理. 具体思路: 就是采用预编译思想, 即: 预先对SQL语句进行编译, 把需要用户录入的地方用占位符填充, 此时就已经确定好了 SQL语句的格式, 不管之后在传入什么内容, 我们都当做普通字符处理. 涉及到的成员方法: Connection接口中的成员方法: public PreparedStatement prepareStatement(String sql); //获取可以执行SQL语句的对象(PreparedStatement, 具有预编译功能) PreparedStatement 是Statement接口的子类, 用法和Statement基本一致, 只不过有预编译功能. */ public class Demo05_SQL注入攻击_问题解决 { public static void main(String[] args) throws Exception { //1. 提示用户录入他/她的用户名或者密码, 并接收. Scanner sc = new Scanner(System.in); System.out.println("请录入您的账号: "); String username = sc.nextLine(); System.out.println("请录入您的密码: "); String password = sc.nextLine(); //以下是标准的 JDBC代码 //2. 注册驱动. //3. 获取连接对象. Connection conn = JDBCUtils.getConnection(); //4. 根据连接对象, 获取可以执行SQL语句的对象. //在这一步, 已经确定好了SQL语句的格式, 之后不管传入什么内容, 都会只当做普通字符处理. String sql = "select * from users where username=? and password=?;"; PreparedStatement ps = conn.prepareStatement(sql); //给占位符填充值. ps.setString(1, username); //占位符的索引从1开始. ps.setString(2, password); //5. 执行SQL语句, 获取结果集. ResultSet rs = ps.executeQuery(); //因为SQL语句已经进行了预编译, 且被ps对象所记录, 所以在执行SQL语句时, 无需在传入SQL语句了. //6. 操作结果集. System.out.println(rs.next() ? "登录成功" : "登录失败, 用户名或者密码错误!"); //7. 释放资源. JDBCUtils.release(conn, ps, rs); } }
package com.it.demo01_jdbc; import com.it.utils.JDBCUtils; import org.junit.Test; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; /* 案例: 演示采用预编译功能(即: PreparedStatement)完成 CURD操作. */ public class Demo06_PreparedStatement_CURD { //查 @Test public void read() throws Exception{ //需求: 获取day15数据库users数据表的, 密码为 pw222的这条数据. //1. 注册驱动. //2. 获取连接对象. Connection conn = JDBCUtils.getConnection(); //3. 根据连接对象, 获取可以执行SQL语句的对象. String sql = "select * from users where password = ? ;"; PreparedStatement ps = conn.prepareStatement(sql); //给占位符设置值, 细节 ps.setString(1, "pw222"); //4. 执行SQL语句, 获取结果集. ResultSet rs = ps.executeQuery(); //5. 操作结果集. if (rs.next()) { System.out.println(rs.getInt("uid") + "..." + rs.getString("username") + "..." +rs.getString("password")); } //6. 释放资源. rs.close(); ps.close(); conn.close(); } //增 @Test public void add() throws Exception{ //需求: 往day15数据库users数据表中添加数据, admin04, pw444 //1. 注册驱动. //2. 获取连接对象. Connection conn = JDBCUtils.getConnection(); //3. 根据连接对象, 获取可以执行SQL语句的对象. String sql = "insert into users values(null, ?, ?);"; PreparedStatement ps = conn.prepareStatement(sql); //给占位符设置值, 细节 ps.setString(1, "admin04"); ps.setString(2, "pw444"); //4. 执行SQL语句, 获取结果集. int num = ps.executeUpdate(); //5. 操作结果集. System.out.println(num > 0 ? "添加成功" : "添加失败"); //6. 释放资源. ps.close(); conn.close(); } //删, //改, }
package com.it.utils; import com.mchange.v2.c3p0.ComboPooledDataSource; import javax.sql.DataSource; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; //抽取的 针对于C3P0数据库连接池操作的 工具类. public class C3P0Utils { //1. 构造方法私有化. private C3P0Utils() { } //2. 创建数据库连接池对象, 要用static修饰, 保证大家使用同一个连接池对象. private static final ComboPooledDataSource cpds = new ComboPooledDataSource(); //3. 定义方法, 对外提供获取 连接池对象. //数据库连接池的顶层接口是: DataSource public static DataSource getDataSource() { return cpds; } //4. 定义方法, 对外提供获取 连接对象. public static Connection getConnection() throws Exception{ return cpds.getConnection(); } //5. 释放资源. //针对于查询语句 public static void release(Connection conn, Statement stat, ResultSet rs) { try { if (conn != null) { conn.close(); conn = null; //GC优先回收null对象. } } catch (SQLException e) { e.printStackTrace(); } finally { try { if (stat != null) { stat.close(); stat = null; } } catch (SQLException e) { e.printStackTrace(); } finally { try { if (rs != null) { rs.close(); rs = null; } } catch (SQLException e) { e.printStackTrace(); } } } } //针对于更新语句 public static void release(Connection conn, Statement stat) { try { if (conn != null) { conn.close(); conn = null; //GC优先回收null对象. } } catch (SQLException e) { e.printStackTrace(); } finally { try { if (stat != null) { stat.close(); stat = null; } } catch (SQLException e) { e.printStackTrace(); } } } } package com.it.demo02_c3p0; import com.it.utils.JDBCUtils; import com.mchange.v2.c3p0.ComboPooledDataSource; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; /* 案例: 演示C3P0数据库连接池入门内容. 步骤: 1. 复制c3p0-config.xml配置文件到当前项目(模块)的src目录下. 2. 导入c3p0-config.xml的jar包. 3. 创建数据库连接池对象, 无需关联和指定配置文件, 因为 C3P0数据库连接池会自动加载并识别配置文件的信息. 4. 从数据库连接池对象中获取连接对象(Connection) 5. 正常的 conn.close()关闭连接对象即可, 因为连接池已经重构了 Connection#close()方法, 所以此时调用close()并不是 销毁连接对象, 而是 自动归还. 弊端: 我们写的这个代码, 效率比以前的代码效率还要低, 因为你是每执行一次这个类, 就创建一个连接池对象, 且要填充5个连接对象, 但是在这个类中, 你才用到了1个连接对象, 剩下的4个连接对象都是闲置的, 这样做肯定不行, 那如何优化呢? 解决方案: 把创建连接池对象的操作封装到工具类中, 然后在项目中需要用到连接池的地方, 直接给连接池对象即可, 只要保证整个项目(模块)共用一个连接池对象即可. */ public class Demo01 { public static void main(String[] args) throws Exception{ //获取连接对象的方式一: 自己造. /*//1. 注册驱动. Class.forName("com.mysql.jdbc.Driver"); //2. 获取连接对象. Connection conn = DriverManager.getConnection("jdbc:mysql:///day15", "root", "123");*/ //获取连接对象的方式二: 通过自定义的工具类实现. //获取连接对象. //Connection conn = JDBCUtils.getConnection(); //获取连接对象的方式三: 从数据库连接池中获取. //1. 创建数据库连接池对象. //该对象会去你当前项目下的src目录下查找: c3p0-config.xml文件, 并自动加载. ComboPooledDataSource cpds = new ComboPooledDataSource(); //读取default-config标签中的配置信息. //ComboPooledDataSource cpds = new ComboPooledDataSource("otherc3p0"); //读取name属性为: otherc3p0 这组标签的配置. //2. 从数据库连接池中, 获取连接对象. Connection conn = cpds.getConnection(); //3. 根据连接对象, 获取可以执行SQL语句的对象. Statement stat = conn.createStatement(); //4. 执行SQL语句, 获取结果集. String sql = "select * from users;"; ResultSet rs = stat.executeQuery(sql); //5. 操作结果集. while (rs.next()) { int uid = rs.getInt("uid"); String username = rs.getString("username"); String password = rs.getString("password"); System.out.println(uid + "..." + username + "..." + password); } //6. 释放资源. rs.close(); stat.close(); conn.close(); /* 如果conn连接对象是我们直接创建的, 调用close()方法时, 就是: 销毁conn对象. 如果conn对象是从数据库连接池中获取的, 调用close()方法是, 就是自动归还此对象到: 连接池中, 因为连接池已经把 Connection#close()的机制给重写了, 将其从 "销毁" 变为 "自动归还". */ } } package com.it.demo02_c3p0; import com.it.utils.C3P0Utils; import com.mchange.v2.c3p0.ComboPooledDataSource; import javax.sql.DataSource; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; /* 案例: 演示 C3P0Utils工具类的使用. */ public class Demo02 { public static void main(String[] args) throws Exception { //思路一: 先获取连接池, 然后在获取连接对象. //DataSource ds = C3P0Utils.getDataSource(); //获取连接池 //Connection conn = ds.getConnection(); //从连接池中获取 连接对象 //思路二: 直接获取连接对象. Connection conn = C3P0Utils.getConnection(); //3. 根据连接对象, 获取可以执行SQL语句的对象. Statement stat = conn.createStatement(); //4. 执行SQL语句, 获取结果集. String sql = "select * from users;"; ResultSet rs = stat.executeQuery(sql); //5. 操作结果集. while (rs.next()) { int uid = rs.getInt("uid"); String username = rs.getString("username"); String password = rs.getString("password"); System.out.println(uid + "..." + username + "..." + password); } //6. 释放资源. C3P0Utils.release(conn, stat, rs); } }
浙公网安备 33010602011771号