JavaWeb 注解注入连接池

JavaWeb开发实战源码拆解:从跑通到二次改造的完整指南 Servlet、Filter、JSP与JDBC是JavaWeb开发的核心技术栈,理解其请求链路与分层结构是掌握Web应用开发的基础。通过分析完整项目源码,可以清晰看到浏览器请求如何经过过滤器、Servlet、Service和DAO层,最终完成数据库交互与响应返回。这种实战拆解不仅能帮助开发者快速跑通项目,更能提升对MVC分层、连接池优化和密码安全改造的工程实践能力。适合课程设计、项目改造及后端接口开发者参考。 阅读详情

      当我们在使用 JDBC 技术的时候,为了减轻服务器的压力,我们通常采用连接池技术,但是我们怎么引用获取连接池?如果将连接池写死在 Dao 层中很不优雅,并且不直观。如果我们采用注解技术,就可以很方便的为每个 Dao 动态注入一个了连接池。这也是 Spring 框架中采用的技术。

      为了注入一个连接池,首先我们必须声明一个注解,注解中有连接数据库常用的属性,当然还有一个连接池的类型,因为我们在注入连接池的时候不知道这个 Dao 想要的是一个什么样的连接池,另外我们为了将连接池注入到 Dao 层中,我们必须将 Dao 层与 Service 层解耦,因为如果让 Dao 直接感染了 Service 层,我们就无法控制 Dao 层中的连接池。解耦采用泛型工厂模式,在创建一个 Dao 实例对象的时候为该 Dao 注入一个连接池。在 Dao 对象中维护着一个包含连接池信息注解字段,我们采用反射技术得到该字段上面的注解信息,从而动态创建一个连接池对象给 Dao 使用。

注解:

package cn.dk.annotation;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import com.mchange.v2.c3p0.DataSources;

@Retention(RetentionPolicy.RUNTIME)
public @interface injectDatasource {

	String driverclass() default "com.mysql.jdbc.Driver";
	String url() default "jdbc:mysql://localhost:3306/user";
	String username() default "root";
	String password() default "root";
	@SuppressWarnings("unchecked")
	Class poolType() default DataSources.class;
}


Dao 层

package cn.dk.dao;

import cn.dk.domain.User;

public interface IUserDao {

	User login(String username, String password);

}
package cn.dk.dao.impl;

import java.sql.SQLException;
import javax.sql.DataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import cn.dk.annotation.injectDatasource;
import cn.dk.dao.IUserDao;
import cn.dk.domain.User;

public class UserDao implements IUserDao {

	@injectDatasource private DataSource source;

	public User login(String username, String password) {
		QueryRunner runner = new QueryRunner(source);
		String sql = "select * from user where username=? and password=?";
		Object[] params = { username, password };
		try {
			return (User) runner.query(sql, new BeanHandler(User.class), params);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
}

泛型工厂

package cn.dk.factory;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.mchange.v2.c3p0.DataSources;
import cn.dk.annotation.injectDatasource;

public class DaoFactory {
	
	private static Properties properties = new Properties();
	private static DaoFactory factory = new DaoFactory();

	private DaoFactory(){
		InputStream inputStream = DaoFactory.class.getClassLoader().getResourceAsStream("daoFactory.properties");
		try {
			properties.load(inputStream);
		} catch (IOException e) {
			throw new ExceptionInInitializerError(e);
		}
	}
	
	public static DaoFactory newInstance(){
		return factory;
	}
	
	@SuppressWarnings("unchecked")
	public <T> T getDao(Class<T> clazz){
		String key = clazz.getSimpleName();
		String className = properties.getProperty(key);
		try {
			T t = (T) Class.forName(className).newInstance();
			injectDataSource(t);
			return t;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	@SuppressWarnings("unchecked")
	public void injectDataSource(Object obj){
		Class<?> clazz = obj.getClass();
		Field[] fields = clazz.getDeclaredFields();
		for (int i = 0; i < fields.length; i++) {
			fields[i].setAccessible(true);
			injectDatasource annotation = fields[i].getAnnotation(injectDatasource.class);
			if(annotation == null)
				continue;
			try {
				Class poolType = annotation.poolType();
				if(poolType==ComboPooledDataSource.class){
					ComboPooledDataSource source = new ComboPooledDataSource();
					source.setDriverClass(annotation.driverclass());
					source.setJdbcUrl(annotation.url());
					source.setUser(annotation.username());
					source.setPassword(annotation.password());
					fields[i].set(obj, source);
				}else if(poolType==DataSources.class){
					InputStream inputStream = DaoFactory.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
					Properties dataProperties = new Properties();
					dataProperties.load(inputStream);
					DataSource source = BasicDataSourceFactory.createDataSource(dataProperties);
					fields[i].set(obj, source);
				}
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
	}
}

Service 层

package cn.dk.service;

import cn.dk.dao.IUserDao;
import cn.dk.domain.User;
import cn.dk.factory.DaoFactory;

public class UserService {
	
	private DaoFactory factory = DaoFactory.newInstance();
	private IUserDao userDao = factory.getDao(IUserDao.class);

	public User login(String username, String password) {
		return userDao.login(username, password);
	}
}

 

Web 层

package cn.dk.web;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.dk.domain.User;
import cn.dk.service.UserService;

@SuppressWarnings("serial")
public class LoginServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		UserService service = new UserService();
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		User user = service.login(username, password);
		if(user == null){
			request.setAttribute("message", "密码不正确");
			request.getRequestDispatcher("/message.jsp").forward(request, response);
		}else{
			request.getSession().setAttribute("user", user);
			response.sendRedirect(request.getContextPath() + "/index.jsp");
		}
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}






 

JavaWeb全栈开发工具包整合实战 标签代表一条路由规则,其主要属性如下:<action 阅读详情

相关推荐

JavaWeb登录注册Demo:验证码生成、Servlet跳转与Druid连接池全解析

在Web应用开发中,用户认证是最基础也最核心的环节,而登录注册功能的实现往往涉及验证码校验、会话状态管理、数据库访问等多个技术点。从原理上看,验证码通过BufferedImage动态生成并借助Session实现一次性校验,能有效防止自动化脚本攻击;而数据库交互层面,使用JdbcTemplate配合Druid连接池,可以简化JDBC操作并提升连接复用效率,避免资源耗尽风险。这类技术组合广泛应用于课设项目、企业内训及初级Web开发实践中,尤其适合理解Servlet请求生命周期、重定向与转发差异,以及BeanPr

weixin_42648844的博客 290

操作系统——线程池详解

线程池详解

xh1605004242的博客 1349

sm整合phoenix和连接池(xml和注解两种方式)

springboot整合mybties利用xml和注解两种方式操作phoenix,连接池使用比较快的HikariCP,通过实体类对应的增删改查等方法操作hbase的表,使用分页,这个东西有点新,网上一直没找到,就自己写了一个

SpringBoot教程 | 第二篇:使用Java配置来实现连接池配置

SpringBoot—使用Java配置来实现连接池配置 如何使用Java配置实现连接池配置 首先我们需要从以下几个注解开始认识 @Configration 申明当前类是一个配置类 @@PropertySource(配置文件信息) 加载外部配置文件 @Value 完全属性注入 @Bean 交给Spring容器管理 案例演示 认识了这几个注解,我们直接通过上一篇的springboot入门案例做一下改造,详细步骤如下: 1.不管干什么,首先想到的应该是引坐标,在pom文件下引入依赖 2.数据

weixin_42437102的博客 328

Spring下配置几种常用连接池及配置详解

Spring下配置几种常用连接池及配置详解,详细介绍了目前流行的几种连接池及其配置属性,并有示例讲解。

用python将dycom .dcm格式图像转换为nifti .nii

因为发现目前搜索到的多数中文教程并不能正确将FMRI图像正确转换,例如很多用simpleITk的seriesreader的,所以写了一下自己正确转换的方法。因为FMRI是一个4D数据,有时间轴,所以用seriesreader读写出来的图像把时间轴维度给降维了。当然你用SPM12工具的dycom import也是能正确转换的,但是我还是喜欢python这样的,代码直接简单。

qq_41103479的博客 3609

通过注解的方式将一个类注入到spring容器中有什么好处

工厂模式是在需要对象的时候在工厂中生产一个对象,并直接返回它,而Spring容器会管理对象的生命周期,每次在需要对象时返回其已经管理的同一个实例。例如,需要调用数据库的操作,就需要维护数据库连接的状态,因此需要使用注入的方式,将一个数据库连接池对象绑定在需要使用它的组件上。通过注入,可以实现Spring框架的IOC(控制反转)和DI(依赖注入)功能,即将对象的创建、管理和使用分离开来,通过Spring容器自动管理对象的生命周期,降低了系统的耦合度,提高了系统的可扩展性、可维护性和可测试性。

weixin_41857176的博客 940

多重共线性问题 -- 岭回归方法

概述 本篇博客分为三大部分,线性模型、多重共线性问题和岭回归。其中,线性模型中介绍了线性模型定义和普通最小二乘法对线性模型的拟合。第二部分,借由1987-2007年的人口、消费和科技对碳排放的影响的数据来说明多重共线性问题(包括如何从定性和定量两个方面判断多重共线性问题)和多重共线性问题对普通最小二乘估计的影响。第三部分,使用岭回归对第二部分中的多重共线性问题进行拟合,并基于R2R^2R2决定系数...

楚江客的记录 1万+

Spring的数据库连接池、IOC和依赖注入的全注解配置

数据库连接池的XML配置 此处我用的是c3p0连接池,导入外部的数据库配置文件 <context:property-placeholder location="classpath:jdbc.properties"> </context:property-placeholder> <bean id="c3p0" class="com.mchange.v2.c3p0...

weixin_44616792的博客 1275

数字频率计设计中的常见误区:从VHDL代码到硬件实现的避坑指南

本文深入探讨了数字频率计从VHDL代码到FPGA硬件实现过程中的关键误区与解决方案。重点分析了闸门时间生成的精度与资源平衡、控制时序设计中的竞争冒险规避,以及如何利用EDA工具进行综合、时序约束与调试,确保设计稳定可靠。文章为开发者提供了从仿真成功到硬件可用的实战避坑指南。

spark7igniter的博客 213

嵌入式开发必备:aarch64-linux-gnu-gcc交叉编译工具链保姆级安装指南(含常见错误解决)

本文详细介绍了aarch64-linux-gnu-gcc交叉编译工具链的安装与配置方法,涵盖从系统软件源安装到Linaro二进制包部署的全流程。针对嵌入式开发中常见的依赖错误、版本冲突等问题提供实用解决方案,并分享性能优化技巧与项目集成经验,帮助开发者高效完成ARM64设备的跨平台开发。

yoga7的博客 1030

springboot 随记 一 (注解配置连接池)

一、springboot的启动 @SpringBootApplication public class BootDemoApplication { // psvm public static void main(String[] args) { // 启动springboot SpringApplication.run(BootDemoA...

mobin518的博客 490

TensorFlow GPU版本安装步骤-Windows系统

本文由在Windows下安装TensorFlow GPU版本教程-优快云等整理得到。 目录 1、确认显卡是否支持CUDA 1.1 查看显卡信息 打开“设备管理器”,查看显卡信息,如下图所示: 由上图知,本电脑的显卡为NVIDIA Quadro P400. 1.2 查看支持CUDA的显卡 网址:https://developer.nvidia.com/cuda-gpus 经查询可知,该显卡支持CUDA,如下图所示: 2、安装CUDA 2.1 下载CUDA 网址:https://developer.nvi

x_lingyun的专栏 766

JavaWeb后端基础知识(2)包括(MyBatis)

(1)MyBatis是一款优秀的持久层框架,用于简化JDBC的开发。(2)MyBatis本是Apache的一个开源项目iBatis,2010年这个项目由apache迁移到了googlecode,并且改名为MyBatis。2013年11月迁移到Github。(3)官网:https://mybatis.org/mybatis-3/zh/index.html(Java DataBase Connectivity),就是使用java语言操作关系型数据库的一套API。

2301_79676344的博客 1101

构建自己的 Qt 插件系统

Qt 本身提供了插件相关的技术,但并没有提供一个通用的插件框架!倘若要开发一个较大的 GUI 应用程序,并希望使其可扩展,那么拥有这样一个插件框架无疑会带来很大的好处。

青春不老,奋斗不止! 2万+

6.14华为OD机试真题 新系统 - 字符串格式调整 (Java/Py/C/C++/Js/Go)

# **字符串格式调整** > 2026 华为OD机试真题 6月14日华为OD上机新系统考试真题 100 分题型 点击查看华为 OD 机试真题完整目录:[2026最新华为OD机试新系统卷 + 双机位C卷 真题题库目录|全覆盖题库 + 逐点算法考点详解](https://blog.youkuaiyun.com/banxia_frontend/article/details/160346662) # 题目描述 输入一个字符串,字符串中只包含大写字母和数字。要求将字符串中的所有数字提取出来,按出现的顺序组

算法大师! 947

JavaWeb后端基础(3)

这一篇,我直接从java操作数据库开始写,所以这一篇大致就是记一下JDBC、MyBatis、以及SpringBoot的配置文件。

weixin_60470460的博客 826

昇腾,Ascend,NPU,mindie,镜像,部署vllm:第5篇,昇腾环境下部署蒸馏版deepseek-r1,并在dify中注册模型供应商

这两天没少折腾deepseek-r1。之前在A100上用ollama部署了一份DeepSeek-R1-Distill-Qwen-32B,感觉真的特别慢。现在,再用昇腾部署一遍,看看速度能不能更快。p.s. 类似的内容其实已经写了很多遍了。但感觉之前写得都太碎,不够顺畅。接着新模型写篇长文,把能包括的都包括进来。这样大家也不需要到处翻来翻去。

xiezhipu的博客 2450

JavaWeb学习日志6(JDBC与Mybatis)

通过输入特定的字符串能够符合不存在的数据库的查询(比如数据库中密码定义的or,就有很大的漏洞),而如果使用预编制SQL,则输入的数据将成为字符串与数据库中的数据做对比,不会被钻空子,更加安全。利用Java语言操作关系型数据库的一套API,在企业中一般使用Mybatis,是封装JDBC的高级框架来操作数据库。是个容器,负责分配、管理数据库的链接。避免总是链接释放,减少资源的消耗。查询时,若有多个参数,需使用注解@param来指明一一对应关系。持久层==数据访问层==DAO层。,用于简化JDBC的开发。

m0_73419206的博客 303

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

JavaEE入门级别最全教程4--初学者必看

JavaEE、JavaWeb、Mysql、Maven、Mybatis初学者必看

Laity 2692

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

JavaWeb基础教程,JavaWeb从入门到实战

数据库连接池是个容器,负责分配、管理数据库连接它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接二引起的数据库连接遗漏好处:资源重用提升系统响应速度避免数据库资源遗漏。

m0_54068390的博客 1170

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

JavaWeb入门实战:从Servlet+JSP到增删改查学生管理

JavaWeb开发的核心,是理解HTTP请求从浏览器出发,经过服务器处理,最终返回页面的完整链路。Tomcat作为Servlet容器负责接收请求,Servlet处理业务逻辑,JSP负责渲染视图,而JDBC则构建了Java程序与MySQL之间的数据桥梁。掌握这套基础原理,不仅能让新手看清Spring Boot等框架背后的封装逻辑,更能在后续开发中快速定位问题、避免盲区。在实际工程中,从环境配置到项目部署,每一步都关乎成败。以经典的学生管理系统增删改查为例,通过IDEA创建项目、配置Tomcat、编写DAO层并

weixin_33824385的博客 253

JavaWeb开发_1 JavaWeb项目搭建基础知识章节总结

超凡论基础的重要性_1 JavaWeb项目搭建基础知识章节总结 作者:田超凡 版权所有,转载请注明原作者,仿冒侵权必究法律责任 搭建工具Idea 基础开发环境jdk1.7.79 tomcat7 maven3.3 pom依赖apache ...

田宝宝的博客 463

javaweb

Mybatis是一款优秀的持久层框架,用于简化JDBC的开发。javaEE的三层框架:持久层,表现层,业务层持久层:将数据保存到数据库的那一层代码。

2301_80098154的博客 1789

JavaWeb学习日结

今天学习了关系型数据库MySQL的使用,因为在校学过,所以快速地复习了一遍MySQL的增删改查语句。接着在了解了在Java中操作数据库的方法:JDBC,由于代码繁琐,引入了Java中的持久化框架Mybatis,对Mybatis进行了主要的学习。

2301_79577567的博客 737

javaweb知识点总结(黑马视频笔记)

一篇学完javaweb

m1215339620的博客 8186
上一篇: JavaWeb 案例——访问权限控制
下一篇: Oracle 一
DriverKing
博客等级 码龄16年 77粉丝 54原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值