先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
正文
2.4中的代码就可以通过工具类JdbcUtils中的静态代码块实现注册驱动,通过getConnection()静态方法实现与数据库建立连接,通过free()方法实现资源的释放。
调用工具类的代码如下:
public static void read2(String name) throws Exception {
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
try {
//1.注册驱动:工具类实现
//2.建立连接:调用工具类中的方法
conn=JdbcUtils.getConnection();
//3.创建语句并建立语句执行对象
/*
-
PreparedStatement相比于Statement的优势:
-
1、PreparedStatement没有SQL注入的问题,可以对sql语句进行预处理,过滤一些MySQL中的字符
-
2、当需要执行多次相似的SQL命令时,能够比较高效地执行。(只执行一次的话,PreparedStatement会包含与处理的时间)
*/
String sql=“select * from user where name=?”;
ps=conn.prepareStatement(sql);
ps.setString(1, name);
//4.执行语句
rs=ps.executeQuery();//区别于Statement,不传入参数
//5.处理结果
while(rs.next()) {//按行遍历
System.out.println(rs.getObject(“id”)+“\t”+rs.getObject(“name”)+“\t”
+rs.getObject(“birthday”)+“\t”+rs.getObject(“money”)+“\t”);//获取每一列
}
}finally {
//6.释放资源(后创建的先关闭):调用工具类中的方法
JdbcUtils.free(rs, ps, conn);
}
}
}
四、连接池的使用
========
4.1、连接池是什么?为什么使用连接池?
程序开发过程中,存在很多问题:首先,每一次web请求都要建立一次数据库连接。建立连接是一个费时的活动,每次都得花费0.05s~1s的时间,而且系统还要分配内存资源。这个时间对于一次或几次数据库操作,或许感觉不出系统有多大的开销。可是对于现在的web应用,尤其是大型电子商务网站,同时有几百人甚至几千人在线是很正常的事。在这种情况下,频繁的进行数据库连接操作势必占用很多的系统资源,网站的响应速度必定下降,严重的甚至会造成服务器的崩溃。不是危言耸听,这就是制约某些电子商务网站发展的技术瓶颈问题。其次,对于每一次数据库连接,使用完后都得断开。否则,如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将不得不重启数据库。还有,这种开发不能控制被创建的连接对象数,系统资源会被毫无顾及的分配出去,如连接过多,也可能导致内存泄漏,服务器崩溃。
上述问题的根源就在于对数据库连接资源的低效管理。我们知道,对于共享资源,有一个很著名的设计模式:资源池(resource pool)。该模式正是为了解决资源的频繁分配﹑释放所造成的问题。为解决上述问题,可以采用数据库连接池技术。数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量﹑使用情况,为系统开发﹑测试及性能调整提供依据。
4.2、自定义共享连接池
Java提供了一个公共接口:Javax.sql.DataSource。此接口提供了 DataSource
对象所表示的物理数据源的连接。作为 DriverManager
工具的替代项,DataSource
对象是获取连接的首选方法。
简单来说,就是DateSource接口是Drivermanager的替代项,提供了getConnection()方法并生产标准的Connection对象,那么要实现连接池,就需要实现该接口和该方法。
一般步骤:
-
实现数据源DataSource,即实现Javax.sql.DataSource接口;由于只是简单的演示,我们只实现其中的getConnection()和returnConnToPool()方法即可。使用getConnection()取出连接对象,使用returnConnToPool()归还连接对象。
-
创建一个LinkList容器。既然是“池子”,就需要保存东西,即存储连接池对象,而连接池涉及移除/添加连接池对象,优先考虑使用LinkList来存储。
-
使用静态代码块初始化若干个连接池对象。由于只是测试,我们初始化5个就行。
-
实现getConnection()方法。注意,为了保证连接对象只提供给一个线程(一个用户)使用,我们需要先将连接对象从池子中取出来。
-
用完的连接对象不需要执行close()而是放回池子去。
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.logging.Logger;
import javax.sql.DataSource;
import cn.itcast.jdbc.JdbcUtils;
public class MyDataSource implements DataSource {// [1]实现接口
// [2]创建一个容器存储连接池里的Connection对象。
private static LinkedList pool = new LinkedList();
// [3]初始化3个Connection对象放进池子。
static {
Connection conn = null;
for (int i = 0; i < 3; i++) {
try {
conn = JdbcUtils.getConnection();
} catch (SQLException e) {
e.printStackTrace();
} // 这里我们使用上面创建的JdbcUtils来获取连接
pool.add(conn);
}
}
@Override
// [4]从池子里取连接对象
public Connection getConnection() throws SQLException {
// 使用前先判断连接池是否有连接对象,没有则添加
Connection conn = null;
if (pool.size() == 0) {
for (int i = 0; i < 5; i++) {
conn = JdbcUtils.getConnection();
pool.add(conn);
}
}
conn = pool.removeFirst();// 取出来
return conn;
}
// [5]用完归还连接到连接池
public boolean returnConnToPool(Connection conn) {
return pool.add(conn);
}
// 下面是未实现的方法。
@Override
public PrintWriter getLogWriter() throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
// TODO Auto-generated method stub
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
// TODO Auto-generated method stub
}
@Override
public int getLoginTimeout() throws SQLException {
// TODO Auto-generated method stub
return 0;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
// TODO Auto-generated method stub
return null;
}
@Override
public T unwrap(Class iface) throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
// TODO Auto-generated method stub
return false;
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
// TODO Auto-generated method stub
return null;
}
}
上面通过自定义连接池的案例简单介绍了连接池的原理。事实上,我们在开发过程中,不需要再关心数据库连接的问题,因为实际开发过程中有成熟的数据库连接池帮助我们处理。下面为大家介绍c3p0和DBCP连接池的使用,笔者通过案例介绍这两个连接池的简单实用,更为深层次的理解和使用大家可以参照他们各自的API。
(1)c3p0的API:https://www.mchange.com/projects/c3p0/
(2)DBCP的API:http://commons.apache.org/proper/commons-dbcp/apidocs/index.html
4.3、c3p0连接池
使用c3p0需要都jar包:c3p0-0.9.1.2.jar
使用方式一:快速创建
该方法对应于c3p0的API中快速创建部分,需要在程序内通过ComboPooledDataSource类的对象设置数据库的url地址、用户名user和用户密码password等信息。最后通过ComboPooledDataSource类的对象调用getConnection()方法获取连接池中的连接。
@Test
public void testC3p0() throws Exception {
/**
-
查看c3p0的API:网址:https://www.mchange.com/projects/c3p0/
-
- 如何快速创建
-
- 如何使用xml文件
-
此部分代码对应为API中的为快速创建c3p0
*/
ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setDriverClass( “com.mysql.jdbc.Driver” ); //loads the jdbc driver
cpds.setJdbcUrl( “jdbc:mysql://localhost:3306/jdbc?serverTimezone=UTC” );
cpds.setUser(“root”);
cpds.setPassword(“mysql”);
Connection conn=cpds.getConnection();
System.out.println(conn);
}
使用方式二:使用xml文件
此部分内容参考于c3p0的API中 Appendix B: Configuation Files 的内容
步骤为:
1. 创建 c3p0-config.xml 文件,
参考帮助文档中 Appendix B: Configuation Files 的内容
- 创建 ComboPooledDataSource 实例;
DataSource dataSource =
new ComboPooledDataSource(“helloc3p0”);
- 从 DataSource 实例中获取数据库连接.
配置文件 c3p0-config.xml的代码如下:需要注意的是,配置时诸如"driverClass"、“jdbcUrl”、"initialPoolSize"等属性名需和API当中要求的一致,否则无法识别。
com.mysql.jdbc.Driver
jdbc:mysql://localhost:3306/jdbc?serverTimezone=UTC
root
mysql
50
5
5
10
20
5
通过c3p0-config.xml 文件使用c3p0连接池的代码为:
@Test
public void testC3poWithConfigFile() throws Exception{
/**
-
查看c3p0的API:网址:https://www.mchange.com/projects/c3p0/
-
- 如何快速创建
-
- 如何使用xml文件
-
此部分代码为使用xml文件实现c3p0
*/
/**
-
- 创建 c3p0-config.xml 文件,
-
参考帮助文档中 Appendix B: Configuation Files 的内容
-
- 创建 ComboPooledDataSource 实例;
-
DataSource dataSource =
-
new ComboPooledDataSource("helloc3p0");
-
- 从 DataSource 实例中获取数据库连接.
*/
DataSource dataSource =
new ComboPooledDataSource(“helloc3p0”); //helloc3p0是c3p0-config.xml文件的名称
Connection conn=dataSource.getConnection();
}
4.4、DBCP连接池
方式一:在程序中设置必须的属性值
使用步骤:
1. 加入jar包:commons-dbcp-1.4和commons-pool-1.6
2.创建数据库连接池
3. 为数据源实例指定必须的属性
4. 从数据源中获取数据库连接
/*
-
使用DBCP数据库连接池
-
- 加入jar包:commons-dbcp-1.4和commons-pool-1.6
-
2.创建数据库连接池
-
- 为数据源实例指定必须的属性
-
- 从数据源中获取数据库连接
*/
@Test
public void testDBCP() throws IOException, SQLException {
//通过dbcp.properties文件中的键值对来获取一部分属性
Properties properties = new Properties();
InputStream in = JDBCTest.class
.getClassLoader().getResourceAsStream(“dbcp.properties”);
properties.load(in);
String driver = properties.getProperty(“Driver”);
String url = properties.getProperty(“url”);
String userName = properties.getProperty(“name”);
String password = properties.getProperty(“password”);
System.out.println(driver);
BasicDataSource dataSource = new BasicDataSource();
//2. 为数据源实例指定必须的属性
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(userName);
dataSource.setPassword(password);
//3. 指定数据源的一些可选的属性.
//1). 指定数据库连接池中初始化连接数的个数
dataSource.setInitialSize(5);
//2). 指定最大的连接数: 同一时刻可以同时向数据库申请的连接数
dataSource.setMaxActive(5);
//3). 指定小连接数: 在数据库连接池中保存的最少的空闲连接的数量
dataSource.setMinIdle(2);
//4).等待数据库连接池分配连接的最长时间. 单位为毫秒. 超出该时间将抛出异常.
dataSource.setMaxWait(1000 * 5);
//4. 从数据源中获取5个数据库连接
Connection connection1 = dataSource.getConnection();
System.out.println(connection1.getClass());
Connection connection2 = dataSource.getConnection();
System.out.println(connection2.getClass());
Connection connection3 = dataSource.getConnection();
System.out.println(connection3.getClass());
Connection connection4 = dataSource.getConnection();
System.out.println(connection4.getClass());
Connection connection5 = dataSource.getConnection();
System.out.println(“5”+connection5.getClass());
//当连接诶池内5个连接被分配完时,创建一个线程在等待数据库连接池分配连接的最长时间maxWait之内释放一个连接,就可以再次获得一个连接。
new Thread() {
@Override
public void run() {
Connection connection6;
最后
看完上述知识点如果你深感Java基础不够扎实,或者刷题刷的不够、知识不全面
小编专门为你量身定制了一套<Java一线大厂高岗面试题解析合集:JAVA基础-中级-高级面试+SSM框架+分布式+性能调优+微服务+并发编程+网络+设计模式+数据结构与算法>
针对知识面不够,也莫慌!还有一整套的<Java核心进阶手册>,可以瞬间查漏补缺
全都是一丢一丢的收集整理纯手打出来的
更有纯手绘的各大知识体系大纲,可供梳理:Java筑基、MySQL、Redis、并发编程、Spring、分布式高性能架构知识、微服务架构知识、开源框架知识点等等的xmind手绘图~
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
oid run() {
Connection connection6;
最后
看完上述知识点如果你深感Java基础不够扎实,或者刷题刷的不够、知识不全面
小编专门为你量身定制了一套<Java一线大厂高岗面试题解析合集:JAVA基础-中级-高级面试+SSM框架+分布式+性能调优+微服务+并发编程+网络+设计模式+数据结构与算法>
[外链图片转存中…(img-LaRNVSEt-1713705682104)]
针对知识面不够,也莫慌!还有一整套的<Java核心进阶手册>,可以瞬间查漏补缺
[外链图片转存中…(img-HSTDMAXS-1713705682104)]
全都是一丢一丢的收集整理纯手打出来的
更有纯手绘的各大知识体系大纲,可供梳理:Java筑基、MySQL、Redis、并发编程、Spring、分布式高性能架构知识、微服务架构知识、开源框架知识点等等的xmind手绘图~
[外链图片转存中…(img-ltiaNj0r-1713705682105)]
[外链图片转存中…(img-gPxY2F3t-1713705682105)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-XtsgfYrN-1713705682106)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!