IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> BaseDaoUtils(基于dbUtil实现) -> 正文阅读

[大数据]BaseDaoUtils(基于dbUtil实现)

????????因为最近学习了dbutils,感觉多数的表都用共同的操作(增删改查),刚好也闲,就顺手做了个BaseDao,dao层的类只需要继承BaseDaoImpl类就可以用使用基本的增删改查。

用前须知(请一定要仔细观看):

作用一,实现基本的数据库操作 (BaseDaoImpl)

用法:(本人用的mysql数据库,如果数据库不同,要更改数据库驱动jar包和xml对应的驱动名和值)
1、复制jar包和c3p0-config.xml到项目的src目录下
2、建数据库和表
3、修改,配置c3p0-config.xml文件
4、Dao层的类继承cn.hnzj.hhao.dao.impl.BaseBaoImpl类(下文会提供源码)
5、编写表对应的bean类
注:
(1)继承时的泛型为表对应的bean类
(2)bean类要求:字段名和数量与数据库表对应,id属性名需为:(id名可以是id 或 <表名>id 或 <表名的首字母>id 或 <表名的首字母>-id ? 不区分大小写)
(3)如果bean类名与数据库的表名不同,需要调用父类的有参构造方法(参数为String类型<表名>),设置表名
(3)bean字段的fianl字段不会被识别。


作用二,(C3P0Utils)
1、提供数据源对象
2、提供数据库连接对象
3、提供QueryRunner对象
4、查询当前数据库下的所有表名
5、查询某个表的所有字段

用法:直接用C3P0Utils.<方法>


jar包依赖:

c3p0-0.9.5.5.jar

commons-dbutils-1.7.jar

mchange-commons-java-0.2.19.jar

mysql-connector-java-8.0.16.jar


c3p0-config.xml c3p0的配置文件(必须放在src根目录下,名称也不能改)

<?xml version="1.0" encoding="UTF-8"?>
<!-- 文件名 -->
<c3p0-config>
	<default-config>
		<!-- 数据库驱动名 -->
		<property name="driverClass" >com.mysql.cj.jdbc.Driver</property>
		<!-- 数据库的url -->
		<property name="jdbcUrl" >jdbc:mysql://localhost:3306/mysql?serverTimeZone=UTC</property>
		<!-- 数据库名称 -->
		<property name="user" >root</property>
		<!-- 数据库密码 -->
		<property name="password" >123456</property>
		<!-- chechoutTimeout:等三秒检查 -->
		<property name="checkoutTimeout" >3000</property>
		<!-- 初始化时的连接数量 -->
		<property name="initialPoolSize" >10</property>
		<!-- 连接池内最大的连接数量 -->
		<property name="maxPoolSize" >100</property>
		<!-- 连接池内最小的连接数量 -->
		<property name="minPoolSize" >10</property>
		<!-- 连接池中缓存PrepareStatement的总数 -->
		<property name="maxStatements" >200</property>
	</default-config>
	<!-- test数据库 -->
	<named-config name="test">
		<property name="driverClass" >com.mysql.cj.jdbc.Driver</property>
		<property name="jdbcUrl" >jdbc:mysql://localhost:3306/test?serverTimezone=UTC</property>
		<property name="user" >root</property>
		<property name="password" >123456</property>
		<property name="checkoutTimeout" >3000</property>
		<property name="initialPoolSize" >10</property>
		<property name="maxPoolSize" >10</property>
	</named-config>
</c3p0-config>

下方为源代码:


BaseDao:

package cn.hnzj.hhao.dao;

import java.util.List;

/**
 * Title: BaseDao Description: 实现数据库的基本操作
 * 
 * @author HhaoAn
 * @date 2021年12月10日
 */
public interface BaseDao<T> {

	/**
	 * Title: insert Description: 通过对象插入数据
	 */
	int insert(T t) throws Exception;

	/**
	 * Title: update Description: 通过对象更改对应id的数据
	 */
	int update(T t) throws Exception;

	/**
	 * Title: delete Description: 通过对象的id属性删除数据
	 */
	int delete(T t) throws Exception;

	/**
	 * Title: selectById Description: 通过对象的id的属性查询数据
	 */
	T selectById(T t) throws Exception;

	/**
	 * Title: selectAll Description: 查询所有的数据
	 */
	List<T> selectAll() throws Exception;

}

????????注:会抛出自定义异常,下方有自定义异常类的源代码(我认为,抛出中文的异常说明还是好看懂,所以顺手做了异常)。?

BaseDaoImpl:

package cn.hnzj.hhao.dao.impl;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import cn.hnzj.hhao.dao.BaseDao;
import cn.hnzj.hhao.exception.FieldDaoException;
import cn.hnzj.hhao.exception.TableNameDaoException;
import cn.hnzj.hhao.exception.DaoException;
import cn.hnzj.hhao.util.C3P0Utils;

/**
 * Title: BaseDao Description: 进行数据库的基本操作
 * 用法:子类继承数据连接层,继承此类,泛型用要操作的表对应的bean类。并保证Bean对象和数据库的字段名一致
 * (id,<表名>id,<表名的首字母>id,<表名的首字母>-id 不区分大小写)
 * 
 * 比如:user表对应的bean类为User则泛型写<User> 《User [id,username,userpassword]》,《User
 * [userid,username,userpassword]》,《User [userId,username,userpassword]》,《User
 * [uId,username,userpassword]》,《User [u-Id,username,userpassword]》
 * 
 * 如果类名与表名不对应: 泛型依旧用对应的Bean类,但是要重新设置表名字段:在子类调用父类的有参构造方法中传入表名
 * 
 * 如:public UserDaoImpl() throws DaoException { super("user"); }
 *
 * @author HhaoAn
 * @date 2021年12月9日
 */
public class BaseDaoImpl<T> extends Thread implements BaseDao<T> {
	// 操作语句常量
	private static final String INSERT = "insert";
	private static final String UPDATE = "update";
	private static final String DELETE = "delete";
	private static final String SELECTBYID = "selectbyid";
	private static final String SELECTALL = "selectall";
	/** runner:执行sql操作 */
	private static QueryRunner runner = null;
	/** entityClass:子类的类 */
	private Class<T> entityClass = null;
	/** tableName:子类的类名(表名) */
	private String tableName = null;
	/** idIndex:子类表的id下标 */
	private int idIndex = 0;
	private Field[] fields = null;

	public BaseDaoImpl() {// 创建子类对象时会调用父类的无参构造方法,从而实现赋值
		init();// 初始化信息
		try {
			// 检测标准
			fieldCheck();
		} catch (DaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * Title: Description: 提供表名,修改泛型的表名
	 * 
	 * @param tableName
	 */
	public BaseDaoImpl(String tableName) {// 创建子类对象时会调用父类的无参构造方法,从而实现赋值
		init();// 初始化信息
		this.tableName = tableName.toLowerCase();
		System.out.println(this.tableName);
		try {
			// 检测标准
			fieldCheck();
		} catch (DaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * Title: insert Description: 通过对象插入数据
	 * 
	 * @param 需要添加的对象
	 * @return 执行后,影响的行数
	 */
	@Override
	public int insert(T t) {
		int row = -1;
		try {
			row = runner.update(getSql(INSERT), setArgs(INSERT, t));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return row;
	}

	/**
	 * Title: update Description: 通过对象更改对应id的数据
	 * 
	 * @param 需要修改的对象(需要含有id值)
	 * @return 执行后,影响的行数
	 */
	@Override
	public int update(T t) {
		int row = -1;
		try {
			row = runner.update(getSql(UPDATE), setArgs(UPDATE, t));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return row;
	}

	/**
	 * Title: delete Description: 通过对象的id属性删除数据
	 * 
	 * @param 需要删除的对象(需要含有id值)
	 * @return 执行后,影响的行数
	 */
	@Override
	public int delete(T t) {
		int row = -1;
		try {
			return runner.update(getSql(DELETE), setArgs(DELETE, t));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return row;
	}

	/**
	 * Title: selectById Description: 通过对象的id的属性查询数据
	 * 
	 * @param 需要查询的对象
	 * @return 执行后,查找的一个对象
	 */
	@Override
	public T selectById(T t) {
		try {
			t = runner.query(getSql(SELECTBYID), new BeanHandler<T>(entityClass), setArgs(SELECTBYID, t));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return t;
	}

	/**
	 * Title: selectAll Description: 查询所有的数据
	 * 
	 * @param 需要查询的对象
	 * @return 执行后,对应表的所有信息
	 */
	@Override
	public List<T> selectAll() {
		List<T> result = null;
		try {
			result = runner.query(getSql(SELECTALL), new BeanListHandler<T>(entityClass));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * Title: getSql Description: 获取sql语句
	 * 
	 * @throws Exception
	 */
	private String getSql(String operation) throws Exception {
		StringBuffer sql = new StringBuffer();
		switch (operation) {
		case INSERT:// 插入语句 insert into <table> values(?,?...);
			sql.append("insert into ").append(tableName).append(" values(");
			for (int i = 0; i < fields.length; i++)
				sql.append("?,");
			sql.deleteCharAt(sql.length() - 1);
			sql.append(");");
			break;
		case UPDATE:// 修改语句 update <table> set *=?,*=?... where <id>=?;
			sql.append("update ").append(tableName).append(" set ");
			for (int i = 0; i < fields.length; i++)
				if (i != idIndex)
					sql.append(fields[i].getName()).append("=?,");
			sql.deleteCharAt(sql.length() - 1);
			sql.append(" where ").append(fields[idIndex].getName()).append("=?;");
			break;
		case DELETE:// 删除语句 delete from <table> where <id>=?;
			sql.append("delete from ").append(tableName).append(" where ").append(fields[idIndex].getName())
					.append("=?;");
			break;
		case SELECTBYID:// 通过id查询语句 select * from <table> where <id>=?;
			sql.append("select * from ").append(tableName).append(" where ").append(fields[idIndex].getName())
					.append("=?;");
			break;
		case SELECTALL:// 查询全部语句 select * from <table>
			sql.append("select * from ").append(tableName);
			break;
		default:// 操作参数传入异常,产生错误,阻止程序继续运行
			throw new Exception("getSql方法的传入参数有误");
		}
		return sql.toString();
	}

	/**
	 * Title: setArgs Description: 把参数包装为数组
	 * 
	 * @throws Exception
	 */
	private Object[] setArgs(String operation, T t) throws Exception {
		Object[] args = null;
		switch (operation) {
		case INSERT:// 插入语句 [*,*,*...]
			args = new Object[fields.length];
			for (int i = 0; i < args.length; i++) {
				fields[i].setAccessible(true);
				args[i] = fields[i].get(t);
			}
			break;
		case UPDATE:// 修改语句 [*,*,*...,<id>]
			args = new Object[fields.length];
			for (int i = 0; i < args.length; i++) {
				fields[i].setAccessible(true);
				if (i < idIndex)
					args[i] = fields[i].get(t);
				else if (i == idIndex)
					args[args.length - 1] = fields[idIndex].get(t);
				else
					args[i - 1] = fields[i].get(t);
			}
			break;
		case DELETE:// 删除语句 删除和通过id查询都只需要<id>参数,可以共用
		case SELECTBYID:// 通过id查询语句
			fields[idIndex].setAccessible(true);
			args = new Object[] { fields[idIndex].get(t) };
			break;
		default:// 操作参数传入异常,产生错误,阻止程序继续运行
			throw new Exception("setArgs方法的第一个传入参数有误");
		}
		return args;
	}

	/**
	 * Title: init Description: 初始化信息
	 */
	@SuppressWarnings("unchecked") // 不报错提示
	private void init() {
		// 获取QueryRunner对象,进行sql语句操作
		runner = C3P0Utils.getQueryRunner();
		// 获取泛型参数
		ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();// this.getClass()等价于getClass();
		// 获取泛型的类
		entityClass = (Class<T>) type.getActualTypeArguments()[0];
		// 获取子类的表名 .substring(0, getClass().getSimpleName().length() - 4)
		tableName = entityClass.getSimpleName().toLowerCase();
		// 排除常量字段
		List<Field> var = new ArrayList<Field>();
		for (Field field : entityClass.getDeclaredFields()) {// 如果不是fianl修饰字段,则添加到列表中
			if (!java.lang.reflect.Modifier.isFinal(field.getModifiers()))
				var.add(field);
		}
		fields = new Field[var.size()];
		fields = var.toArray(fields);
	}

	/**
	 * Title: fieldCheck Description: 检查格式是否匹配
	 */
	private void fieldCheck() throws DaoException {
		List<String> tableNames = C3P0Utils.getTableNames();
		// 判断表名是否存在
		if (!tableNames.contains(tableName))
			throw new TableNameDaoException(tableNames, tableName);
		List<String> columnNames = C3P0Utils.getColumnNames(tableName);
		List<String> fields = new ArrayList<String>();
		for (Field field : this.fields)
			fields.add(field.getName());
		// 判断字段名是否匹配
		if (!(fields.containsAll(columnNames) && columnNames.containsAll(fields)))
			throw new FieldDaoException(entityClass.getSimpleName(), tableName, fields, columnNames);
		// 获取id属性值的下标
		for (String field : fields) {
			if (field.equalsIgnoreCase("id") || field.equalsIgnoreCase(tableName + "id")
					|| field.equalsIgnoreCase(tableName.substring(0, 1) + "id")
					|| field.equalsIgnoreCase(tableName.substring(0, 1) + "-" + "id"))// 存在时,直接结束
				break;
			idIndex++;// 下标加以
		}
		// 下标等于字段数组的长度时,说明没有找到id属性,报错
		if (idIndex == this.fields.length)
			throw new FieldDaoException(entityClass.getSimpleName());
	}
}

异常类:(处理BaseDaoImpl抛出的异常)

DaoException:自定义报错的父类

package cn.hnzj.hhao.exception;

/**
 * Title: DaoException Description: 数据连接层的基本报错
 * 
 * @author HhaoAn
 * @date 2021年12月12日
 */
public class DaoException extends Exception {

	/** serialVersionUID: */
	private static final long serialVersionUID = 1L;

	public DaoException() {
		// TODO Auto-generated constructor stub
		super("数据库表结构和Bean类不匹配或无法连接数据库");
	}

	public DaoException(String info) {
		// TODO Auto-generated constructor stub
		super(info);
	}

}

C3P0ParamDaoException: 数据库连接的报错

package cn.hnzj.hhao.exception;

/**
 * Title: ParamDaoException Description: 数据库没有成功连接时的报错
 * 
 * @author HhaoAn
 * @date 2021年12月10日
 */
public class C3P0ParamDaoException extends DaoException {

	/** serialVersionUID: */
	private static final long serialVersionUID = 1L;

	/**
	 * Title: Description: 报错信息
	 */
	public C3P0ParamDaoException() {
		// TODO Auto-generated constructor stub
		super("无法连接数据库,请检查您的c3p0-config文件内的参数是否正确的与数据库匹配,或更改了c3p0-config文件的名称,位置等");
	}
}

FieldDaoException:字段是否匹配的报错

package cn.hnzj.hhao.exception;

import java.util.List;

/**
 * Title: FieldDaoException Description: 数据库与bean类字段问题
 * 
 * @author HhaoAn
 * @date 2021年12月12日
 */
public class FieldDaoException extends DaoException {

	/** serialVersionUID: */
	private static final long serialVersionUID = 1L;

	public FieldDaoException(String beanName) {
		// TODO Auto-generated constructor stub
		super("您的" + beanName + "类的id属性名与默认的id名(id,<表名>id,<表名的首字母>id,<表名的首字母>-id 不区分大小写)不匹配");
	}

	public FieldDaoException(String beanName, String tableName, List<String> fields, List<String> columnNames) {
		// TODO Auto-generated constructor stub
		super("您的" + beanName + "类属性名有:" + fields + "与数据库内" + tableName + "表的字段名:" + columnNames + "数量或名称不匹配");
	}

}

RunSqlDaoException:运行时传入参数的报错(基本上时不可能遇到)

package cn.hnzj.hhao.exception;

public class RunSqlDaoException extends DaoException{

	/** serialVersionUID:*/
	private static final long serialVersionUID = 1L;

	public RunSqlDaoException(Object obj) {
		// TODO Auto-generated constructor stub
		super("请检查:"+obj+"的参数是否合法(类型不匹配或id为空值)");
	}
}

TableNameDaoException:表名不匹配时的报错

package cn.hnzj.hhao.exception;

import java.util.List;

/**
 * Title: TableNameDaoException Description: 未在相应数据库下找到表名
 * 
 * @author HhaoAn
 * @date 2021年12月12日
 */
public class TableNameDaoException extends DaoException {

	/** serialVersionUID: */
	private static final long serialVersionUID = 1L;

	public TableNameDaoException() {
		// TODO Auto-generated constructor stub
		super("表名与数据库内表名不对应(如果您未设置表名需要bean类名与表名相同,或在继承类上设置tableName属性,或当前的数据库下并没有这个表)");
	}

	public TableNameDaoException(List<String> tableNames, String tableName) {
		// TODO Auto-generated constructor stub
		super("未读取到对应的表,当前数据库下存在表有:" + tableNames + "当前读取到的表名为:" + tableName + "(如果您需要设置" + tableName
				+ "的类名与数据库内的表名相同,或在继承BaseBean的类的构造方法上调用父类的有参构造方法(设置表名))");
	}
}

C3P0Utils:数据源的工具类

package cn.hnzj.hhao.util;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

import javax.sql.DataSource;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ColumnListHandler;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import cn.hnzj.hhao.exception.C3P0ParamDaoException;

/**
 * Title: C3P0Utils Description: 获取数据库连接 记得根据自己的数据库调整c3p0-config.xml的参数
 * 
 * @author HhaoAn
 * @date 2021年12月6日
 */
public class C3P0Utils {
	/** ds:声明一个数据源 */
	public static DataSource ds;
	static {
		ds = new ComboPooledDataSource("test");// 创建一个test数据库数据源对象
	}

	/**
	 * Title: getDataSource Description: 获取数据源
	 * 
	 * @return DataSource
	 */
	public static DataSource getDataSource() {
		return ds;
	}

	/**
	 * Title: getConnection Description: 获取一个连接
	 * 
	 * @return Connection
	 */
	public static Connection getConnection() throws SQLException {
		return ds.getConnection();
	}

	/**
	 * Title: getQueryRunner Description: 获取一个QueryRunner对象
	 * 
	 * @return QueryRunner
	 */
	public static QueryRunner getQueryRunner() {
		return new QueryRunner(ds);
	}

	/**
	 * Title: getColumnNames Description: 获取数据库下的所有表名
	 * 
	 * @return List<String>
	 * @throws C3P0ParamDaoException
	 */
	public static List<String> getTableNames() throws C3P0ParamDaoException {
		try {
			return getQueryRunner().query("show tables;", new ColumnListHandler<String>());
		} catch (SQLException e) {
			// TODO: handle exception
			e.printStackTrace();
			throw new C3P0ParamDaoException();
		}
	}

	/**
	 * Title: getColumnNames Description: 获取表中所有字段名称
	 * 
	 * @param tableName 表名
	 * @return List<String>
	 * @throws C3P0ParamDaoException
	 */
	public static List<String> getColumnNames(String tableName) throws C3P0ParamDaoException {
		try {
			return getQueryRunner().query("desc " + tableName, new ColumnListHandler<String>());
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new C3P0ParamDaoException();
		}
	}
}

以下为自己测试时用的代码:

?UserBean:用户表对应的封装对象

package cn.hnzj.hhao.bean;

import java.io.Serializable;

/**
 * Title: user Description: userbean
 * 
 * @author HhaoAn
 * @date 2021年12月6日
 */
public class UserBean implements Serializable {
	/** serialVersionUID: */
	private static final long serialVersionUID = 1L;
	private int userid;
	private String username;
	private String password;

	/**
	 * Title: Description:
	 */
	public UserBean() {
		super();
	}

	/**
	 * Title: Description:
	 * 
	 * @param userid
	 * @param username
	 * @param password
	 */
	public UserBean(int userid, String username, String password) {
		super();
		this.userid = userid;
		this.username = username;
		this.password = password;
	}

	/**
	 * @return the userid
	 */
	public int getUserid() {
		return userid;
	}

	/**
	 * @param userid the userid to set
	 */
	public void setUserid(int userid) {
		this.userid = userid;
	}

	/**
	 * @return the username
	 */
	public String getUsername() {
		return username;
	}

	/**
	 * @param username the username to set
	 */
	public void setUsername(String username) {
		this.username = username;
	}

	/**
	 * @return the password
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * @param password the password to set
	 */
	public void setPassword(String password) {
		this.password = password;
	}

	/*
	 * (non-Javadoc) Title: toString Description:
	 * 
	 * @return
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "UserBean [userid=" + userid + ", username=" + username + ", password=" + password + "]";
	}
}

UserDao:用户数据库操作的对应类

package cn.hnzj.hhao.dao;

import java.sql.SQLException;

import cn.hnzj.hhao.bean.UserBean;

/**
* Title: UserDao Description: 实现用户表的基本操作
* @author HhaoAn
* @date 2021年12月10日
*/
public interface UserDao extends BaseDao<UserBean>{

	/**
	 * Title: selectByUserName Description: 通过用户名查询用户
	 */
	UserBean selectByUserName(UserBean user) throws SQLException;

}


UserDaoImpl:用户数据库操作的对应类(因为Bean名与表名不对应,所以需要调用父类的有参构造方法设置tableName)

package cn.hnzj.hhao.dao.impl;

import java.sql.SQLException;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;

import cn.hnzj.hhao.dao.UserDao;
import cn.hnzj.hhao.bean.UserBean;
import cn.hnzj.hhao.util.C3P0Utils;

public class UserDaoImpl extends BaseDaoImpl<UserBean> implements UserDao {

	public UserDaoImpl() {
		// TODO Auto-generated constructor stub
		super("User");
	}
	
	/**
	 * Title: selectByUserName Description: 通过用户名查询用户
	 */
	@Override
	public UserBean selectByUserName(UserBean user) throws SQLException {
		return new QueryRunner(C3P0Utils.getDataSource()).query("select * from user where username=?",
				new BeanHandler<UserBean>(UserBean.class), user.getUsername());
	}

	public static void main(String[] args) {
		System.out.println(new UserDaoImpl().selectAll());
	}
	
}

????????以上便是全部内容,本人也时学生,还处在学习阶段。如果您有更高的见解,或发现bug,或有更好的优化等,都欢迎您的评论,讨论,希望能和您一起进步!!

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-12-14 16:00:53  更:2021-12-14 16:01:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:31:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码