第一:jdbc的四大参数:
jdbc的本质是一套API(应用程序的接口。有driverManager类,connection接口,statement接口,resultset接口)
一:驱动管理
1.qq:是一个应用程序,在项目执行起来之后会产生大量的数据
2.应用程序:1.完成某些特定的功能。2完成对数据的管理
3.数据库:保存应用程序需要的数据和产生的数据。应用程序与数据库互动
4.数据要选放到应用程序中,然后在给用户看,用户不能直接访问数据库。
5.使用jdbc把应用程序(java程序)和数据库创建连接,完成数据的交互。
6.jdbc:java db connection:java与数据库连接技术
7.jdbc提供了一组标准的访问数据库的API(系统封装好的(api的中文含义是应用程序接口))。也就是提供了类和类封装的方法。
8. oracle和mysql数据库之间本身是有差异的,但是jdbc访问这两个数据库的过程是一模一样的(这就是jdbc所谓的标准),jdbc是怎么做到无论是什么
数据库都能用一套相同的程序来连接的?因为jdbc有一个驱动,这个驱动能够把不同的数据库都变成同一个模式(例如,把英文和法语都转化成汉语)。
9.也就是说:oracle公司为了能够连接java应用程序,oracle制作了一个oracle的驱动程序,有了oracle自己的驱动程序oracle就能访问java应用程序了。
mysql公司为了能够连接java应用程序,mysql制作了一个mysql的驱动程序,有了mysql自己的驱动程序mysql就能访问java应用程序了。
其实就是java公司先指定了一个访问条件,然后各个数据库公司为了能够访问(连接)java就做了自己的驱动用来连接java程序
10.java给我们提供了一个类,叫做驱动管理器,这个驱动管理器能够管理一组不同的驱动,并能根据当前使用的数据库加载(加载某一个驱动)与当前匹配的驱动(这时候屏蔽了数据库之间的差异。驱动也进入内存),这时候可以连接数据库了,使用API进行通信了。
二:驱动弄好后就能访问了(使用API)
DriverManager:加载特定的驱动
Connection:获得与特定数据库之间的连接
Statement:()发送sql语言(java把oracle语句发送给oracle)。创建了执行语句
ResultSet:封装sql语句执行的结果集(只能用在select语句)。(这是oracle给java发送过来的内容放在了ResultSet,跟上面那个对象正好相反)。
三:JRE System Library:这里面放着系统提供的jar包,因此我们可以直接用系统提供给我们的类。
如果我们想用jdbc提供给我们的类,我们就要把jdbc的jar包放在JRE System Library。之后这里出现了一个参考包
四:
注意:DriverManager类和Connection 接口里面全部是静态的方法。Statement是接口,Resultset是接口,通过意:DriverManager类可以获得所有接口了.
DriverManager是个驱动的集合,他有方法:getConnection是试图从各种驱动程序中选择合适的驱动,当第一行写的是Class.forName("oracle.jdbc.driver.OracleDriver")的时候,就将尝试连接oracle驱动,并连接成功。
1.加载驱动:Class.forName("oracle.jdbc.driver.OracleDriver");//把驱动类加载到内存。反射需要一个字符串(类名)作为参数。这个驱动类中有静态代码,加载后就能自动执行了。注意这个参数是包.类的写法,因此最后那个单词要符合类名的规范,也就是首字母大写。
创建了驱动类的对象,并注入到DriverManager中。 有异常是找不到这个类:1.是字符串写错了,2是没有导入jar包
2.数据库连接对象:Connection是个接口不能new(与特定数据库的连接(会话)),这个接口里面的方式是静态的。
Connection conn=DriverManager.getConnertion();(注意这里是接口对应着实现类的对象)这里面三个参数是用户名密码用来连接数据库,其实这个代码就相当于数据库的客户端,客户端访问服务器端
3.创建语句对象:statement stat=conn.createStatement();这个createStatement不是静态的方法
4.执行(增删改)语句对象:int row=stat.exexuteUpdate(sql);//发送并执行sql语句,用于增删改,返回值是受影响的行数
4.1执行(查询)语句对象(结果集对象):ResultSet res=stat.executeQuery()//产生结果集,就是一个表。遍历的时候用next
回顾知识点:
反射:反射是在程序开始运行的时候把类找到
静态的:静态的方法是在类运行的时候就在内存中执行了,因此以后在用的时候直接调用就行了。
这两个总结:Class.forName("oracle.jdbc.driver.OracleDriver")这句话表示在执行程序的时候加载OracleDriver这个类,这个是个驱动类,也就是加载了oracle的(不是mysql的)驱动,有了驱动就能连接数据库了
下面我们就用驱动类了: Connection conn=DriverManager.getConnertion();//通过不同的驱动建立不同的连接 。
注意:1.Class.forName("oracle.jdbc.driver.OracleDriver")是加载驱动并把驱动注册(或者说叫注入)到DriverManager中,DriverManager是管理一组驱动的。
2. Connection conn=DriverManager.getConnertion()是驱动管理器使用他的连接的方法,这个getConnertion试图在驱动管理器DriverManager中找驱动,由于上面的oracle注册到了DriverManager中,因此找到了也就是连接成功了。
第二:代码实现
1.使用Properties对象连接四大参数(张)
package dbutils;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class dbHandler {
/**这个类的目的是获取properties文件里的内容,而properties里面放的是四个参数,因此在这里声明四个变量,
* 用来表示properties文件里的四个参数。static的作用是让这几个参数随着类的加载而加载,这样提高效率,现在这里
* 不写final是因为这四个变量此时还没有赋值,还是null,所以不能是最终的
*/
private static String DRIVER;
private static String URL;
private static String USERNAME;
private static String PASSWORD;
/** 第一个方法:找到资源。注意:这个方法定义成了私有的,目的是只给下面的两个方法用
* 这个方法的作用是:让外面资源文件properties中的内容能在java程序中使用
* 步骤:1.定义一个方法,参数就是那个要使用的properties文件
* 2.通过本类的反射dbHandler.class,获取类加载器对象
* 3.转化成输入流对象(通过类加载器对象的getResourceAsStream方法(因为是stream,因此是个字节流),并传给输入流对象)
* 4.加载输入流对象(也就是加载properties里面的内容,持久化对象加载持久化里面的内容),并赋值(通过键找值)
*/
private static void getParam(String filename){
ClassLoader loader = dbHandler.class.getClassLoader();//通过这个类本身的反射,获得类加载器对象
InputStream inStream = loader.getResourceAsStream(filename);//通过类加载器对象的方法获得持久化文件中的资源,并传给字节输出流对象。注意这个方法找的是.class文件,文件的.class和类的.class文件放在一起了,因此在同一个目录下,不用写src这个路径
Properties p=new Properties();//创建持久化对象,通过这个对象把持久化文件中的值都复制到本类的变量里来
try {
p.load(inStream);//含义是:持久化对象.加载(持久化文件里面的内容),获得了含有四大参数的Properties对象
DRIVER=p.getProperty("driver");//通过资源文件中的键找到值,并赋值给上面定义的变量
URL=p.getProperty("url");//这四个值都传给了静态变量,因此在其他类调用的时候就不用创建dbHandler这个对象了,这就是为什么要把变量定义成静态的原因
USERNAME=p.getProperty("dbUser");//getProperty是属性值的意思,通过键找到属性值
PASSWORD=p.getProperty("dbPassword");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 这是第二个方法,是连接数据库的方法。
* 在连接数据库之前要加载OracleDriver类的驱动程序,连接数据库还需要地址,用户名和密码,
* 因此,要先调用getParam方法获得这四个参数的值
* 步骤:1.调用getParam方法 2.加载驱动 3.连接数据库
*/
public static Connection getConnection(){
getParam("dbOracle.properties");//调用上面的方法,因为上面的方法就是为了给连接和关闭方法是用的,四个参数都在getParam方法中
Connection conn=null;
try {
Class.forName(DRIVER);//加载驱动,获得驱动管理器对象
conn=DriverManager.getConnection(URL,USERNAME,PASSWORD);//通过驱动管理器对象的getConnection方法获得conn
System.out.println("连接成功");
} catch (ClassNotFoundException e) {
System.out.println("连接失败1");
e.printStackTrace();
} catch (SQLException e) {
System.out.println("连接失败2");
e.printStackTrace();
}
return conn;//返回连接的结果
}
/**这是第三个方法:关闭资源。不等系统的垃圾处理器自动回收,而是自己马上关闭资源
* 传入三个参数,从后往前关
* @param rs:结果集对象
* @param stmt:select语句对象
* @param conn:connection连接对象
*/
public static void getClose(ResultSet rs,Statement stmt,Connection conn){
if(rs!=null){
try {
rs.close();
System.out.println("关闭rs");
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
System.out.println("关闭stmt");
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
System.out.println("关闭conn");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
2.完成增删改查(张)
package demo.chu2;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import dbutils.dbHandler;
public class TestJDBC2 {
private static Statement stmt=null;
private static ResultSet rs=null;
private static Connection conn=dbHandler.getConnection();
public static void getData(String tablename){
String sql="select * from "+ tablename ;
//Statement stmt=null;
//ResultSet rs=null;
//Connection conn = dbHandler.getConnection();//静态方法类名调用。其实不用这样写,直接把这句话跟下面的内容写在一起就行了,因为所有的程序对于Connection接口的实现都是一样的
try {
stmt=conn.createStatement();//创建语句对象
rs=stmt.executeQuery(sql);//创建结果集对象
DatabaseMetaData dbmd=conn.getMetaData();//通过连接对象,获得数据库产品相关的元数据信息
System.out.println("当前oracle版本:"+dbmd.getDatabaseMajorVersion()+dbmd.getDatabaseProductName()+dbmd.getDriverName());//打印oracle版本
ResultSetMetaData rsmd=rs.getMetaData();//通过结果集对象,获得结果集元对象
int colsCount=rsmd.getColumnCount();//通过结果集元对象获得总列数
System.out.println("当前虚拟表的总列数:"+colsCount);
while(rs.next()){//遍历行
for(int i=1;i<=colsCount;i++){//遍历列
System.out.print(rs.getObject(i)+" ");//如果表中没有日期类型就能用getString,否则就只用getObject
}
System.out.println();
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
dbHandler.getClose(rs, stmt, conn);
}
}
//添加
public static void insertData(String tablename){
//Connection conn = dbHandler.getConnection();
//Statement stmt=null;
//ResultSet rs=null;
String sql="insert into " +tablename+" values('111','张三',80)";
String sql1="select * from "+ tablename;
try {
stmt=conn.createStatement();
int rows = stmt.executeUpdate(sql);
if(rows>0){
System.out.println("添加成功 ,行数:"+rows);
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
dbHandler.getClose(rs, stmt, conn);
}
}
//删除
public static void deleteData(String tablename){
String sql="delete from "+tablename+" where cid='104'";
try {
stmt=conn.createStatement();
int rows=stmt.executeUpdate(sql);
if(rows>0){
System.out.println("删除成功,条数:"+rows);
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
dbHandler.getClose(rs, stmt, conn);
}
}
//修改
public static void updateData(String tablename){
String sql="select * from "+tablename+" where cid='102'";
String sql1="update "+tablename+" set cname='李四' where cid='102' ";
try {
stmt=conn.createStatement();
rs=stmt.executeQuery(sql);
int r=stmt.executeUpdate(sql1);
if(r>0){
System.out.println("修改成功"+r);
}else{
System.out.println("error");
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
dbHandler.getClose(rs, stmt, conn);
}
}
public static void main(String[] args) {
//insertData("cou");//增
getData("cou");//查
//deleteData("cou");//删
//updateData("cou");//改
}
}
3.带问号的增删改查(严)
package com.dao.impl;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import com.comm.BaseDao;
import com.dao.NewsDao;
import com.entity.News;
public class NewsDaoImpl extends BaseDao implements NewsDao {
Connection conn=null;
PreparedStatement pstat=null;
ResultSet rs=null;
//添加
@Override
public int addNews(News news) {
int row=0;
try {
conn=super.getConnection();
String sql="insert into news values(?,?,?,sysdate,?)";
pstat=conn.prepareStatement(sql);
pstat.setInt(1, news.getNid());
pstat.setString(2,news.getNtitle());
pstat.setString(3,news.getNcontent());
pstat.setString(4,news.getAuthor());
row=pstat.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally{
super.getClose(conn, pstat, null);
}
return row;
}
//删除
@Override
public int delteNews(int id) {
int row=0;
try {
conn=super.getConnection();
String sql="delete from news where nid=?";
pstat=conn.prepareStatement(sql);
pstat.setInt(1, id);
row=pstat.executeUpdate();
} catch (Exception e) {
}finally{
super.getClose(conn, pstat, null);
}
return row;
}
//修改
@Override
public int updateNews(News news) {
int row = 0;
try{
conn=super.getConnection();
String sql="update news set ntitle=?,ncontent=?,author=? where nid=?";
pstat=conn.prepareStatement(sql);
pstat.setString(1, news.getNtitle());
pstat.setString(2, news.getNcontent());
pstat.setString(3, news.getAuthor());
pstat.setInt(4, news.getNid());
row=pstat.executeUpdate();
}catch(Exception ex){
ex.printStackTrace();
}finally{
super.getClose(conn, pstat, null);
}
return row;
}
//查询全部
@Override
public List<News> search() {
List<News> list=new ArrayList<News>();
try {
conn=super.getConnection();
String sql="select * from news";
pstat=conn.prepareStatement(sql);
rs=pstat.executeQuery();
while(rs.next()){
News news=new News();
news.setNid(rs.getInt("nid"));
news.setNtitle(rs.getString("ntitle"));
news.setNcontent(rs.getString("ncontent"));
news.setNdate(rs.getDate("ndate"));
news.setAuthor(rs.getString("author"));
list.add(news);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
System.out.println("集合长度:"+list.size());
super.getClose(conn, pstat, rs);
}
return list;
}
//按id查询
@Override
public News searchById(int id) {
News news=null;//先声明一个对象,如果能找到就创建这个对象并返回这个对象的内容,如果没找到就返回null,因为这里就是null
try {
conn=super.getConnection();
String sql="select * from news where nid=?";
pstat=conn.prepareStatement(sql);
pstat.setInt(1, id);
rs=pstat.executeQuery();
if(rs.next()){
news=new News();
news.setNid(rs.getInt("nid"));
news.setNtitle(rs.getString("ntitle"));
news.setNcontent(rs.getString("ncontent"));
news.setNdate(rs.getDate("ndate"));
news.setAuthor(rs.getString("author"));
}
} catch (Exception e) {
e.printStackTrace();
}finally{
super.getClose(conn, pstat, rs);
}
return news;
}
//批量删除1
@Override
public int batDelNews(int[] ids) {
int rows=0;
try {
conn=super.getConnection();
String sql="delete from news where nid in(";
for(int x=0;x<ids.length;x++){
if(x==ids.length-1){
sql=sql+ids[x]+")";
}else{
sql=sql+ids[x]+",";
}
}
pstat=conn.prepareStatement(sql);
rows=pstat.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}
return rows;
}
//批量删除2
public int batDelNews1(int[] ids) {
int rows=0;
try {
conn=super.getConnection();
String sql="delete from news where nid in(";
for(int x=0;x<ids.length;x++){
if(x==ids.length-1){
sql=sql+"?)";
}else{
sql=sql+"?,";
}
}
pstat=conn.prepareStatement(sql);
for(int x=0;x<ids.length;x++){
pstat.setObject(x+1, ids[x]);
}
rows=pstat.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}
return rows;
}
//存储过程完成求极值
public int max(){
CallableStatement call=null;
int m=0;
try {
conn=super.getConnection();
String sql="{call proc_max(?,?,?) }";//调用oracle数据库中的存储过程(比较两个数大小的存储过程)。第一个和第二个是输入参数,第三个是输出参数
call=conn.prepareCall(sql);//CallableStatement是preparedStatement的子类。prepareCall表示预定义存储过程,Call表示存储过程
call.registerOutParameter(3, Types.INTEGER);//定义第三个问号是输出参数,参数类型为int类型。前两个问号默认为输入参数
call.setInt(1, 100);//给第一个输入参数赋值
call.setInt(2, 101);//给第二个输入参数赋值
boolean flag = call.execute();
m=call.getInt(3);
} catch (Exception e) {
e.printStackTrace();
}finally{
//System.out.println("最大值为:"+add);
super.getClose(conn, call, null);
}
return m;
}
//存储过程完成求和
public int sum(){
CallableStatement pcall=null;
int s=0;
try{
conn=super.getConnection();
String sql="{call proc_add(?,?,?)}";
pcall = conn.prepareCall(sql);
pcall.setInt(1, 100);
pcall.setInt(2, 100);
pcall.registerOutParameter(3, Types.INTEGER);
pcall.execute();
s=pcall.getInt(3);
}catch(Exception ex){
ex.printStackTrace();
}finally{
super.getClose(conn, pcall, null);
}
return s;
}
}
第四:查询(张)
package demo.chu1;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class myjdbc01 {
//静态的,效率高
private static final String DRIVER="oracle.jdbc.driver.OracleDriver";//加载驱动类OracleDriver,这个字符串是这个驱动类的位置
private static final String URL="jdbc:oracle:thin:@localhost:1521:ORCL";//jdbc协议和数据库的网络位置
private static final String UNAME="chu1";
private static final String PWORD="1234";
//类加载的时候同时加载驱动,提高效率,由于每个程序都会要用到这个,所以把这个方法独立些出来,一是为了公用,二是为了随着类的加载而加载,提高速度
static{
//加载驱动,并注册驱动,加载OracleDriver驱动类,产生了驱动管理器对象,并注入DriverManager驱动管理器类中
//1 加载对应的数据库程序,是将class文件加载到内存,通过反射来完成,加载oracle的驱动,最后一个是类名,单词的首字母是大写
//其实也就是说OracleDriver这个类里面有静态代码,因为静态代码随着类的加载而加载,然后驱动管理器管理这些被加载的静态代码
try {
Class.forName(DRIVER);//ctrl+1
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static void getTableDate(){
//第一步:声明使用到的接口类型的变量,避免出了大括号就用不了
Connection conn=null;
Statement stmt=null;
ResultSet rs=null;
try {
//第二步:获得连接对象,因为在加载驱动的时候已经获得了驱动管理器对象
//DriverManager这个类里面全部是静态方法,类名调用,他里面就有个getConnection方法
conn=DriverManager.getConnection(URL, UNAME, PWORD);
//第三步:创建语句对象
stmt= conn.createStatement();
//第四步:执行sql语句,并产生结果集对象
String sql="select * from student";
rs=stmt.executeQuery(sql);
//第五步:移动指针,指向记录.rs.next()返回布尔类型的
while(rs.next()){
//第六步:提取当前记录的字段内容
int sno=rs.getInt(1);
String sname=rs.getString(2);
int sage=rs.getInt("sage");
String stel=rs.getString(4);
System.out.println(sno+" "+sname+" "+sage+" "+stel);
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
try {
rs.close();
stmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
getTableDate();
}
}
相关推荐
本篇将重点讨论"j2ee09:jdbc03:jdbc的最后封装(用到了反射)"这一主题,该主题涉及到JDBC的高级使用技巧,特别是如何通过反射来优化和简化数据库操作。 首先,我们来看“jdbc03”的部分。这可能是项目中的一个模块...
在J2EE应用程序开发中,数据访问是...总的来说,J2EE连接Oracle数据库进行增删改查涉及了JDBC、Model2架构、DAO设计模式和数据库操作的多个层面。理解并熟练掌握这些知识,对于开发高效、健壮的企业级应用至关重要。
在J2EE应用程序开发中,Hibernate是一个非常重要的ORM(对象关系映射)框架,它使得Java开发者能够方便地处理数据库操作,如增删改查(CRUD),而无需编写大量的SQL语句。本教程将详细介绍如何使用Hibernate实现...
在IT行业中,开发Web应用程序是常见的任务之一,而"myeclipse+mysql+jdbc+servlet增删改查"是一个典型的Web应用开发流程,涉及到的主要技术包括MyEclipse、MySQL数据库、Java JDBC(Java Database Connectivity)...
SSH整合开发实现的增删改查功能是Java Web开发中常见的应用场景,SSH指的是Struts2、Spring和Hibernate三个开源框架的组合。这三个框架在企业级应用开发中扮演着重要角色,帮助开发者构建高效、可维护的Web应用。...
这篇博文主要探讨了如何使用`logic`标签来实现数据的增删改查操作,以及它们在实际项目中的应用。 `logic`标签库是Struts 1.x时代的产物,虽然现在已经被更先进的技术如Spring MVC所取代,但在很多遗留系统或教学...
使用JDBC,开发者可以进行CRUD(创建、读取、更新、删除)操作,实现数据的增删改查。JDBC的使用步骤通常包括以下几步: 1. 加载数据库驱动:通过`Class.forName()`方法加载相应的数据库驱动。 2. 建立数据库连接:...
首先,`J2EE实现增删改查课程设计报告书.doc`可能详细介绍了如何在Java企业版(J2EE)环境下,通过编程来完成数据库的CRUD操作。这通常涉及到Servlet、JSP和JavaBeans等组件的使用,以及与数据库的连接和交互。 `...
这些文件提供了完整的STRUTS-HIBERNATE结合的示例,可以帮助开发者理解如何在实际项目中集成这两个框架,进行数据的增删改查操作。通过分析和学习这些源码,可以深入理解MVC架构和ORM思想,提升J2EE应用开发能力。
在J2EE(Java 2 Platform, Enterprise Edition)开发中,增删改查(CRUD:Create, Read, Update, Delete)是基本且至关重要的操作,涵盖了数据库中的数据管理核心功能。以下是对“J2EE增删改查经典代码”的详细解析...
通过XML保存JDBC相关配置(参考) 作者:13部王曦同学在学习J2EE的XML开发的小项目。 说明:做得越多,收获越多。 博文链接:https://java1573.iteye.com/blog/124704
现在,我们深入探讨一下这个"J2EE-SSH实现数据增删改查示例"所涉及的关键知识点。 首先,Struts是Apache软件基金会的一个开源项目,它是一个用于构建基于Java EE平台的MVC框架。在本示例中,Struts作为控制器负责...
**J2EE项目练习:JDBC+Struts** 在Java企业级开发中,J2EE(Java 2 Platform, Enterprise Edition)是一个标准平台,用于构建分布式、多层的Web应用程序。这个项目练习的核心是结合JDBC(Java Database ...
Java 企业版(Java 2 Platform, Enterprise Edition,简称 J2EE)是 Sun Microsystems 推出的用于构建分布式、多层企业级应用的框架。它为开发者提供了多种服务和组件模型,包括Java Servlets、JavaServer Pages ...
《J2EE实例:电子商城系统》是一款基于Java企业版(J2EE)技术构建的电子商务平台。这个实例深入展示了如何运用J2EE的核心组件,如Servlet、JSP、JavaBeans、EJB以及相关的框架(如Spring、Hibernate等),来实现一...
标题中的“j2ee22:json”暗示了我们正在探讨的是J2EE(Java 2 Platform, Enterprise Edition)框架的第22个主题,主要关注JSON(JavaScript Object Notation)技术的应用。JSON是一种轻量级的数据交换格式,广泛用于...