框架为我们做了什么?

1. SpringBoot

1.1 web服务器

Spring Boot 的 web 服务器原理主要基于其嵌入式服务器的概念,这意味着它内嵌了一个 web 服务器,无需部署到外部服务器上。Spring Boot 内嵌了如 TomcatJettyUndertowservlet 容器

1.2 servlet

Servlet(Server Applet)是 Java EE(Java Enterprise Edition)规范的一部分,它是一个运行在服务器端的Java程序,用于生成动态网页。Servlet 容器(如 Tomcat)负责管理 Servlet 的生命周期和执行。以下是 Servlet 编程的基本原理:

  1. Servlet 接口 :Servlet 必须实现 javax.servlet.Servlet 接口,该接口定义了五个方法:init(), service(), getServletConfig(), getServletInfo(), 和 destroy()

  2. Servlet 生命周期 : Servlet 的生命周期从实例化开始,通过 init() 方法初始化,然后可以接收服务请求,最后通过 destroy() 方法销毁。

  3. 请求处理 : Servlet 容器接收到客户端的请求后,会调用 Servlet 的 service() 方法,该方法根据请求的类型(如 GET 或 POST)决定调用 doGet()doPost() 方法。

  4. 多线程:Servlet 容器支持多线程,Servlet 容器可以创建多个 Servlet 实例或使用同一个 Servlet 实例的多个线程来处理并发请求。

  5. Servlet 映射 : Servlet 映射定义了 URL 到 Servlet 的映射关系。映射可以在 web.xml 文件中配置,也可以使用注解(如 @WebServlet)。

  6. 请求和响应对象 : Servlet 使用 HttpServletRequestHttpServletResponse 对象来与客户端进行交互。HttpServletRequest 包含了请求信息,而 HttpServletResponse 用于构造响应。

  7. 事件监听器 : Servlet API 提供了多种事件监听器,如 ServletContextListenerHttpSessionListener 等,它们可以在 Servlet 生命周期的关键时刻执行特定的操作。

  8. 过滤器 : Servlet 容器允许开发者实现 javax.servlet.Filter 接口来拦截请求和响应,进行预处理或后处理。

  9. 会话管理 : Servlet API 通过 HttpSession 对象支持会话管理,允许在多个页面请求之间保持状态。

  10. 安全: Servlet 容器和 Servlet 可以配置安全性,如使用声明式和编程式安全控制对资源的访问。

  11. Servlet 3.0 异步处理:Servlet 3.0 引入了异步处理机制,允许 Servlet 方法异步执行,不阻塞容器线程,提高应用程序的并发处理能力。

  12. 依赖注入: Servlet 3.0 还支持依赖注入(DI),可以直接在 Servlet 中注入服务和管理 Bean。

Servlet 编程模型为构建基于 Java 的服务器端应用程序提供了一种简单、一致和可扩展的方式。通过 Servlet,开发者可以生成动态内容、处理表单提交、与数据库交互等。

1.3 不依赖框架可以怎么做?

不使用 Spring 框架,您仍然可以使用 Java 的标准库 java.netjavax.servlet 来提供 HTTP 接口。以下是两种常见的方法:

1.3.1 使用 java.net

Java 的 java.net 包提供了基本的网络通信能力,可以用来创建简单的 HTTP 服务器。以下是一个使用 ServerSocketSocket 来处理 HTTP 请求的简单示例:

java 复制代码
import java.io.*;
import java.net.*;

public class SimpleHttpServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(8080);
        System.out.println("Server is listening on port 8080...");

        while (true) {
            Socket socket = serverSocket.accept();
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                if (!inputLine.isEmpty()) {
                    break;
                }
            }

            // 简单的请求处理逻辑
            String response = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nHello, World!";
            out.write(response);
            out.flush();

            // 关闭连接
            in.close();
            out.close();
            socket.close();
        }
    }
}

这个示例创建了一个在 8080 端口上监听的 HTTP 服务器,对于每个连接,它发送一个简单的响应 "Hello, World!"。

1.3.2 使用 javax.servlet

如果您想使用更接近现代 Web 应用的方法,可以使用 javax.servlet 包来创建一个基于 Servlet 的 HTTP 服务器。以下是一个使用 HttpServletHttpServer 的示例:

java 复制代码
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;

public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/plain");
        PrintWriter out = response.getWriter();
        out.println("Hello, World!");
    }

    public static void main(String[] args) throws Exception {
        HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
        Context context = server.createContext("/myapp", (servletRequest, servletResponse) -> {
            new MyServlet().doGet(servletRequest, servletResponse);
        });

        server.start();
        System.out.println("Server is started at port 8080...");
    }
}

这个示例创建了一个 Servlet,它在接收到 GET 请求时返回 "Hello, World!"。然后使用 HttpServer 来启动服务器,并定义了 URL 路径 /myapp 来映射到我们的 Servlet。

请注意,这些示例都是非常简单的基础示例,用于演示如何不使用 Spring 框架来提供 HTTP 接口。在实际开发中,您可能需要考虑更多的因素,比如请求解析、路由、错误处理、安全性、并发处理等。对于更复杂的应用,您可能需要使用更高级的 Web 服务器或框架。

2. Gin

2.1 web服务器

Gin 是一个用 Go 语言编写的 Web 框架,以其高性能和快速的开发效率而闻名。Gin 框架本身并不内嵌 Web 服务器,而是使用 Go 标准库中的 net/http 包来处理 HTTP 请求和响应。net/http 包提供了一个非常轻量级的 HTTP 服务器,它足以应对大多数 Web 应用的需求。

以下是 Gin 框架启动服务器的基本步骤:

  1. 创建路由: 使用 Gin 创建路由,定义应用程序的端点和对应的处理函数。

  2. 设置中间件: 可以设置中间件来处理跨域请求、日志记录、请求验证等。

  3. 启动服务器 : 使用 gin.Default()gin.New() 创建一个 Gin 实例,然后调用 Run 方法来启动服务器。Run 方法接受一个字符串参数,表示服务器监听的地址和端口。

  4. 监听端口 : Gin 使用 http.ListenAndServe 函数来监听指定的端口,等待客户端的连接。

  5. 处理请求: 当客户端发起请求时,Gin 会根据定义的路由规则将请求分发到对应的处理函数。

  6. 响应客户端: 处理函数执行完成后,Gin 会构造 HTTP 响应并发送给客户端。

下面是一个简单的 Gin 应用启动服务器的例子:

go 复制代码
package main

import (
    "github.com/gin-gonic/gin"
)

func main() {
    router := gin.Default() // 创建一个默认的 Gin 路由器

    // 定义路由
    router.GET("/", func(c *gin.Context) {
        c.JSON(200, gin.H{
{            "message": "hello world"}
        })
    })

    // 启动服务器,默认在 8080 端口监听
    router.Run(":8080")
}

在这个例子中,Gin 应用定义了一个处理根 URL (/) 的路由,当访问这个路由时,它会返回一个 JSON 响应。然后,使用 router.Run(":8080") 启动服务器,监听 8080 端口。

2.2 不依赖框架如何提供HTTP接口?

在 Go 语言中,即使不使用 Gin 框架,也可以通过标准库 net/http 来提供 HTTP 接口。以下是如何使用 Go 的 net/http 包来创建一个简单的 HTTP 服务器并提供接口的示例:

go 复制代码
package main

import (
    "fmt"
    "log"
    "net/http"
)

// 定义一个处理函数,它响应客户端请求
func myHandler(w http.ResponseWriter, r *http.Request) {
    // 设置响应的头部,指明返回的内容类型
    w.Header().Set("Content-Type", "text/plain")

    // 响应客户端请求
    fmt.Fprintf(w, "Hello, World! This is a simple HTTP interface.")
}

func main() {
    // 设置路由,将"/"路径的请求映射到myHandler处理函数
    http.HandleFunc("/", myHandler)

    // 定义服务器监听的端口
    port := "8080"

    // 启动服务器,阻塞等待请求
    log.Printf("Server starting on port %s", port)
    if err := http.ListenAndServe(":"+port, nil); err != nil {
        log.Fatal("ListenAndServe error: ", err)
    }
}

在这个示例中,我们首先定义了一个 myHandler 函数,它接收 http.ResponseWriter*http.Request 作为参数。http.ResponseWriter 用于构造 HTTP 响应,*http.Request 包含了请求的信息。

然后,我们使用 http.HandleFunc 来设置路由,将根路径("/")的请求映射到 myHandler 函数。

最后,我们使用 http.ListenAndServe 来启动服务器,它接受一个端口号和一个处理器(这里是 nil,因为我们已经使用 HandleFunc 设置了处理器)。服务器将阻塞等待请求,并在接收到请求时调用相应的处理函数。

这个简单的服务器将响应所有到根路径的 GET 请求,并返回 "Hello, World! This is a simple HTTP interface." 文本。

Go 的 net/http 包非常强大,它支持路由、中间件、文件服务、静态文件处理等,可以满足大多数 Web 服务的需求。对于更高级的用例,比如参数解析、JSON 响应、请求验证等,你可能需要编写更多的逻辑或使用第三方库。

3. MyBatis

3.1 MyBatis 原理

MyBatis 是一个半自动的持久层框架,用于在 Java 应用程序中简化数据库操作。它提供了简单的 API 和映射配置,以实现类型安全、对象关系映射(ORM)和 SQL 映射。以下是 MyBatis 的一些核心原理:
(1)SqlSessionFactorySqlSessionFactory 是 MyBatis 的核心对象,负责创建 SqlSession。它通过 XMLConfigBuilderXMLMapperBuilder 加载配置文件和映射文件来构建。

(2)SqlSessionSqlSession 是 MyBatis 工作的主要执行者,提供了执行命令对象(如 update, select, delete, insert)的方法,以及提交和回滚事务的功能。

(3)映射文件:MyBatis 使用 XML 或注解来映射 SQL 语句和 Java 类。这些映射文件定义了 SQL 语句和 Java 对象之间的映射关系。

(4)动态 SQL:MyBatis 支持动态 SQL,允许使用 if、choose、when、otherwise、trim、set 等元素来构建条件 SQL。

(5)参数映射:MyBatis 支持自动将 Java 对象的属性映射到 SQL 语句的参数上。

(6)结果映射 :MyBatis 支持将查询结果映射到 Java 对象。可以通过 <resultMap> 元素定义复杂的结果映射。

(7)一级缓存和二级缓存

  • SqlSession 提供了一级缓存,它是会话级别的缓存,用于存储查询结果。
  • MyBatis 还支持二级缓存,它是全局的,可以被多个 SqlSession 共享。

(8)插件机制:MyBatis 允许开发者编写插件来拦截方法的执行,实现自定义逻辑,如分页、审计等。

(9)配置和映射的分离:MyBatis 支持将配置和映射分离,使得 SQL 映射可以独立于配置文件存在。

(10)事务管理:MyBatis 支持声明式事务和编程式事务管理。

(11)MyBatis Generator:MyBatis 提供了代码生成器,可以根据数据库表结构自动生成映射文件和 Java 模型类。

(12)MyBatis 3 增强的映射特性 :MyBatis 3 引入了新的映射特性,如 @SelectProvider, @UpdateProvider, @InsertProvider, 和 @DeleteProvider 注解,允许使用 Java 代码提供 SQL 语句。

MyBatis 的设计哲学是提供足够的灵活性,让开发者可以编写高效的 SQL 语句,同时保持代码的简洁性和可维护性。通过 MyBatis,开发者可以避免大量的样板代码,并能够更精细地控制数据库操作。

3.2 不使用框架该怎么做?

使用 Java 的 JDBC API 直接操作数据库。JDBC 是 Java 语言中用来规范客户端程序如何访问数据库的应用程序接口,通过 JDBC 可以连接任何符合 SQL 数据库。

4. Gorm

4.1 Gorm原理

Gorm 是 Go 语言的一个对象关系映射(ORM)库,用于操作各种 SQL 数据库系统。它提供了一个简单易用的 API 来与数据库进行交互,同时隐藏了底层 SQL 语句的复杂性。以下是 Gorm 的一些核心原理:
(1)连接管理 :Gorm 管理数据库连接,允许配置多个数据源,并在它们之间进行切换。
(2)自动迁移 :Gorm 支持自动迁移功能,可以自动创建或修改数据库表结构以匹配 Go 结构体的定义。
(3)事务处理 :提供了事务的支持,可以确保数据的一致性和完整性。
(4)关联处理 :支持定义模型之间的关联关系,如一对一、一对多和多对多。
(5)预加载 :支持预加载(Eager Loading)关联数据,以减少数据库查询次数。
(6)懒加载 :支持懒加载(Lazy Loading)关联数据,按需从数据库加载数据。
(7)条件查询 :支持链式调用,可以方便地构建复杂的查询条件。
(8)批量操作 :支持批量创建、更新和删除记录。
(9)事务回滚 :在发生错误时,可以回滚事务,保证数据操作的原子性。
(10)自定义操作 :允许自定义 SQL 语句或使用原生数据库驱动的函数。
(11)日志记录 :提供了详细的 SQL 日志记录功能,方便调试。
(12)结果映射 :将查询结果映射到 Go 结构体中,简化了结果处理。
(13)插件系统 :Gorm 拥有丰富的插件系统,可以扩展其功能,如添加新的数据库类型支持。
(14)接口和抽象 :Gorm 提供了一系列接口和抽象,使得替换底层数据库驱动或自定义行为变得简单。
(15)兼容性:支持多种 SQL 数据库,如 MySQL, PostgreSQL, SQLite, SQL Server 等。

Gorm 的工作原理基于以下几个步骤:

  • 定义模型:使用 Go 的结构体定义数据模型,Gorm 会根据这些结构体来生成和操作数据库表。
  • 连接数据库 :使用 Gorm 的 gorm.Open() 方法连接到数据库。
  • 创建/更新记录 :使用 Create(), Save(), Update() 等方法操作数据库记录。
  • 查询记录 :使用 Find(), First(), Scan() 等方法查询数据库。
  • 删除记录 :使用 Delete() 方法从数据库中删除记录。
  • 关闭数据库连接 :操作完成后,使用 Close() 方法关闭数据库连接。

Gorm 通过简化数据库操作,让开发者能够更专注于业务逻辑,而不是底层的 SQL 语句。同时,它保留了足够的灵活性,允许在需要时执行自定义的 SQL 操作。

4.2 不使用框架该怎么做?

如果不使用 Gorm 框架,你仍然可以使用 Go 语言的 database/sql 标准库来直接与数据库进行交互。以下是不使用 Gorm 框架实现数据库操作的一些基本步骤:
(1)导入包 :导入 database/sql 包以及其他可能需要的包,如 fmt 用于格式化输出,log 用于记录日志。
(2)配置数据源 :使用正确的驱动和连接字符串配置数据源。
(3)创建数据库连接 :使用 sql.Open() 函数创建到数据库的连接。
(4)准备 SQL 语句 :使用 db.Prepare() 准备 SQL 语句,这有助于提高性能并防止 SQL 注入。
(5)执行 SQL 语句 :使用 Exec(), Query()QueryRow() 执行 SQL 语句。
(6)处理结果 :使用 RowsRow 对象来迭代查询结果。
(7)错误处理 :检查并处理可能发生的错误。
(8)关闭资源 :使用 Close() 方法关闭 Rows, StmtDB 对象以释放资源。
(9)事务处理 :使用 Tx 对象管理事务。

下面是一个简单的示例,演示了如何使用 database/sql 包执行一个查询并将结果打印出来:

go 复制代码
package main
import (
    "database/sql"
    "fmt"
    "log"

    _ "github.com/go-sql-driver/mysql" // 导入 MySQL 驱动
)

func main() {
    // 配置数据源
    dsn := "username:password@/dbname?charset=utf8&parseTime=True&loc=Local"
    db, err := sql.Open("mysql", dsn)
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    // 测试连接
    err = db.Ping()
    if err != nil {
        log.Fatal(err)
    }

    // 准备 SQL 语句
    rows, err := db.Query("SELECT id, name FROM users")
    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()

    // 处理结果
    var id int
    var name string
    for rows.Next() {
        err = rows.Scan(&id, &name)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Printf("ID: %d, Name: %s\n", id, name)
    }

    // 检查可能的错误
    err = rows.Err()
    if err != nil {
        log.Fatal(err)
    }
}

在这个示例中,我们首先导入了 MySQL 的驱动(需要使用 go get 命令安装),然后配置了数据源字符串(DSN),接着创建了数据库连接并测试了连接的有效性。之后,我们准备并执行了一个 SQL 查询,迭代结果集并打印出每行的数据。最后,我们检查并处理了可能发生的错误。

请注意,实际开发中还需要考虑 SQL 注入防护、更复杂的错误处理、日志记录、配置和查询参数化等因素。此外,你可能需要编写额外的代码来处理数据库迁移、模型定义、关联关系等高级功能。

相关推荐
拖把湛屎,戳谁谁死7 小时前
SpringMVC的基本使用
java·spring·tomcat
咖啡煮码13 小时前
深入剖析Tomcat(十二) 详解StandardContext
java·spring boot·tomcat
weixin_5214296116 小时前
实操Nginx+Tomcat多实例部署,实现负载均衡和动静分离
nginx·tomcat·负载均衡
castlooo20 小时前
记录一次Apache Tomcat 处理返回自定义的404页面
java·tomcat·apache
ZZDICT1 天前
Tomcat session复制及session共享技术
tomcat·session共享
德乐懿1 天前
Tomcat高效部署与性能优化
java·性能优化·tomcat
海螺炒面1 天前
ServletConfig与ServletContext详解
java·servlet·tomcat
今日信息差2 天前
6月29日,每日信息差
java·大数据·人工智能·ffmpeg·tomcat
mayo的自留地2 天前
window10/11如何下载安装JDK(jdk) 超详细图文教程
java·开发语言·jvm·spring·servlet·tomcat·nio