Gson使用Gson工具类GsonUtils(项目中要求不要使用Fastjson,原因:Fastjson存在安全漏洞)

在这里插入图片描述

一、概述
Gson是google提供的用来操作json数据的一个非常好用的类库。其使用范围非常的广泛,所以非常有必要对其进行系统的学习。
json是一种数据格式,确切的说是一种文本数据格式。其在网络通讯过程中的作用非常的明显。
目前大多数的网络通讯格式已经从xml替换为json格式。
其提供了序列化和反序列化的功能。在我们进行网络开发的过程中通常会把参数封装成json格式传给后台,后台解析后的返回结果也会封装成json格式返回给调用者。

1.如何创建一个Gson对象

	/*** 创建Gson对象的两种形式*/private void createGsonObject() {//第一种方式Gson gson = new Gson();//第二种方式Gson gson1 = new GsonBuilder().create();//方式二除了可以创建一个Gson对象以外还可以进行多项配置,例如,设置日期的格式化
//       例如: new GsonBuilder().setDateFormat("yyyy-MM-dd");}

2.如何创建一个JsonObject

/*** 如何创建一个json对象*/private void createJsonObject() {JsonObject jsonObject = new JsonObject();jsonObject.addProperty("id", "1");//给jsonObject创建一个id属性值为1jsonObject.addProperty("bookName", "《深入Java虚拟机》");jsonObject.addProperty("bookPrice", 36.8);jsonObject.addProperty("bookColor", "红色");//打印Json字符串System.out.println(jsonObject.toString());//给JsonObject添加对象JsonObject jsonObject1 = new JsonObject();jsonObject1.addProperty("chapterId", "1");jsonObject1.addProperty("chapterName", "第一章");//给JsonObject添加实体对象jsonObject.add("chapter", jsonObject1);System.out.println(jsonObject.toString());/*** 输出结果:* {"id":"1","bookName":"《深入Java虚拟机》","bookPrice":36.8,"bookColor":"红色"}* {"id":"1","bookName":"《深入Java虚拟机》","bookPrice":36.8,"bookColor":"红色","chapter":{"chapterId":"1","chapterName":"第一章"}}*/}

注:这里的JsonObject表示我们一样可以创建一个json对象;但是我们后面一般使用的是java对象跟json字符串的转换,可以用通过创建好的gson对象来操作。

3.数组的序列化与反序列化

	/*** 根据一个json创建一个数组*/private void createJsonArray() {//把数组转换为Json字符串String[] str = new String[]{"《深入Java虚拟机》", "《Android插件编程》", "《OpenCV全解》"};Gson gson = new Gson();String jsonStr = gson.toJson(str);//先创建一个Json字符串System.out.println(jsonStr);//输出//把Json字符串转换为Json数组String[] strArray = gson.fromJson(jsonStr, String[].class);for (String s : strArray) {System.out.println(s);}/*** 输出结果:* ["《深入Java虚拟机》","《Android插件编程》","《OpenCV全解》"]* 《深入Java虚拟机》* 《Android插件编程》* 《OpenCV全解》*/}

4.List的序列化与反序列化

 	/*** 根据一个json创建一个list*/private void createJsonToList() {//将list集合转换为json字符串List<Book> books = new ArrayList<>();books.add(new Book("1", "《深入Java虚拟机》"));books.add(new Book("2", "《OpenCV进阶》"));books.add(new Book("3", "《深入Android源代码》"));Gson gson = new Gson();String jsonListStr = gson.toJson(books);System.out.println(jsonListStr);//将json字符串转换为list集合//获取泛型的类型Type type = new TypeToken<List<Book>>() {}.getType();//使用gson将字符串转换为泛型集合,即List<Book>List<Book> books1 = gson.fromJson(jsonListStr, type);for (Book book : books1) {System.out.println(book.getName());}/*** 输出结果:* [{"id":"1","name":"《深入Java虚拟机》"},{"id":"2","name":"《OpenCV进阶》"},{"id":"3","name":"《深入Android源代码》"}]* 《深入Java虚拟机》* 《OpenCV进阶》* 《深入Android源代码》*/}

注:

//获取泛型的类型
Type type = new TypeToken<List<Book>>() {}.getType();*

5.序列化与反序列化综合例子(基于Book对象)

public class Book {public Book(){}private String id;/*** 加上@SerializedName注解后服务端api返回bookName、Name、bn时,客户端都能够拿到正确的值给name属性。*/@SerializedName(value = "bookName",alternate = {"Name","bn"})private String name;public Book(String id, String name) {this.id = id;this.name = name;}
}/*** json的序列化与反序列化* 使用toJson实现序列化,使用fromJson实现反序列化*/private void jsonSeriaReSeria() {Gson gson = new Gson();Book book = new Book("1", "《深入Java虚拟机》");//将book类序列化成字符串String bookStr = gson.toJson(book);System.out.println(bookStr);//将bookStr反序列化成为Book类Book b = gson.fromJson(bookStr, Book.class);System.out.println(b.getName());}

6.如何为属性做兼容性处理(重命名、预设名称等)

 	/*** 如何给json属性重命名* 假设我们有这样一个需求:由于接口改版,从服务端返回的api中的book字段的name属性,变为了bookName。如果我们* 仍然用name进行解析,则接不到bookName的值,而由于服务端没有返回name,则解析后name=null。如果要考虑到兼容性那么我们的的Book类的属性就* 需要做一下兼容性的处理。* 使用@SerializedName可以给属性重命名。用@SerializedName的alternate属性给Book的属性做扩展*/private void reNameProperty() {String bookJson = "{\"id\":\"1\",\"bookName\":\"《深入Java虚拟机》\"}";Gson gson = new Gson();Book book = gson.fromJson(bookJson, Book.class);System.out.println(book.getName());}

注:@SerializedName(value = “bookName”,alternate = {“Name”,“bn”})表示在反序列化时候可以使用bookName,Name,bn都可以被识别到,set到Book中的name属性;相应的在序列化的时候,name属性会被序列化为bookName字符串;

7.GsonBuilder的一些基础配置

	/*** 对GsonBuilder一些属性介绍*/private void gsonBuilderProperty() {Gson gson = new GsonBuilder().serializeNulls()//默认情况下如果某一个属性为null,那么此属性不会参与序列化和反序列化的过程,加上此属性后会参与序列化和反序列化的过程.setPrettyPrinting()//格式化json字符串的输出,默认情况下是输出一行,经过这个属性设置后会格式化输出,即有缩进的输出.setDateFormat("yyyy-MM-dd HH:mm:ss")//对时间进行格式化.create();}

8.TypeAdapter使用方法介绍

	/*** typeAdapter的使用方法* TypeAdapter是一个泛型抽象类,用于接管某种类型的序列化和反序列化的过程* 它包含两个抽象方法write和read,分别用于自定义的序列化和反序列化的过程*/private void useTypeAdapter() {Gson gson = new GsonBuilder().registerTypeAdapter(Book.class,new BookTypeAdapter()).create();Book book = new Book("1","深入Java虚拟机");System.out.println(gson.toJson(book));String bookJson = "{\"Id\":\"1\",\"Name\":\"《深入Java虚拟机》\"}";Book book1 = gson.fromJson(bookJson,Book.class);System.out.println(gson.toJson(book1));}以下是BookTypeAdapter的代码介绍package com.yw.gsonlib;import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;import java.io.IOException;public class BookTypeAdapter extends TypeAdapter<Book> {/*** 序列化接口** @param jsonWriter* @param book* @throws IOException*/@Overridepublic void write(JsonWriter jsonWriter, Book book) throws IOException {//流式序列化对象开始jsonWriter.beginObject();//将Json的key值都指定为首字母大写jsonWriter.name("Id").value(book.getId());jsonWriter.name("Name").value(book.getName());//流式序列化对象结束jsonWriter.endObject();}/*** 反序列化接口** @param jsonReader* @return* @throws IOException*/@Overridepublic Book read(JsonReader jsonReader) throws IOException {Book book = new Book();//流式反序列化开始jsonReader.beginObject();while (jsonReader.hasNext()) {switch (jsonReader.nextName()) {case "id":case "Id":book.setId(jsonReader.nextString());break;case "name":case "Name":book.setName(jsonReader.nextString());break;}}//流式反序列化结束jsonReader.endObject();return book;}
}

Gson 工具类

package com.utils;import com.google.gson.*;
import com.google.gson.reflect.TypeToken;import java.util.ArrayList;
import java.util.List;
import java.util.Map;public class GsonUtils {//不用创建对象,直接使用Gson.就可以调用方法private static Gson gson = null;//判断gson对象是否存在了,不存在则创建对象static {if (gson == null) {//gson = new Gson();// 当使用GsonBuilder方式时属性为空的时候输出来的json字符串是有键值key的,显示形式是"key":null,而直接new出来的就没有"key":null的gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();}}//无参的私有构造方法private GsonUtils() {}/*** 将对象转成json格式** @param object* @return String*/public static String GsonString(Object object) {String gsonString = null;if (gson != null) {gsonString = gson.toJson(object);}return gsonString;}/*** 将json转成特定的cls的对象** @param gsonString* @return*/public static <T> T GsonToBean(String gsonString, Class<T> cls) {T t = null;if (gson != null) {//传入json对象和对象类型,将json转成对象t = gson.fromJson(gsonString, cls);}return t;}/*** json字符串转成list** @param gsonString* @return*/public static <T> List<T> GsonToList(String gsonString, Class<T> cls) {List<T> list = null;if (gson != null) {//根据泛型返回解析指定的类型,TypeToken<List<T>>{}.getType()获取返回类型list = gson.fromJson(gsonString, new TypeToken<List<T>>() {}.getType());}return list;}/*** json字符串转成list** @param json* @return*/public static <T> List<T> jsonToList(String json, Class<T> cls) {ArrayList<T> mList = new ArrayList<T>();JsonArray array = new JsonParser().parse(json).getAsJsonArray();for (final JsonElement elem : array) {mList.add(gson.fromJson(elem, cls));}return mList;}/*** json字符串转成数组** @param json* @return*/public static Object[] json2ObjectArray(String json, Class cls) {TypeToken<?> array = TypeToken.getArray(cls);Gson gson = new Gson();Object[] objects = gson.fromJson(json, array.getType());return objects;}/*** json字符串转成list中有map的** @param gsonString* @return*/public static <T> List<Map<String, T>> GsonToListMaps(String gsonString) {List<Map<String, T>> list = null;if (gson != null) {list = gson.fromJson(gsonString,new TypeToken<List<Map<String, T>>>() {}.getType());}return list;}/*** json字符串转成map的** @param gsonString* @return*/public static <T> Map<String, T> GsonToMaps(String gsonString) {Map<String, T> map = null;if (gson != null) {map = gson.fromJson(gsonString, new TypeToken<Map<String, T>>() {}.getType());}return map;}
}

注意:

项目中要求不要使用Fastjson,原因:Fastjson存在安全漏洞
经查阅资料:Fastjson≤1.2.80的版本存在安全漏洞;

Gson工具类

import com.google.gson.*;
import com.google.gson.reflect.TypeToken;
import lombok.SneakyThrows;import java.lang.reflect.Type;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.Objects;public class GsonUtils {private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");private static final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");private static final DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");private static final JsonSerializer<LocalDateTime> dateTimeSerializer= (obj, type, ctx) -> new JsonPrimitive(dateTimeFormatter.format(obj));private static final JsonSerializer<LocalDate> dateSerializer= (obj, type, ctx) -> new JsonPrimitive(dateFormatter.format(obj));private static final JsonSerializer<LocalTime> timeSerializer= (obj, type, ctx) -> new JsonPrimitive(timeFormatter.format(obj));private static final JsonDeserializer<LocalDateTime> dateTimeDeserializer= (json, type, ctx) -> LocalDateTime.parse(json.getAsJsonPrimitive().getAsString(), dateTimeFormatter);private static final JsonDeserializer<LocalDate> dateDeserializer= (json, type, ctx) -> LocalDate.parse(json.getAsJsonPrimitive().getAsString(), dateFormatter);private static final JsonDeserializer<LocalTime> timeDeserializer= (json, type, ctx) -> LocalTime.parse(json.getAsJsonPrimitive().getAsString(), timeFormatter);private static final Gson gson;static {GsonBuilder builder = new GsonBuilder();builder.disableHtmlEscaping();builder.enableComplexMapKeySerialization();// builder.excludeFieldsWithoutExposeAnnotation();builder.setDateFormat("yyyy-MM-dd HH:mm:ss");builder.registerTypeAdapter(LocalDateTime.class, dateTimeSerializer);builder.registerTypeAdapter(LocalDate.class, dateSerializer);builder.registerTypeAdapter(LocalTime.class, timeSerializer);builder.registerTypeAdapter(LocalDateTime.class, dateTimeDeserializer);builder.registerTypeAdapter(LocalDate.class, dateDeserializer);builder.registerTypeAdapter(LocalTime.class, timeDeserializer);gson = builder.create();}public static Type makeJavaType(Type rawType, Type... typeArguments) {return TypeToken.getParameterized(rawType, typeArguments).getType();}public static String toString(Object value) {if (Objects.isNull(value)) {return null;}if (value instanceof String) {return (String) value;}return toJSONString(value);}public static String toJSONString(Object value) {return gson.toJson(value);}public static String toPrettyString(Object value) {return gson.newBuilder().setPrettyPrinting().create().toJson(value);}public static JsonElement fromJavaObject(Object value) {JsonElement result = null;if (Objects.nonNull(value) && (value instanceof String)) {result = parseObject((String) value);} else {result = gson.toJsonTree(value);}return result;}@SneakyThrowspublic static JsonElement parseObject(String content) {return JsonParser.parseString(content);}public static JsonElement getJsonElement(JsonObject node, String name) {return node.get(name);}public static JsonElement getJsonElement(JsonArray node, int index) {return node.get(index);}@SneakyThrowspublic static <T> T toJavaObject(JsonElement node, Class<T> clazz) {return gson.fromJson(node, clazz);}@SneakyThrowspublic static <T> T toJavaObject(JsonElement node, Type type) {return gson.fromJson(node, type);}public static <T> T toJavaObject(JsonElement node, TypeToken<?> typeToken) {return toJavaObject(node, typeToken.getType());}public static <E> List<E> toJavaList(JsonElement node, Class<E> clazz) {return toJavaObject(node, makeJavaType(List.class, clazz));}public static List<Object> toJavaList(JsonElement node) {return toJavaObject(node, new TypeToken<List<Object>>(){}.getType());}public static <V> Map<String, V> toJavaMap(JsonElement node, Class<V> clazz) {return toJavaObject(node, makeJavaType(Map.class, String.class, clazz));}public static Map<String, Object> toJavaMap(JsonElement node) {return toJavaObject(node, new TypeToken<Map<String, Object>>(){}.getType());}@SneakyThrowspublic static <T> T toJavaObject(String content, Class<T> clazz) {return gson.fromJson(content, clazz);}@SneakyThrowspublic static <T> T toJavaObject(String content, Type type) {return gson.fromJson(content, type);}public static <T> T toJavaObject(String content, TypeToken<?> typeToken) {return toJavaObject(content, typeToken.getType());}public static <E> List<E> toJavaList(String content, Class<E> clazz) {return toJavaObject(content, makeJavaType(List.class, clazz));}public static List<Object> toJavaList(String content) {return toJavaObject(content, new TypeToken<List<Object>>(){}.getType());}public static <V> Map<String, V> toJavaMap(String content, Class<V> clazz) {return toJavaObject(content, makeJavaType(Map.class, String.class, clazz));}public static Map<String, Object> toJavaMap(String content) {return toJavaObject(content, new TypeToken<Map<String, Object>>(){}.getType());}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/554660.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

keil 函数最多可以传几个参数_007 函数进阶,来做一次比较正式的作业

这节课开始之前&#xff0c;先来解决一个小问题。最近这两节课&#xff0c;有人对缩进的规则不太理解&#xff0c;这里解释一下。如上图所示&#xff0c;相同的缩进代表同一个代码块&#xff0c;即同一个顺序执行代码段落。如果代码缩进减少&#xff0c;则说明当前代码块结束&a…

信号回勾产生的原因_燃气减压阀振动的原因及处理方案

燃气减压阀是一种自动降低管路工作压力的专门装置&#xff0c;作用是在给定减压范围后&#xff0c;可以将较高压力的介质减到给定压力。它可将阀前管路较高的液气体压力减少至阀后管路所需的水平。燃气减压阀是各装置广泛使用的仪表之一&#xff0c;它准确正常地工作对保证工艺…

Java判断Bigdecimal类型是否等于0的方法

1.我之前用来判断Bigdecimal类型是否等于0的方法 b.equals(BigDecimal.ZERO); 用equals方法和BigDecimal.ZERO进行比较。 2.上面方法存在的问题 有一天&#xff0c;调用这个这句代码的时候&#xff0c;传入的确实是0&#xff0c;但却返回false 查看源代码发现&#xff1a;…

c++ _mkdir无法创建文件夹_Python脚本4:根据txt文本,批量创建文件夹

背景&#xff1a;深度学习图像分类的时候&#xff0c;有许多的标签类。1000个标签就需要创建1000个文件夹&#xff0c;文件夹里面放入对应的图像。不可能一个一个右击创建文件夹&#xff0c;所以有了今天的脚本。根据txt文本每一行的类别&#xff0c;创建文件名为类别的文件夹。…

grep -e命令详解_grep中的正则表达式

grep是Linux中用于处理文件的工具之一。grep搜索输入文件&#xff0c;查找与正则表达式匹配的行&#xff0c;并将每个匹配的行标准输出。正则表达式是匹配一组字符串的模式。模式由操作符、构造文字字符和具有特殊意义的元字符组成。grep支持三种正则表达式语法:Basic、Extende…

幼儿课外活动游戏_泰国清迈大小学校介绍 --【Little Star小星星幼儿园】

细数清迈的大小学校&#xff0c;主要分为国际学校和双语学校.一般国际学校的课程设置为10%的泰语&#xff0c;90%的英语&#xff0c;一些中文国际学校设置为20%-30%中文。国际学校可按照学制区分&#xff0c;美制、英制、德制、IB、新加坡等一系列课程。双语学校则为40%的泰语&…

Java8 Stream集合的筛选、归约、分组、聚合详解+案例

文章目录1 Stream概述2 Stream的创建3 Stream的使用案例使用的员工类3.1 遍历/匹配&#xff08;foreach/find/match&#xff09;3.2 筛选&#xff08;filter&#xff09;3.3 聚合&#xff08;max/min/count)3.4 映射(map/flatMap)3.5 归约(reduce)3.6 收集(collect)3.6.1 归集(…

liunx宝塔配置https_宝塔面板安装教程

宝塔面板安装教程原创 计科青年 今天首先登陆阿里云官网登陆你买的阿里云服务器打开服务器控制台&#xff0c;点击购买的服务器&#xff0c;点击实例&#xff0c;就可以看见自己的公网IP。1.下载Xshell6远程连接软件&#xff0c;打开软件点击文件新建这里推荐大家使用Xshell6进…

java用户角色权限管理 只显示姓_快递物流管理系统SSM,JQUERYEASYUI,MYSQL

快递物流管理系统(SSM,JQUERY-EASYUI,MYSQL)(毕业论文27564字,共78页,程序代码,MySQL数据库) 全套项目下载地址: http://woc.xin/WQBgtE【运行环境】 Eclipse, IDEA JDK1.7(JDK1.8) Tomcat7(Tomcat8)【技术栈】 JAVA, JSP, SSM, JQUERY, JQUERY EASYUI, MYSQL, HTML, CSS, JAVA…

判刑后再上诉会改判吗_近视眼手术后还会再近视反弹吗?有哪些后遗症,温州眼科专家告诉你...

经过几代的更新发展&#xff0c;近视眼手术的技术已相当成熟。激光近视手术受到越来越多近视患者的青睐&#xff0c;飞秒激光近视手术俨然成为目前矫正近视的新潮流。很多人以为&#xff0c;有了近视手术后便不需要注意近视的防控。轻松摘镜的背后&#xff0c;是彻夜狂欢&#…

dev c++调试怎么看变量的值_利用GDB调试 MSQL

原创 张政俊 老叶茶馆来自专辑MySQL修行作者&#xff1a;张政俊就职于中欧基金&#xff0c;知数堂粉丝&#xff0c;数据库爱好者&#xff0c;熟悉RDBMS、nosql、new sql等各类数据库。啃完Oreilly的《高性能mysql》、姜老师的《MySQL技术内幕》&#xff0c;再加上个2,3年的实战…

案例 自动办公_办公自动化案例教程(双色)(含微课)

办公自动化案例教程(双色)(含微课)ISBN:978-7-5165-1852-6作者&#xff1a;贺鑫 彭卫华 李胜华定价&#xff1a;48.00元出版社&#xff1a;航空工业出版社适用层次&#xff1a;通用出版日期&#xff1a;2020-05-01项目一 使用Word制作常用公文项目描述学习要点任务一 制作行政…

柱形图无数据可选中_Excel – 如何制作出上下层排列的柱形图?

如何将同一个数据表中的不同数据列排列成上下两层柱形图&#xff1f;案例&#xff1a;将下图 1 的数据表制作成柱形图&#xff0c;要求将销量和利润的柱形分成两个图表上下排列。效果如下图 2 所示。解决方案&#xff1a;1. 选中整个数据表区域 --> 选择菜单栏的“插入”--&…

html画布360图案填充_在Photoshop中创建带有图案的抽象设计

效果图知识点&#xff1a;应用选区工具结合图层混合模式和混合选项&#xff0c;创造出唯美的抽象类画册 效果设计本身由一系列同心圆组成&#xff0c;每组的大小各不相同。每个圆都有6个核心色板的底色&#xff0c;然后渐变和图案填充会增加细节和深度。我们需要创建图案填充。…

emd实现信息隐藏_EMD算法原理与实现

欢迎关注我们&#xff0c;选择加"星标"或“置顶”更多技术&#xff0c;第一时间送达SSVEP信号中含有自发脑电和大量外界干扰信号&#xff0c;属于典型的非线性非平稳信号。传统的滤波方法通常不满足对非线性非平稳分析的条件&#xff0c;1998年黄鄂提出希尔伯特黄变换…

转为yaml python_python 如何使用HttpRunner做接口自动化测试

作者&#xff1a;星安果 来源&#xff1a;AirPython1. 前言原始测试金子塔包含 3 层&#xff0c;分别是&#xff1a;UI 自动化测试、接口服务测试、单元测试其中&#xff0c;单元测试是对软件的最小可测试单元进行检查和验证&#xff0c;也是产生效率最大的一项测试接口服务测试…

eq值 推荐算法_利用 SVD 实现协同过滤推荐算法

奇异值分解(Singular Value Decomposition&#xff0c;以下简称SVD)是在机器学习领域广泛应用的算法&#xff0c;它不光可以用于降维算法中的特征分解&#xff0c;还可以用于推荐系统&#xff0c;以及自然语言处理等领域。优点&#xff1a;简化数据&#xff0c;去除噪声&#x…

打开数据库_打开这份指南,数据库运维也能优雅、简单!

对于常规数据库的运维监控来说&#xff0c;如何能够快速简洁的发现问题&#xff0c;直达问题本质并解决常见问题&#xff0c;是 Bethune 的安身立命之本。简约&#xff0c;优雅&#xff0c;专业&#xff0c;直抵本心&#xff0c;这是用户对 Bethune 的评价。Bethune X 功能强大…

mysql集群_MySQL集群

MySQL集群搭建之主从复制: 主从复制原理: 从库生成两个线程,一个I/O线程,一个SQL线程; i/o线程去请求主库 的binlog,并将得到的binlog日志写到relay log(中继日志) 文件中; 主库会生成一个 log dump 线程,用来给从库 i/o线程传binlog; SQL 线程,会读取relay log文件中…

mysql 数据库操作类_【数据库操作类】10个php操作数据库类下载

数据库(Database)操作是在开发过程中重要的组成部分&#xff0c;熟练掌握数据库的操作是开发人员必备的武器。PHP中文网为大家提供了各种封装好的php数据库操作类库&#xff0c;供大家下载和学习。相关mysql视频教程推荐&#xff1a;《mysql教程》php各种数据库操作类库下载PDO…