![在这里插入图片描述](https://img-blog.csdnimg.cn/bc8b89d4cca3450bb057f3c476a4a3ec.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5omT54OK5LqGUUFR,size_15,color_FFFFFF,t_70,g_se,x_16)
JDBC
概念
JDBC是sun公司提供的一套用于数据库操作的接口,java程序员只需要面向这套接口编程即可,不同的数据库厂商对这套接口有不同的实现
步骤
-
首先jdbc只是一个接口规范,所以第一导入对应厂商的jar包
-
加载并将驱动类注册进内存区
//注册驱动的代码是在jar包已经定义好了 static { try { DriverManager.registerDriver(new Driver()); } catch (SQLException var1) { throw new RuntimeException("Can't register driver!"); } } //所以下面两步可以做可以不做 new Driver()//第一种 class.forname("地址")//第二种 //都是把类加载进内存,用反射符合开闭原则
-
创建连接对象
不论你是用jdbc还是用数据库软件,首先都会和数据库建立连接,而java将连接视为一个对象,万物皆对象
-
创建执行对象statement执行SQL
❓ 用statement接口的弊端:
1
需要拼接字符串,出现sql注入的问题:拼接or 1 = 1
解决办法
: 使用perparestatement预编译statement
🌓步骤:1.定义一个sql语句,动态值用sql占位
2.perparedstatement预编译sql
3.调用perparedstatement的实例对象填充sql语句
4.执行
-
使用ResultSet对象(查询)
如果你是查询语句,会根据条件得到一系列结果,java
将之封装为结果集对象
-
关闭statement,connection对象
Class.forName("com.mysql.jdbc.Driver");
//Driver dr = new Driver();
Properties pass = new Properties();
InputStream re = son.class.getClassLoader().getResourceAsStream("./res/user.properties");
pass.load(re);
String username = pass.getProperty("username");
System.out.println(username);
String passw = pass.getProperty("password");
System.out.println("棉麻"+passw);
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/zf1", username, passw);
String sql = "SELECT * FROM user";
Statement stmt = con.createStatement();
ResultSet resultSet = stmt.executeQuery(sql);
System.out.println(resultSet);
while (resultSet.next()){
String user = resultSet.getString("user");
int password = resultSet.getInt("password");
System.out.println(user+""+password);
}
con.close();
stmt.close();
}
数据库连接池
1.概念
相当于一个容器集合,用于存放数据库连接对象的容器,当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库的时候,从容器中获取连接对象,用户访问完之后不销毁而是归还给容器
DataSource(数据源)是一个接口规范
❓一个连接到这个DataSource
对象所代表的物理数据源的工厂。 DriverManager
设备的DriverManager
, DataSource
对象是获取连接的首选方法。 实现DataSource
接口的对象通常将基于Java“命名和目录(JNDI)API”的命名服务注册。 接口由驱动程序供应商实现
2.接口规范方法
Connection getConnection()
尝试建立与此 DataSource对象所代表的数据源的连接。
Connection getConnection(String username, String password)
尝试建立与该 DataSource对象所代表的数据源的连接。
3.第三方数据库连接池技术
C3p0
- 导入jar包
- 定义配置文件包括一些数据库账号密码,最大连接数量等等
Druid:由阿里提供
-
导入jar包
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.9</version> </dependency>
-
定义配置文件*.properties放在任意目录手动加载
driverClassName=com.mysql.cj.jdbc.Driver #URL连接数据库的URL,其中travel(以下面例子来说)为连接的数据库,后面的参数可不改但不删 url=jdbc:mysql://localhost:3306/travel?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC characterEncoding=utf-8 #安装mysql时候设置的用户与密码 username=root password=root #初始化物理连接的个数 initialSize=5 #最大连接池数量 maxActive=10 #获取连接时最大等待时间 maxWait=3000 #用来检测连接是否有效的sql validationQuery=SELECT 1 #保证安全性! testWhileIdle=true
-
获取不是创建数据库连接池对象,通过
DruidDataSourceFactory
DruidDataSourceFactory.createDateSource(properties对象:需要手动加载文件流)
-
获取连接
Druid工具类
public class JDBCUtils {
//1定义成员变量DataSource
private static DataSource ds;
static {
try {
//1.加载配置文件
Properties pro = new Properties();
pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
//2.获DataSource
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnetion() throws SQLException {
return ds.getConnection();
}
//释放资源
public static void close(Statement stmt,Connection conn){
if (stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn !=null){
try {
conn.close();//归还连接
} catch (SQLException e) {
e.printStackTrace();
}
}
//close(null,stmt,conn);
}
//释放资源重载
public static void close(ResultSet rs,Statement stmt, Connection conn){
if (rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn !=null){
try {
conn.close();//归还连接
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//获取连接池方法
public static DataSource getDs(){
return ds;
}
}
mysql -u root -p 回车输入密码进入mysql
2、show processlist;
查看连接数,可以发现有很多连接处于sleep状态,这些其实是暂时没有用的,所以可以kill掉
3、show variables like “max_connections”;
查看最大连接数,应该是与上面查询到的连接数相同,才会出现too many connections的情况
4、set GLOBAL max_connections=1000;
修改最大连接数,但是这不是一劳永逸的方法,应该要让它自动杀死那些sleep的进程。
5、show global variables like ‘wait_timeout’;
这个数值指的是mysql在关闭一个非交互的连接之前要等待的秒数,默认是28800s
6、set global wait_timeout=300;
修改这个数值,这里可以随意,最好控制在几分钟内
7、set global interactive_timeout=500;
修改这个数值,表示mysql在关闭一个连接之前要等待的秒数,至此可以让mysql自动关闭那些没用的连接,但要注意的是,正在使用的连接到了时间也会被关闭,因此这个时间值要合适
批量kill之前没用的sleep连接,在网上搜索的方法对我都不奏效,因此只好使用最笨的办法,一个一个kill
8、select concat(‘KILL ‘,id,’;’) from information_schema.processlist where user=‘root’; 先把要kill的连接id都查询出来
(1)复制中间的kill id;内容到word文档
(2)替换掉符号“|”和回车符(在word中查询^p即可查询到回车符)
(3)把修改过的内容复制回终端,最后按回车执行