超详细的JDBC基础,内含 C3P0 和 Druid 等 工具类 JAR 包下载
Posted 一直在进步的派大星
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了超详细的JDBC基础,内含 C3P0 和 Druid 等 工具类 JAR 包下载相关的知识,希望对你有一定的参考价值。
JDBC API 是一系列的接口,统一和规范了应用程序与数据库链接,执行sql语句,并得到返回结果等。在java.sql 和 javax.sql 中
目录
C3P0 连接方式 包含 JAR 下载地址
1. 对 Apche-DButils 介绍 包含下载JAR包地址
1. JDBC概述和原理
1. 概述
(1)JDBC为Java程序操作不同的数据库提供了统一的接口,避免了细节.
(2)JDBC可以链接任何提供了JDBC的驱动程序的数据库系统,从而完成对数据库的任何操作.
2. 原理示意图
2. JDBC快速入门
1. JDBC程序有四个步骤
(1) 加载驱动 -- 加载Driver 类
(2) 获取连接 -- connection
(3)写sql语句 -- CRUD
(4) 释放资源-- close
2. 第一个JDBC程序
先在数据库 db_02 中,建一个actor表
create table Person (idt primary key inauto_increment,`name` varchar(32),sex varchar(1),phone varchar(12));
(1)在加载驱动之前,先要导入 jar 包,其中含有 MySQL厂商 实现java提供接口的规范的类.
1. 下载jar包,前往 mysql官网
2. 在java项目下建一个目录 把 jar 文件复制到该目录中
3. 导入项目 右键jar 选择 add...
1. 加载驱动
2. 获得连接
3. 写sql语句
4. 释放资源
三. 数据库连接的五种方式
1. 就是通过 Driver ,不过是静态加载,依赖性很强
//加载驱动
Driver driver = new Driver();
// 2. 获得连接
// jdbc:mysql:// 固定,是协议
// localhost:3306/ IP 地址 和 端口号
// db_02 数据库
String url = "jdbc:mysql://localhost:3306/db_02";
// 把用户和密码 封装到集合 properties 中
Properties properties = new Properties();
properties.setProperty("user", "root");
properties.setProperty("password","liubo321");
//获得连接
Connection connect = driver.connect(url, properties);
// 3. 编写sql语句 (1) 首先写sql语句(2)获得statement对象写入
String sql = "insert actor values(null , '蔡徐坤', '男', '146843489')";
Statement statement = connect.createStatement();
int i = statement.executeUpdate(sql); // 该对象可以写静态sql语句,并返回结果的行数 大于 0 即为成功
System.out.println(i > 0 ? "成功" : "失败");
//4. 释放资源
connect.close();
statement.close();
2. 通过反射,动态加载 Driver,依赖性降低
public void connect02 () throws ClassNotFoundException, InstantiationException, IllegalAccessException
Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");
Driver driver = (Driver) aClass.newInstance();
3. 使用 DriverManager 统一管理
4. 利用反射机制,自动注册驱动
public static void connect04 () throws ClassNotFoundException, SQLException
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/db_02";
String user = "root";
String password = "liubo321";
Connection connection = DriverManager.getConnection(url, user, password);
System.out.println(connection);
5. 通过配置文件,更加灵活读取
public static void connect05 () throws IOException, ClassNotFoundException, SQLException
Properties properties = new Properties();
properties.load(new FileInputStream("src//mysql.properties"));
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String driver = properties.getProperty("driver");
String url = properties.getProperty("url");
Class.forName(driver);
Connection connection = DriverManager.getConnection(url,user,password);
System.out.println(connection);
配置文件 mysql.properties
四、ResultSet
1. 概述
public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException
Properties properties = new Properties();
properties.load(new FileInputStream("src//mysql.properties"));
String driver = properties.getProperty("driver");
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String url = properties.getProperty("url");
Class.forName(driver);
Connection connection = DriverManager.getConnection(url, user, password);
Statement statement = connection.createStatement();
String sql = "select * from actor";
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next())
int id = resultSet.getInt(1);//获取第一行信息
String name = resultSet.getString(2);//获取第二行信息
String sex = resultSet.getString(3);//获取第三行信息
String phone = resultSet.getString(4);//获取第四行信息
System.out.println(id + "\\t" + name + "\\t" + sex + "\\t" + phone);
connection.close();
statement.close();
五、SQL注入
一、Statement 存在的危险
1. Statement 对象 用于执行静态SQL语句并返回其生成的结果
2. 在建立连接之后,需要对数据库进行访问,执行命名或是sql语句,可以通过
Statement [存在SQL注入问题]
PreparedStatement【预处理】
CallableStatement 【存储过程】
3. SQL注入,是利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入数据中注入非法SQL语句段或者命令,恶意攻击数据库.
二、使用 PreparedStatement 解决
1. 免去拼接字符串
2. 有效解决SQL注入问题
3.减少编译次数,提高效率
使用 PreparenStatement 对象 ,
select * from emp where ename = ?and id = ?;
1. ? 代表占位符,可以使用 PreparenStatement 对象 提供一系列的setXXX ()方法,第一个参数代表第几个问号 从1开始
2. executeQuery 返回结果集
3. executeUpdate (增,删,该)语句,返回 int 值,代表受影响的行数,大于0 成功
案例:使用PerparenStatement 完成对 表 actor 查询
public static void main(String[] args) throws Exception
Properties properties = new Properties();
// 加载驱动
String driver1 = properties.getProperty("driver");
Class.forName(driver1);
// 2. 连接,向配置文件读取信息
properties.load(new FileInputStream("src//mysql.properties"));
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String url = properties.getProperty("url");
// 创建连接
Connection connection = DriverManager.getConnection(url, user, password);
String sql = "select * from actor where id = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1,2);//查询ID为2的信息
ResultSet resultSet = preparedStatement.executeQuery();
System.out.println(resultSet.next() ? "成功" : "失败");
六、JDBC API梳理
1. DriverManager
1. getConnection(url,user,password) 获得链接
2.Statement 接口(存在SQL注入问题)
1. executeUpdate(sql)执行dml语句
2.executeQuery(sql) 执行select语句,返回结果集
3. execute (sql) 执行任意语句,返回boolean值
3. PreparedStatement 接口(预处理)
1. executeUpdate(sql)执行dml语句
2.executeQuery(sql) 执行select语句,返回结果集
3. execute (sql) 执行任意语句,返回boolean值
4.setXXX(占位符索引,赋予占位符的值),解决SQL注入
5. setObject(占位符索引,赋予占位符的值)
4. ResultSet(结果集)
1. next()向下移动,同时没有行返回false
2. previous() 向上移动,如果没有上一行返回false
3.getXXX(列的索引 | | 列的名称),获得对应列的值,接受类型是XXX
4.getObject (列的索引 | | 列的名称)获得对应列的值,接受类型是Object
七、事务
1. jdbc 事务概述
·基本介绍
1.JDBC程序中当一个Connection对象创建时,默认情况下是自动提交事务:每次执行一个SQL语句时,如果执行成功,就会向数据库自动提交,而不能回滚。
2.JDBC程序中为了让多个SQL语句作为一个整体执行,需要使用事务
3.调用Connection 的 setAutoCommit(false) 可以取消自动提交事务
4.在所有的SQL语句都成功执行后,调用commitO;方法提交事务
5.在其中某个操作失败或出现异常时,调用rollback0;方法回滚事务
2.批处理
简述
1.当需要成批插入或者更新记录时。可以采用Java的批量更新机制,这一机制允许多条语句 一次性提交给数据库批量处理。通常情况下比单独提交处理更有效率。
2.JDBC的批量处理语句包括下面方法:
addBatch(O:添加需要批量处理的SQL语句或参数
executeBatch():执行批量处理语句;
clearBatch():清空批处理包的语句
3.JDBC连接MySQL时,如果要使用批处理功能,请再url中加参
数 ?rewriteBatchedStatements=true
4.批处理往往和PreparedStatement一起搭配使用,可以既减少编译次数,又减
少运行次数,效率大大提高
八、数据库连接池 内含 C3P0 and Druid 下载地址
1. 传统链接弊端
1. 对于每次建立一次链接,就要从Connection 对象 ,验证IP,密码等
2. 不能控制连接数量,如果数量过多会导致MySQL奔溃
3. 对于每一次连接,都要关闭,如果程序出现问题,会导致内存泄漏,导致重启MySQL
2. 数据库连接池基本原理
3. 连接池的种类
数据库连接池种类
1.JDBC的数据库连接池使用javax.sql.DataSource来表示,DataSource 只是一个接口,该接口通常由第三方提供实现
2.C3P0 数据库连接池,速度相对较慢,稳定性不错(hibernate,spring)
3.DBCP数据库连接池,速度相对c3p0较快,但不稳定
4.Proxool数据库连接池,有监控连接池状态的功能,稳定性较c3p0差一点
5.BoneCP数据库连接池,速度快
6.Druid(德鲁伊)是阿里提供的数据库连接池,集DBCP、C3PO、Proxool
优点于一身的数据库连接池
4. C3P0 连接方式
1. 导入jar包 下载官网 C3P0 jar包下载地址
@Test
//C3P0 第一种连接方式 ,用户密码,driver url 在程序中方设定
public void C3p01 () throws IOException, PropertyVetoException, SQLException
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
Properties properties = new Properties();
properties.load(new FileInputStream("src//mysql.properties"));
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String url = properties.getProperty("url");
String driver = properties.getProperty("driver");
// 2 配置连接数据库的信息
comboPooledDataSource.setJdbcUrl(url);
comboPooledDataSource.setUser(user);
comboPooledDataSource.setPassword(password);
comboPooledDataSource.setDriverClass(driver);
// 初始化
comboPooledDataSource.setInitialPoolSize(10);//初始化连接数
comboPooledDataSource.setMaxPoolSize(50);//设置最大连接数
// 3 获得链接
Connection connection = comboPooledDataSource.getConnection();
System.out.println("连接成功");
connection.close();
2. 通过配置文件 来完成对数据库连接所需的信息
1. 在src目录下 建 c3p0-config.xml 文件,其内容如下
<c3p0-config> <!--使用默认的配置读取数据库连接池对象 --> <named-config name="小鲨鱼"> <!--加载驱动的Driver路径--> <property name="driverClass">com.mysql.jdbc.Driver</property> <!--指定连接数据库--> <property name="jdbcUrl">jdbc:mysql://localhost:3306/db_02</property> <!--连接数据库的用户--> <property name="user">root</property> <!--对应的密码--> <property name="password">123456</property> <!-- 连接池参数 --> <!--初始化申请的连接数量--> <property name="initialPoolSize">5</property> <!--每次增长链接的数--> <property name="acquireIncrement">5</property> <!--最大的连接数量--> <property name="maxPoolSize">10</property> <!--最小连接数--> <property name="minPoolSize">5</property> <!--超时时间--> <property name="checkoutTimeout">3000</property> <!--每个连接对象可连接的最多的命令对象数--> <property name="maxStatementsPerConnection">2</property> </named-config> </c3p0-config>
2. 通过程序向连接池中取出连接
public void C3P02 () throws SQLException
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("小鲨鱼");
Connection connection = comboPooledDataSource.getConnection();
System.out.println("通过配置文件连接");
5. 德鲁伊连接池 德鲁伊JAR包下载地址
步骤
1. 从官方下载 druid jar 包,导入项目中
2. 在src下面加入 druid 的配置文件
3. 加载驱动,使用 DruidDataSourceFactory.createDataSource(properties);
4. 获得连接
1. 案例:对MySQL数据库完成连接使用Druid连接池
public class Druid_
@Test
public void Druid_connection_pool() throws Exception
// 创建properties对象,加载信息
Properties properties = new Properties();
properties.load(new FileInputStream("src\\\\Druid-config.properties"));
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
dataSource.getConnection();
System.out.println("连接成功");
2. 配置 Druid-config.perproties 配置文件如下 导入 src 目录下
#key=vlaue
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db_02?rewriteBatchedStatements=true
username=root
password=liubo321
initialSize=10
maxActive=50
maxWait=5000
六、Apche-DButils
简述
由于,上述方法,Connection 释放资源时,返回的ResultSet就不能使用。要对ResultSet数据可以想使用的时候就使用,我们要把这个结果集,封装到ArraryList<类>中,该类的属性与表中字段相等,该类称为JavaBean
JavaBean 是为该类是表的映射
代码实现 - Actor 类
package com.study.myDButils;
/**
* +----+-----------+------+------+-----------+
* | id int name varchar | sex varchar | sorc double | phone varchar |
* +----+-----------+------+------+-----------+
* actor 表
*/
public class Actor
private Integer id;
private String name;
private String sex;
public Double sorc;
public String phone;
public Actor() //必须提供无参构造器
public Actor(Integer id, String name, String sex, Double sorc, String phone)
this.id = id;
this.name = name;
this.sex = sex;
this.sorc = sorc;
this.phone = phone;
public Integer getId()
return id;
public void setId(Integer id)
this.id = id;
public String getName()
return name;
public void setName(String name)
this.name = name;
public String getSex()
return sex;
public void setSex(String sex)
this.sex = sex;
public Double getSorc()
return sorc;
public void setSorc(Double sorc)
this.sorc = sorc;
public String getPhone()
return phone;
public void setPhone(String phone)
this.phone = phone;
@Override
public String toString()
return "Actor" +
"id=" + id +
", name='" + name + '\\'' +
", sex='" + sex + '\\'' +
", sorc=" + sorc +
", phone='" + phone + '\\'' +
'';
结果集保存
@Test
public void MyDButils01() throws SQLException
ArrayList<Actor> actors = new ArrayList<>();//JavaBean 把结果集保存在ArrayList中
Connection connection = JdbcDruid.getConnection();//获得连接
String sql = "select * from actor where id = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);//获取preparedStatement执行sql语句
preparedStatement.setInt(1,1);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next())
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
String sex = resultSet.getString("sex");
double sorc = resultSet.getDouble("sorc");
String phone = resultSet.getString("phone");
actors.add(new Actor(id,name,sex,sorc,phone));
JdbcDruid.close(preparedStatement,connection,resultSet);
System.out.println(actors);
对上述方法进行优化 - 引出 Apche-DButils
1. 对 Apche-DButils 介绍 下载JAR包
·基本介绍
1. commons-dbutils是Apache组织提供的一个开源JDBC工具类库,它是对JDBC的封装,
使用dbutils能极大简化jdbc编码的工作量
· DbUtils类
1.QueryRunner类:该类封装了SQL的执行,是线程安全的。可以实现增、删、改、查、批处理
2.使用QueryRunner类实现查询
3.ResultSetHandler接口:该接口用于处理java.sql.ResultSet,将数据按要求转换为另一种形
式,
Q
1.ArrayHandler:把结果集中的第一行数据转成对象数组。
2. ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中。
3. BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
4. BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
5. ColumnListHandler:将结果集中某一列的数据存放到List中。
6. KeyedHandler(name):将结果集中的每行数据都封装到Map里,再把这些map再存到一个map里,其key为指定的key。
7. MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
8. MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List9. ScalarHandler 返回一个字段一列信息
2. 案列:使用 DbUtils 完成对actor表的查询,并把结果集加到list中
package com.study.myDButils;
import com.study.F_jdbc.untils.JdbcDruid;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.junit.jupiter.api.Test;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
/**
* 使用DbUtils 完成对actor表的查询,并把结果集加到list中
*/
public class DButils
@Test
public void DButlis01() throws SQLException
Connection connection = JdbcDruid.getConnection();
String sql = "select * from actor where id >= ?";
QueryRunner queryRunner = new QueryRunner();
/**
* connection 放入一个链接
* sql 写入sql语句
* new BeanListHandler<>(Actor.class)
* 通过反射 获得Actor的属性,并把结果集存在List中
* 最后为可变参数,是 给 ? 占位符 赋值
*/
List<Actor> query = queryRunner.query(connection, sql, new BeanListHandler<>(Actor.class), 1);
for(Actor a :query)
System.out.println(a);
//queryRunner.query 会自动吧statement 关闭,和 resultSet
JdbcDruid.close(null,connection,null);
QueryRunner对象中.update 方法,执行失sql语句的DML语句、
public void DButils_DML() throws SQLException
Connection connection = JdbcDruid.getConnection();
String sql = "delete from actor where id = ?";
// int 返回的是sql语句影响表中的行数
int update = new QueryRunner().update(connection, sql, 1);
System.out.println(update > 0 ? "删除成功" : "没有影响到表");
十、BasicDAO
DAO - - - Data Access Object 【数据访问对象】
概述上述代码缺点
1. SQL 语句写死,不能通过参数传递,通用性不好.
2. 对于 select 语句 返回结果集,返回类型不确定.
2. 编写BasicDAO
1. 建四个包,分别存入不同的类
1. com.study.dao_
2. com.study.dao_.JavaBean // 存放 与表中数据映射的类
3. com.study.dao_.utils // 存放工具类
4. com.study.dao_.dao //存放 XXxDAO
5.com.study.dao_.text // 测试类
1. com.study.dao_.dao
package com.study.dao_.dao;
import com.study.dao_.utils.JDBCUtilsByDruid;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
/**
* 完成其他DAO对象使用的方法
*/
public class BasicDao<T>
private QueryRunner qr = new QueryRunner();
private Connection connection = null;
//执行dml语句
public int queryDate (String sql,Object...parameters)
int updates;
try
this.connection = JDBCUtilsByDruid.getConnection();
updates = qr.update(connection,sql,parameters);
catch (SQLException e)
throw new RuntimeException(e);
finally
JDBCUtilsByDruid.close(null,connection,null);
return updates;
//查询多行结果集
public List<T> queryMulti (String sql, Class<T> aclass,Object... parameters)
try
this.connection = JDBCUtilsByDruid.getConnection();
return qr.query(connection, sql, new BeanListHandler<>(aclass), parameters);
catch (SQLException e)
throw new RuntimeException(e);
finally
JDBCUtilsByDruid.close(null,connection,null);
//查询单行数据
public T querySingle (String sql, Class<T> aclass, Object...parameters)
try
connection = JDBCUtilsByDruid.getConnection();
return qr.query(connection,sql,new BeanHandler<>(aclass),parameters);
catch (SQLException e)
throw new RuntimeException(e);
finally
JDBCUtilsByDruid.close(null,connection,null);
//查询单行单列数据
public Object queryScalar (String sql, Object...parameters)
try
connection = JDBCUtilsByDruid.getConnection();
return qr.query(connection,sql,new ScalarHandler<>(),parameters);
catch (SQLException e)
throw new RuntimeException(e);
finally
JDBCUtilsByDruid.close(null,connection,null);
2. com.study.dao_.domain
package com.study.dao_.domain;
/**
* +----+-----------+------+------+-----------+
* | id int name varchar | sex varchar | sorc double | phone varchar |
* +----+-----------+------+------+-----------+
* actor 表
*/
public class Actor
private Integer id;
private String name;
private String sex;
public Double sorc;
public String phone;
public Actor() //必须提供无参构造器
public Actor(Integer id, String name, String sex, Double sorc, String phone)
this.id = id;
this.name = name;
this.sex = sex;
this.sorc = sorc;
this.phone = phone;
public Integer getId()
return id;
public void setId(Integer id)
this.id = id;
public String getName()
return name;
public void setName(String name)
this.name = name;
public String getSex()
return sex;
public void setSex(String sex)
this.sex = sex;
public Double getSorc()
return sorc;
public void setSorc(Double sorc)
this.sorc = sorc;
public String getPhone()
return phone;
public void setPhone(String phone)
this.phone = phone;
@Override
public String toString()
return "Actor" +
"id=" + id +
", name='" + name + '\\'' +
", sex='" + sex + '\\'' +
", sorc=" + sorc +
", phone='" + phone + '\\'' +
'';
3. com.study.dao_.tex
package com.study.dao_.text;
import com.study.dao_.dao.ActorDao;
import com.study.dao_.domain.Actor;
import org.junit.jupiter.api.Test;
import java.util.List;
public class TextDao
@Test
public void text01()
ActorDao actorDao = new ActorDao();
String sql = "select * from actor where id > ?";
List<Actor> list = actorDao.queryMulti(sql, Actor.class,2);
for(Actor actor : list)
System.out.println(actor);
//单行记录
String sql1 = "select * from actor where id = ?";
Object o = actorDao.querySingle(sql, Actor.class, 3);
System.out.println("单行记录");
System.out.println(o);
//单行单列信息
String sql3 = "select name from actor where id = ?";
Object o1 = actorDao.queryScalar(sql3, 3);
System.out.println("单列数据");
System.out.println(o1);
RabbitMq高级特性之死信队列 通俗易懂 超详细 内含案例
RabbitMq高级特性之死信队列 又称 死信交换机 DLX
当消息成为 Dead message 后,会重新发送到另一个交换机,这个交换机就是 DLX
消息成为死信的情况公有三种:
- 队列消息长度达到限制
- 消费者拒接消费消息 basicNack/basicReject,并且不把消息重新放回原目标队列,requeue=false;
- 原队列消息存在消息过期设置,消息达到过期时间
前提
一、更改RabbitMqConfig.java文件
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* RabbitMq 配置类
*/
@Configuration
public class RabbitMqConfig {
private static final String TOPIC_EXCHANGE_NAME = "topic_exchange";
private static final String TOPIC_QUEUE_NAME = "topic_queue";
public static final String DLX_EXCHANGE = "dlx_exchange";
public static final String DLX_QUEUE = "dlx_queue";
public static final String DLX_ROUTING_KEY = "dlx";
/**
* 创建 交换机
* @return
*/
@Bean
public Exchange itemTopicExchange(){
return ExchangeBuilder.topicExchange(TOPIC_EXCHANGE_NAME).build();
}
@Bean
public Exchange DlxExchange(){
return ExchangeBuilder.directExchange(DLX_EXCHANGE).build();
}
/**
* 创建 队列
* @return
*/
@Bean
public Queue itemQueue(){
//QueueBuilder.durable(TOPIC_QUEUE_NAME).withArgument("x-message-ttl",3000).build();
//与下句代码 效果一致 写一个就可以
//与死信交换机绑定
return QueueBuilder.durable(TOPIC_QUEUE_NAME).ttl(3000).deadLetterExchange(DLX_EXCHANGE).deadLetterRoutingKey(DLX_ROUTING_KEY).build();
}
@Bean
public Queue dlxQueue(){
return QueueBuilder.durable(DLX_QUEUE).build();
}
/**
* 绑定 交换机与队列
* @param exchange
* @param queue
* @return
*/
@Bean
public Binding itemQueueExchange(@Qualifier("itemTopicExchange") Exchange exchange, @Qualifier("itemQueue") Queue queue){
return BindingBuilder.bind(queue).to(exchange).with("item.#").noargs();
}
@Bean
public Binding itemQueueExchange(@Qualifier("dlxExchange") Exchange exchange, @Qualifier("dlxQueue") Queue queue){
return BindingBuilder.bind(queue).to(exchange).with(DLX_ROUTING_KEY).noargs();
}
}
二、测试
- 如有topic_queue已存在,请删除
- 执行ProducerTest.java单元测试
- 过期的死信队列会跑到DLX_QUEUE队列中
三、小结
- 死信队列也可以创建一个消费者来消息死信消息
- 可以在RabbitMqConfig.java文件中的itemQueue()方法中设置队列的最大限度,QueueBuilder.maxLendth(5); 当出入大于5个消息,多余的会丢到死信队列中
- channel.basicNack(deliveryTag, true, false);确认消息但是不发送回原目标队列,会丢到死信队列中
以上是关于超详细的JDBC基础,内含 C3P0 和 Druid 等 工具类 JAR 包下载的主要内容,如果未能解决你的问题,请参考以下文章
RabbitMq消息可靠性之确认模式 通俗易懂 超详细 内含案例
Hadoop——MapReduce相关eclipse配置及Api调用(图文超详细版)(内含遇到错误的解决方法)
C3P0的详细配置说明(com.mchange.v2.c3p0.ComboPooledDataSource)
RabbitMq高级特性之死信队列 通俗易懂 超详细 内含案例