my sql数据库链接每次操作完都需要关闭吗

mysql 的jdbc链接如果不进行关闭,那么每次产生新链接,就会新增加一个并发,显然这是很可怕的。即便是同一个ip的多次访问,都会造成并发数量的上升。也就是说,每次操作完页面,是一定要关闭链接。是不是会产生这样的疑问。每次都关闭又链接,不是开了关,关了开,这不是更加资源浪费。其实这是错误的,反而保持越久的链接,会更加浪费资源。因为计算机的处理能力是惊人的,人类的几天,也就是计算机的毫秒而已。换算过来,仅仅是几天打开一次,几天关闭一次。可以这么理解。

//如下,我们注销掉关闭conn的方法:

// 非连接池模式关闭数据库链接
    	DataConn.close(stat, conn);

那么,我们进行多次刷新,并链接数据库,控制台显示代码为:

我们并没有进行关闭链接的操作,即便是同一个ip的访问,也会造成并发。每次刷新都会产生新的链接,并发链接数量不断增加。多次同一个ip刷新操作后,数据库并发量达到20之多。

如果我们接下来,每次操作完,进行数据库链接关闭操作。并发数量始终都是1,无论多少次刷新操作。并发量都能保证在1.关闭数据库情况的打印控制台情况。


MYsql JDBC:关闭statement对象:null
MYsql JDBC:关闭了conn对象:null
MYsql JDBC对象:com.mysql.jdbc.JDBC4Connection@35434747--第10 次请求
MYsql JDBC:关闭statement对象:null
MYsql JDBC:关闭了conn对象:null
MYsql JDBC对象:com.mysql.jdbc.JDBC4Connection@36a66ccc--第11 次请求
MYsql JDBC:关闭statement对象:null
MYsql JDBC:关闭了conn对象:null
MYsql JDBC对象:com.mysql.jdbc.JDBC4Connection@39e5ded1--第12 次请求
MYsql JDBC:关闭statement对象:null
MYsql JDBC:关闭了conn对象:null
MYsql JDBC对象:com.mysql.jdbc.JDBC4Connection@2f782dfe--第13 次请求
MYsql JDBC:关闭statement对象:null
MYsql JDBC:关闭了conn对象:null
MYsql JDBC对象:com.mysql.jdbc.JDBC4Connection@57e0c68a--第14 次请求
MYsql JDBC:关闭statement对象:null
MYsql JDBC:关闭了conn对象:null
MYsql JDBC对象:com.mysql.jdbc.JDBC4Connection@7d5852a7--第15 次请求
MYsql JDBC:关闭statement对象:null
MYsql JDBC:关闭了conn对象:null
MYsql JDBC对象:com.mysql.jdbc.JDBC4Connection@710933f7--第16 次请求
MYsql JDBC:关闭statement对象:null
MYsql JDBC:关闭了conn对象:null
MYsql JDBC对象:com.mysql.jdbc.JDBC4Connection@54e0662c--第17 次请求
MYsql JDBC:关闭statement对象:null
MYsql JDBC:关闭了conn对象:null
MYsql JDBC对象:com.mysql.jdbc.JDBC4Connection@278d791d--第18 次请求
MYsql JDBC:关闭statement对象:null
MYsql JDBC:关闭了conn对象:null
MYsql JDBC对象:com.mysql.jdbc.JDBC4Connection@596bb9de--第19 次请求
MYsql JDBC:关闭statement对象:null
MYsql JDBC:关闭了conn对象:null
MYsql JDBC对象:com.mysql.jdbc.JDBC4Connection@26ed0728--第20 次请求
MYsql JDBC:关闭statement对象:null
MYsql JDBC:关闭了conn对象:null
MYsql JDBC对象:com.mysql.jdbc.JDBC4Connection@38890bb0--第21 次请求
MYsql JDBC:关闭statement对象:null
MYsql JDBC:关闭了conn对象:null

关闭后,共发起21次请求,但mysql数据库的并发了数量依然只是1.

druid连接池配置数据库产生多个{dataSource-1} inited

导致这个错误的原因主要是代码逻辑的错误,把链接池初始化放在获取链接的方法体中了。每次链接都会导致初始化一个连接池。每次刷新都会初始化一个链接池。代码很快就崩溃了。

解决方法:把方法体放在类静态代码块中。也就是类的全局代码块。采用全局代码块的static正确写法,具体代码如下。

import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class DruidPoolConn {
	
	static Connection conn;
	static DataSource dataSource = null;
	static int i=0;
	
	//放在全局代码块,避免创建多个链接池
	     static {
	        //1.输入流加载src目录下的配置配置文件
	        InputStream in = DruidPoolConn.class.getResourceAsStream("/poolbydruid.properties");
	        //2.Properties对象方法加载配置文件
	        Properties prop = new Properties();
	        //加载了配置文件中所有的属性
	        try {
	            prop.load(in);
	            System.out.println("装载连接池配置文件poolbydruid.properties成功...");
	        } catch (IOException e) {
	            e.printStackTrace();
	        }
	            try {
					dataSource = DruidDataSourceFactory.createDataSource(prop);
				} catch (Exception e) {
					// TODO 自动生成的 catch 块
					e.printStackTrace();
				}
	     }
	     
	        //4.从连接池中获取连接对象
	        public static Connection getDruidCon() {
	        try {
	            conn=dataSource.getConnection();
	            i++;
	            System.out.println("同一IP的第:"+i+" 次请求");
	            System.out.println("连接池模式:Druid_Conn对象名:"+conn+"---!!!");
	        } catch (SQLException e) {
	            e.printStackTrace();
	        }
			return conn;
	 }
	        
	    	//关闭数据库链接对象
	    	public static void close(java.sql.PreparedStatement stat,java.sql.Connection conn){
	    		   if(stat !=null){
	    	       try {
	    				stat.close();
	    				stat=null;  //设置可让GC回收
	    				System.out.println("Druid连接池模式:关闭tatement对象:"+stat+"");
	    			} catch (SQLException e) {
	    				// TODO Auto-generated catch block
	    				e.printStackTrace();
	    			}
	    		   }   
	    		   if(conn !=null){
	    			   try {
	    				conn.close();
	    				conn=null; //设置可让GC回收
	    				System.out.println("Druid连接池模式:关闭conn对象:"+conn+"");
	    			} catch (SQLException e) {
	    				// TODO Auto-generated catch block
	    				e.printStackTrace();
	    			}
	    		   }
	    	}
}

我们在方法中设置跟踪,连接池配置放在链接方法中,会产生如下图的异常,conn对象名称不断变化,一般连接池初始化设置为8,很快就会用光。每产生一个链接池,就会分配规定数量的链接数量。如下每次刷新,都会产生一个新的链接对象,建立了新链接。

druid 连接池产生多个dataSource的错误图片

当我们重新采用static静态态代码块以后,静态代码块就一次性分配了连接池资源,当有新的链接进来时,就会从常驻的static进行分配了。采用static静态代码后,重新运行程序,不断N次刷新,无论如何刷新。所产生的链接对象都只是一个,也就是只分配一个链接对象。但我们明明关闭了连接池对象conn,怎么会不变呢?难道关闭连接池没有起到作用。否则刷新操作应该是从新分配链接对象才对。这个问题还需要思索测试。但至少采用这种方式,至少保证了一个一个链接对象的重复利用。具体如下图:

无论多少次请求,分配的链接对象都是一样的。

修改以后刷新链接信息如下:

同一IP的第:1 次请求
连接池模式:Druid_Conn对象名:com.mysql.jdbc.JDBC4Connection@a31b7af—!!!
Druid连接池模式:关闭tatement对象:null
Druid连接池模式:关闭conn对象:null
同一IP的第:2 次请求
连接池模式:Druid_Conn对象名:com.mysql.jdbc.JDBC4Connection@a31b7af—!!!
Druid连接池模式:关闭tatement对象:null
Druid连接池模式:关闭conn对象:null
同一IP的第:3 次请求
连接池模式:Druid_Conn对象名:com.mysql.jdbc.JDBC4Connection@a31b7af—!!!
Druid连接池模式:关闭tatement对象:null
Druid连接池模式:关闭conn对象:null

java mysql如何配置数据库连接池

运行时环境
1.jdk版本 1.8
2.操作系统 windows10
3.tomcat 版本 9.0
4.my sql版本 5 驱动版本:mysql-connector-java-5.1.46-bin.jar
5.durid连接池版本 druid-1.0.29.jar

第一步,在src根目录创建配置文件poolbydruid.properties

#Update MySQL_DruidPool_link
#Fri Dec 28 03:39:24 CST 2020
url=jdbc:mysql://localhost:3306/jicha?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false
username=root
password=
driverClassName=com.mysql.jdbc.Driver
initialSize=5
maxActive=10
maxWait=2000

第二步:在同包目录下创建连接池类DruidPoolConn.java

package com.data;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class DruidPoolConn {
	
	static Connection conn;
	static DataSource dataSource = null;
	static int i=0;
	
	//放在全局代码块,避免创建多个链接池
	     static {
	        //1.输入流加载src目录下的配置配置文件
	        InputStream in = DruidPoolConn.class.getResourceAsStream("/poolbydruid.properties");
	        //2.Properties对象方法加载配置文件
	        Properties prop = new Properties();
	        //加载了配置文件中所有的属性
	        try {
	            prop.load(in);
	            System.out.println("装载连接池配置文件poolbydruid.properties成功...");
	        } catch (IOException e) {
	            e.printStackTrace();
	        }
	            try {
					dataSource = DruidDataSourceFactory.createDataSource(prop);
				} catch (Exception e) {
					// TODO 自动生成的 catch 块
					e.printStackTrace();
				}
	     }
	     
	        //4.从连接池中获取连接对象
	        public static Connection getDruidCon() {
	        try {
	            conn=dataSource.getConnection();
	            i++;
	            System.out.println("同一IP的第:"+i+" 次请求");
	            System.out.println("连接池模式:Druid_Conn对象名:"+conn+"---!!!");
	        } catch (SQLException e) {
	            e.printStackTrace();
	        }
			return conn;
	 }
	        
	    	//关闭数据库链接对象
	    	public static void close(java.sql.PreparedStatement stat,java.sql.Connection conn){
	    		   if(stat !=null){
	    	       try {
	    				stat.close();
	    				stat=null;  //设置可让GC回收
	    				System.out.println("Druid连接池模式:关闭tatement对象:"+stat+"");
	    			} catch (SQLException e) {
	    				// TODO Auto-generated catch block
	    				e.printStackTrace();
	    			}
	    		   }   
	    		   if(conn !=null){
	    			   try {
	    				conn.close();
	    				conn=null; //设置可让GC回收
	    				System.out.println("Druid连接池模式:关闭conn对象:"+conn+"");
	    			} catch (SQLException e) {
	    				// TODO Auto-generated catch block
	    				e.printStackTrace();
	    			}
	    		   }
	    	}
}	

第三步,同包目录下创建OperationTable.java类进行所有表的操作

package com.data;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

//Operation类方法定义了所有表的sql操作,为高重用类
public class OperationTable {

    private  String operationsql=null;
    private  String selectsql=null ;
    Connection conn =null;
	PreparedStatement  stat = null;
	
	//从alibaba Druid 德鲁伊连接池获取链接
	public void getConn() {
		 conn=DruidPoolConn.getDruidCon();
	}
	
	//operateTabble方法根据传入的sql进行所有数据表的增、删、改
    public  void operateTable(String operatestr) throws SQLException, ClassNotFoundException {
     //打印出sql语句,用于监测程序运行过程中出现的空值及错误的sql代码。
     //System.out.println("OperationTable类的operateTable()方法处,sql代码详情:"+operatestr);
     operationsql=operatestr;
     stat = (PreparedStatement) conn.prepareStatement(operationsql);
     stat.executeUpdate(operationsql);
}  
     
    //selectTable方法获取所有数据库表的RS结合数据
    public  ResultSet selectTable(String selectstr) throws SQLException, ClassNotFoundException {	 
        // System.out.println("这里是OperationTable类的selectTable方法处...sql代码详情"+selectstr);
         selectsql=selectstr;
         stat = (PreparedStatement) conn.prepareStatement(selectsql);
         ResultSet rs = stat.executeQuery(selectsql);
        return rs;
	}
    
    //从链接池关闭链接
    public  void operateclose() throws SQLException, ClassNotFoundException
    {
    	DruidPoolConn.close(stat, conn );  //调用关闭数据库链接
    }  
}

第四步:配置durid链接监控页面,方便查看监控情况,在web info目录下的xml文件添加以下代码

<servlet>
      <servlet-name>DruidStatView</servlet-name>
      <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>DruidStatView</servlet-name>
      <url-pattern>/druid/*</url-pattern>
  </servlet-mapping>

第五步:运行项目,查看监控效果

运行tomcat得到的运行结果

第六步,访问durid提供的监控页面,访问路径为http://localhost:8084/javaSpringboot/druid/index.html

druid 数据库连接池监控页面

有一种技术叫做停止追逐的脚步,而回归本我

技术是一条无极之路,没有终点。也没有远方,更多的是苦逼的现实。曾几何时,那个意气风发的青年,成为了秃顶的大叔。无论如何说,追求专精的技术道路才是明智选择。

计算机技术发展突飞猛进的今天,版本迭代更新,技术发生巨大变化。无论从何种角度,想要博学达到理想的高度,都如夸父追日一样不现实。10年来,编程语言的排行榜发生了巨大变化。曾今的一些编程语言彻底退出历史舞台。而新的技术,以前所未有的速度走进我们的生活。js在十年前还只是普通的网页脚本,仅仅用来做一些特效。而如今成为了流行的前端语言。vue,nodejs流行开来,原来的ajax已不见踪影。以前的前端叫做美工,现在叫做前端开发岗。

再来说说开发语,仅仅是java,版本都换了好几个,从1.4到了8,很多特性发生了变化。这仅仅只是se的变化,ee的变化更大,十年前,流行MVC。很多项目还是基于jsp+bean+控制器的,现在的各种架构简直让人眼花缭乱。从jsp依赖的编程,直接过度到了spring等架构上来,发生了很多变化。是效率更高了吗?也许吧,但学习成本无疑才是最高的成本。因为出了工作,很多人一直都走在学习的道路上。这,不知道是幸运还是不幸。

从自己熟悉的地方开始,然后逐渐扩展。这明显要简单容易一些,学一门新技术的时间,可以附加更多的思考在旧的技术体系上。选择性淘汰和选择性学习,这将会更加明智。从过程化思维方式到面向对象的思维转变,就是一次历史性的飞跃。所以需要跟上。然而,可以取代的,非必须的。没必要太追求前卫就一定要跟上。

其实,世界在变,技术在变。可是我们的初心不能变?每个人都可以追求一条属于自己的技术道路,里面包含思考和智慧。很多开源软件的形成,刚开始也不过如此。而每个人的技术道路不同,所以好的技术架构都可能被推广,流行开来。我们如果追求所有的技术。那将会永远走在学习的路上而没有自己的思考。这是很可怕的。

maven spring项目本地仓库明明包含jar包,但编译却提示找不到jar包的问题解决

eclipse自带的本地仓库地址为:C:\Users\Administrator.m2\repository,进入到具体的jar包位置,发现配置文件问题。
maven本地仓库中有jar包,项目也能运行,但提示找不到jar包的问题。这个主要是具体jar包位置中的_remote.repositories的配置文件引起的问题,解决方法是进行修改。如下

#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
#Sat Oct 08 18:54:18 CST 2022
mysql-connector-java-8.0.20-sources.jar>central=
mysql-connector-java-8.0.20.jar>central=
mysql-connector-java-8.0.20.pom>central=

修改为配置文件为以下内容

#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
#Sat Oct 08 18:54:18 CST 2022
mysql-connector-java-8.0.20-sources.jar>central
mysql-connector-java-8.0.20.jar>central
mysql-connector-java-8.0.20.pom>central

重新右键项目,update project,然后miss错误提示消失。

提示错误:容器 Maven引用了不存在的库mysql-connector-java-5.1.46.jar

运行spring maven项目中,在pom.xml中配置了依赖关系,同时也在本地maven仓库中拷贝进入了对应的jar包文件,依然提示引用了不存在的jar。提示丢失的是mysql-connector-java-5.1.46.jar包。

项目启动是maven自动下载了mysql-connector-java-8.0.20.jar,以及mysql-connector-java-8.0.22.jar两个jar包文件。但由于自己使用的是MYSQL服务器版本: 5.1.53-community 的版本,所以需要在pom文件规定版本号,并在maven本地仓库引入新的旧版jar包文件。eclipse自带的maven仓库地址为:C:\Users\Administrator.m2\repository\mysql\mysql-connector-java\。

后经仔细观察发现,原来mysql驱动的jar包文件是两个,一个是-bin.jar,而还有一个是不带-bin的jar包文件,而在maven依赖中配置的是带了-bin的jar包文件,mysql-connector-java-5.1.46-bin.jar包。所以提示容器引用错误提示,同时maven构建库中也提示错误的bin文件。

重新到mysql网站下载对应的mysql驱动版本,发现其实驱动文件其实是两个jar包文件,一个带-bin,一个不带,拷贝两个文件到maven仓库,错误提示消失了。mysql java 驱动程序下载地址 https://downloads.mysql.com/archives/c-j/

md5加密算法是否安全,可以被破解吗?

md5可以被破解吗?显然不能,md5采用单向散列算法单向加密。原理上是不可能被破解的,如果用高性能计算机,利用假设法设置密码进行md5碰撞,那也需要很久的时间。理论是需要几万年,从这个角度讲,是比较安全的。

那么,网上那么多md5破解的网站,到底真的能破解吗?对于简单的密码,一定能。因为可以提前对简单的弱密码进行md5加密,然后保存到数据库,形成md5对应的字典密码。然后利用反查法,只要字典中存在弱密码的md5加密串,那么就可以反向查找出对应密码。原理so easy!

比如123456的md5密文为e10adc3949ba59abbe56e057f20f883e,大数据平台可以保存大量字典。进行反向查找,那么显然md5并没有那么靠谱。再者,md5不安全的因素还在于很多曾今数据量庞大的网站都被破解过,这些被破解的网站用户信息都极大可能进入黑客数据库字典。然而,很多用户其实一辈子都循环用着自己为数不多的那几个常用密码,太多显然也记不住。比如生日前缀加good 姓氏后面加特殊纪念日等。这就给字典类破解提供了可能性。

很多小伙伴甚至使用过的密码换平台使用。这是相当不安全的,对于进入字典库的密码来说,早就已经被记录了。所以随着md5的时间推移,被破解的可能性会越来越大。也就是所谓的md5大数据平台,但由于很多人、很多平台都用相同的密码。所以你的密码一旦被黑客md5大数据平台收录,那么md5就很容易被破解。因为很容易理解,md5的破解就是反查法。由于md5的缺点就是相同密码加密的结果是一样的。也就是同一个密码加密后具备唯一性的特征。

因此随着md5使用的时间越长,反查字典就会越完善,被破解的风险就会越高。
程序开发人员如何避免反查法,被破解的可能性。可以在原有密码基础上加入不同字符串等,加盐加料不加价,这样一定程度上可以防止md5大数据字典法破解用户信息。不同系统采用不同字符串,这样就无形中避开了md5数据库字典。安全上的到一定程度提高。

java如何用一句代码实现用户名密码的md5加密

数据库后台用户密码明文显示,显然安全隐患太大。那么我们如何进行密码的加密呢?采用外部jar包的形式是比较简单的一种方式。spring核心jar包中有一个md5DigestAsHex(Password.toString().getBytes())方法,只需要一句代码就能实现加密。so easy!
利用spring-core-5.2.6.jar的DigestUtils.md5DigestAsHex()方法就能对用户密码进行加密。

但这种加密方式是单向加密,也就是相同的用户密码,加密的结果是一样的。但不可逆向。逆向算法解密也只能采用穷举法,也就是碰撞到相同密码,才能对应到相同的密文。显然这种加密方式还是很靠谱滴。
开始操作。

第一步:我们下载spring 提供的安全加密jar包,名称为spring-core-5.2.6.RELEASE.jar,在spring springframework 的核心jar包中。将jar包拷贝到工程lib目录下;当然如果创建的是spring maven项目,项目自身就包含了相关jar包,不需要导入就可以直接用啦。如果是普通java MVC项目,那么我们就需要找到这个jar包,然后手动导入项目。
classs 类开始!
import org.springframework.util.DigestUtils;

//在局部需要加密的方法处加密
DigestUtils.md5DigestAsHex(Password.toString().getBytes());

eclipse调试时自动将lib目录、class目录同时发布到tomcat目录

eclipse 项目debug时,class文件不跟随发布,lib目录不跟随发布都会导致项目启动失败,报错一丢丢。
这个时候就需要右键查看工程目录与运行时环境目录是否debug对应起来啦。

发布目录时,是否同时debug到了tomcat运行目录。首先右键项目,属相选项。选择Deployment Assembly 选项设置。其中可以添加source路径,对应的deploy Path目录可以修改。deploy Path目录为tomcat运行时环境,也是服务器线上环境。debug线上环境的过程中需要检查各种jar包是否成功部署到tomcat服务器。

eclipse非maven构建的spring程序容易导致各种jar包发布不到位,因此报错原因多为运行环境jar包丢失导致的。我们可以从工程目录手动拷贝jar包到tomcat运行环境目录,当然最简单便捷方式的是通过设置来一次性达到目的。对于需要频繁debug的项目尤其如此。下图所示,修改对应的debug目录后,程序每次调试都能成功自动debug到tomcat。so easy!!

java mysql数据库如何配置alibaba druid(德鲁伊)数据库连接池

流量不大的网站其实没有必要配置数据库连接池。小网站尽量避免尾大不掉。代码越多,留给远方的坑就会越多。维护成本不减反增。之所以配置,主要网上小伙伴纷纷表示可以防止sql注入。把连接池提高到sql安全的角度。那就配吧!首先我们去gt下载jar包,然后调整配置一下。非常easy!!!

首先第一步:tomcat lib目录下导入jar包druid-1.0.29.jar。
第二步在配置文件properties文件中创建数据库链接配置项

MysqlPassword=
MysqlAdmin=root
MysqlUrl=jdbc\:mysql\://localhost\:3306/test?characterEncoding\=utf8&useSSL=false
MysqlDriver=com.mysql.jdbc.Driver //如果mysql是5的版本,则采用此。若mysql为6版本,则为com.mysql.cj.jdbc.Driver
initialSize=1
maxActive=8

第三步://在链接类中import DruidDriver类

import com.alibaba.druid.proxy.DruidDriver;	   
Properties  prop = new Properties();
//创建输入流对象,读取数据库配置文件 
InputStream in =DruidDriver.class.getResourceAsStream("/mysqlJdbc.properties");  
try {
prop.load(in);
//System.out.println("装载mysql配置文件mysqlJdbc.properties!");
//System.out.println("alibaba.druid连接池模式");
url  = prop.getProperty("MysqlUrl");
user = prop.getProperty("MysqlAdmin");
password = prop.getProperty("MysqlPassword");
mdname= prop.getProperty("MysqlDriver");
}

第四步:在xml中配置监控查看项

  <servlet>
      <servlet-name>DruidStatView</servlet-name>
      <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>DruidStatView</servlet-name>
      <url-pattern>/druid/*</url-pattern>
  </servlet-mapping>

至此,配置完成。可以在监控页面查看各项监控数据。

杨帆梦想,生命起航。