// 2. 用户信息和url
// 三个参数:useUnicode=true&characterEncoding=utf8&useSSL=true
// useUnicode=true :支持中文编码
// characterEncoding=utf8 :设置字符集为utf8
// useSSL=true :使用安全的连接
String url = “jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true”;
String username = “root”;
String password = “123456”;
// 3. 连接成功,数据库对象 这里的connection代表数据库
Connection connection = DriverManager.getConnection(url,username,password);
// 4. 执行sql的对象 Statement用来执行sql的
Statement statement = connection.createStatement();
// 5. 执行sql
String sql = “SELECT * FROM users”;
// resultSet :返回的结果集,结果集中封装了我们全部的查询结果
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(“===============================================”);
}
// 6. 释放连接(关闭连接)
// 关闭连接的顺序刚好是反着的
resultSet.close();
statement.close();
connection.close();
}
}
步骤总结:
-
1.加载驱动,Class.forName(“com.mysql.jdbc.Driver”);
-
2.连接数据库 DriverManager
-
3.获得执行sql的对象 Statement
-
4.获得返回的结果集 ResultSet
-
5.释放连接(关闭连接)
DriverManager:
// DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Class.forName(“com.mysql.jdbc.Driver”); // 固定写法,加载驱动
//其实上面的forName就是调用的DiverManager中的registerDriver,使用上推荐使用forName。
//它们两个功能都是一样的,加载驱动
// connection 代表的就是数据库。
Connection connection = DriverManager.getConnection(url,username,password);
// 前面在mysql中所说的事务回滚,事务提交,数据库设置为自动提交,都可以通过connection来操作。
connection.rollback();
connection.commit();
connection.setAutoCommit();
URL:
// 三个参数:useUnicode=true&characterEncoding=utf8&useSSL=true
// useUnicode=true :支持中文编码
// characterEncoding=utf8 :设置字符集为utf8
// useSSL=true :使用安全的连接
String url = “jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true”;
//mysql 默认端口号:3306
//mysql的URL格式:
//jdbc:mysql://主机地址:端口号/数据库名?参数1&参数2&参数3
//oracle 默认端口号:1521
//oracle的URL格式:
//jdbc:oracle:thin:@localhost:1521:sid
//像jdbc:mysql 或者 jdbc.oracle 这些都是一种协议。
Statement执行SQL对象:(还有一个PrepareStatement 也是执行sql对象的)
String sql = “SELECT * FROM users”; // 编写sql
statement.executeQuery(“sql语句”); //查询操作,返回resultSet。
statement.execute(“sql语句”); //可以执行任何sql,它能执行任何sql就说明它会有一个判断形式,性能比其他语句低。
statement.executeUpdate(“sql语句”); // 更新,插入,删除,都是用update操作。
statement.executeBatch(“sql语句”); //可以存放多个sql语句,执行。
ResultSet 查询的结果集:封装了所有的查询结果
ResultSet resultSet = statement.executeQuery(sql);
resultSet.getObject(“列名”); //在不知道列类型的情况下使用,getObject()
//如果知道列的类型就是用指定类型
resultSet.getString(“列名”);
resultSet.getInt(“列名”);
resultSet.getFloat(“列名”);
resultSet.getDate(“列名”);
…
ResultSet结果集的遍历,指针操作:
resultSet.beforeFirst(); // 移动到最前面
resultSet.afterLast(); // 移动到最后面
resultSet.next(); // 移动到下一个数据
resultSet.previous(); //移动到前一行
resultSet.absolute(row); //移动到指定行
释放资源:
resultSet.close();
statement.close();
connection.close();
// 一定要释放资源,用完关掉!不然占内存。
=============================================================================
JDBC中的statement对象用于向数据库发送SQL语句,向完成对数据库的增删改查,只需要通过这个对象向数据库发送增删改查语句即可。
-
statement对象中的executeUpdate方法,用于向数据库发送增删改查的sql语句,它返回的是一个整数(即增删改语句导致了数据库几行数据发生了变化)。
-
statement.executeQuery方法用于像数据库发送查询语句,它返回一个ResultSet对象数据集。
封装数据:
db.properties 文件:用来存储连接数据库的内容。
// db.properties文件:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true
username=root
password=123456
JdbcUtiles文件:获取db.properties文件内容,驱动加载,获取连接和释放连接操作。
// JdbcUtils文件:
package com.zhangsan.demo02.utils;
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 {
//获取db.properties的文件,因为在src下,因此不用链接地址。 这里会返回一个输入流
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();
}
}
// 获取连接
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,username,password);
}
//释放连接资源
public static void release(Connection con, Statement st, ResultSet rs){
if (rs!=null){
try{
rs.close();
} catch (SQLException e){
e.printStackTrace();
}
}
if (st!=null){
try{
st.close();
} catch (SQLException e){
e.printStackTrace();
}
}
if (con!=null){
try{
con.close();
} catch (SQLException e){
e.printStackTrace();
}
}
}
}
操作sql语句的文件:增删改查。
//步骤都是一样,就是通过修改sql语句实现。注意是select查询语句有resultset返回集。
package com.zhangsan.demo02;
import com.zhangsan.demo02.utils.JdbcUtils;
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) {
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection(); // 获取数据库连接
st = conn.createStatement(); //获得sql的执行对象
String sql = “UPDATE users SET name
=‘张三’,email
=‘无’ WHERE id=3”;
int i = st.executeUpdate(sql);
if (i>0){
System.out.println(“更新成功|!!”);
}
} catch(SQLException e){
e.printStackTrace();
} finally {
JdbcUtils.release(conn,st,rs);
}
}
}
SQL注入的问题:
sql存在漏洞,会被攻击导致数据泄露,换句话说就是将SQL语句进行拼接。
package com.zhangsan.demo02;
import com.zhangsan.demo02.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class SQL注入 {
public static void main(String[] args) {
//这样我们可以通过login链接数据库完成登录
//login(“张三”,“123456”);
//sql注入别的语句操作,这里通过拼接其他的sql语句即便没有密码用户,照样能获取数据库信息。
login(“’ or '1=1”,“’ or '1=1”);
}
// 登录业务
public static void login(String username,String password){
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection(); // 获取数据库连接
st = conn.createStatement(); //获得sql的执行对象
String sql = “SELECT * FROM users WHERE name
= '”+username+“’ AND password
= '”+password+“'”;
rs = st.executeQuery(sql);
while (rs.next()){
System.out.println(rs.getString(“name”));
System.out.println(rs.getString(“password”));
System.out.println(“===================================”);
}
} catch(SQLException e){
e.printStackTrace();
} finally {
JdbcUtils.release(conn,st,rs);
}
}
}
=====================================================================================
PreparedStatement 可以防止SQL注入,并且效率更高。
PreparedStatement是继承了Statement这个类。
依照上面sql注入,采用preparedstatement就可以有效的避免:
package com.zhangsan.demo02;
import com.zhangsan.demo02.utils.JdbcUtils;
import java.sql.*;
public class SQL注入 {
public static void main(String[] args) {
//这样我们可以通过使用PreparedStatement就避免了SQL注入的问题。
//login(“老铁”,“123456”);
login(“’ or '1=1”,“’ or '1=1”);
}
// 登录业务
public static void login(String username,String password){
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
String sql = “SELECT * FROM users WHERE name
= ? AND password
= ?”;
// PreparedStatement 防止SQL注入的本质,把传递进来的参数当作字符。
// 假设其中存在转移字符,比如说: ’ 会被直接转义。
st = conn.prepareStatement(sql);
st.setString(1,username);
st.setString(2,password);
rs = st.executeQuery();
while (rs.next()){
System.out.println(rs.getString(“name”));
System.out.println(rs.getString(“password”));
System.out.println(“===================================”);
}
} catch(SQLException e){
e.printStackTrace();
} finally {
JdbcUtils.release(conn,st,rs);
}
}
}
通过PreparedStatement进行的查询操作(增删改也是一样的。):
package com.zhangsan.demo03;
import com.zhangsan.demo02.utils.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) {
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
String sql = “select * from users where id=?”;
st = conn.prepareStatement(sql);
st.setInt(1,1);
rs = st.executeQuery();
if(rs.next()){
System.out.println(rs.getString(“name”));
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
JdbcUtils.release(conn,st,rs);
}
}
}
============================================================================
**打开IDEA,右侧的Database找到MySQL:
(远程阿里云数据库需要用到它的外网地址查询)**
Schemas中选择和查看数据库:
修改数据,一定要提交:
在intellij idea 中使用sql语句远程操作数据库:
===================================================================
要么都成功,要么都失败。
**1. 开启事务 :conn.setAutoCommit(false);
2. 一组业务执行完毕后,要提交事务: conn.commit()。
3. 可以在catch语句中显示定义回滚语句,并且不定义也是默认回滚的!**
创建一个模拟事务的java代码:
package com.zhangsan.demo04;
import com.zhangsan.demo02.utils.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) {
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
try{
conn = JdbcUtils.getConnection();
conn.setAutoCommit(false); // 关闭自动提交事务
//实现一次转账
String sql1 = “update account set money = money-100 where name=‘A’”;
st = conn.prepareStatement(sql1);
st.executeUpdate();
int x = 1/0; //模拟失败后,是否回滚
String sql2 = “update account set money = money+100 where name=‘B’”;
st = conn.prepareStatement(sql2);
st.executeUpdate();
//如果两个都成功就要提交事务
conn.commit(); //提交事务
System.out.println(“提交事务,成功!”);
} catch (Exception e) {
//如果不写也会回滚,默认就是回滚。
try{
System.out.println(“回滚事务”);
conn.rollback(); // 如果失败则回滚事务
}catch (SQLException throwables) {
throwables.printStackTrace();
}
e.printStackTrace();
}finally {
JdbcUtils.release(conn,st,rs);
}
}
}
=======================================================================
对于上面JDBC的过程:
数据库连接 – 执行完毕 – 释放
但是,这个过程一步步是非常浪费时间的,因此才有了池化技术。
已下几个名词要熟记:
池化技术:准备一些预先的资源,过来就连接预先准备好的。
常用连接数:就是平时多少人连接的数量。
最小连接数:这里的最小连接数,最好和常用连接数相同或大点。
最大连接数:最大连接数就是业务最高的承载上限!
排队等待:如果超过了最大连接数,就要排队等待,等待有人释放了连接。
等待超时:超过一定的时间就会结束这次连接,告诉等待者已经超时或报错。
编写连接池,实现一个接口 DataSource。
开源数据源实现:
DBCP
C3P0
Druid(阿里巴巴)
使用了这些数据库连接池之后,我们在项目开发中就不需要编写连接数据库的代码了(connection,preparedstatement一系列操作)。
DBCP:
需要的jar包:
dbcpconfig.properties文件:
连接设置 这里面的名字都是DBCP数据源中定义好的,不能乱其名字!!
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true
username=root
password=123456
#!-- 初始化连接 –
initialSize=10
#最大连接数量
maxActive=50
#!-- 最大空闲连接 –
maxIdle=20
#!-- 最小空闲连接 –
minIdle=5
#!-- 超时等待时间以毫秒为单位 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
JdbcUtils_DBCP文件:
package com.zhangsan.demo05.utils;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JdbcUtils_DBCP {
private static DataSource dataSource = null;
static {
try {
//获取db.properties的文件,因为在src下,因此不用链接地址。 这里会返回一个输入流
InputStream in = com.zhangsan.demo02.utils.JdbcUtils.class.getClassLoader().getResourceAsStream(“dbcpconfig.properties”);
Properties properties = new Properties();
properties.load(in); // 读取字节流种的属性列表
//创建数据源 工厂模式–>创建对象
dataSource = BasicDataSourceFactory.createDataSource(properties);
}catch (Exception e){
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException {
return dataSource.getConnection(); //从数据源中获取连接
}
//释放连接资源
public static void release(Connection con, Statement st, ResultSet rs){
if (rs!=null){
try{
rs.close();
} catch (SQLException e){
e.printStackTrace();
}
}
if (st!=null){
try{
st.close();
} catch (SQLException e){
e.printStackTrace();
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

《MySql面试专题》
《MySql性能优化的21个最佳实践》
《MySQL高级知识笔记》
文中展示的资料包括:**《MySql思维导图》《MySql核心笔记》《MySql调优笔记》《MySql面试专题》《MySql性能优化的21个最佳实践》《MySq高级知识笔记》**如下图
关注我,点赞本文给更多有需要的人
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

《MySql面试专题》
[外链图片转存中…(img-6lTwqhEf-1713636816157)]
[外链图片转存中…(img-v14MyfKE-1713636816158)]
《MySql性能优化的21个最佳实践》
[外链图片转存中…(img-yWAWr7I6-1713636816158)]
[外链图片转存中…(img-S1nfYNkK-1713636816158)]
[外链图片转存中…(img-biPQ5YK2-1713636816158)]
[外链图片转存中…(img-naTbzn7k-1713636816158)]
《MySQL高级知识笔记》
[外链图片转存中…(img-7sIx2H3C-1713636816159)]
[外链图片转存中…(img-mSTPmHT8-1713636816159)]
[外链图片转存中…(img-EJQFl7SI-1713636816159)]
[外链图片转存中…(img-t4nxlQjY-1713636816159)]
[外链图片转存中…(img-Tbu3mUYU-1713636816159)]
[外链图片转存中…(img-n96Zm7U4-1713636816159)]
[外链图片转存中…(img-6mamAodM-1713636816160)]
[外链图片转存中…(img-3XztrZQz-1713636816160)]
[外链图片转存中…(img-ZrOD6deA-1713636816160)]
[外链图片转存中…(img-Gw6qzQUM-1713636816160)]
文中展示的资料包括:**《MySql思维导图》《MySql核心笔记》《MySql调优笔记》《MySql面试专题》《MySql性能优化的21个最佳实践》《MySq高级知识笔记》**如下图
[外链图片转存中…(img-FHeqUSQA-1713636816160)]
关注我,点赞本文给更多有需要的人
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!