框架为我们做了什么?

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 注入防护、更复杂的错误处理、日志记录、配置和查询参数化等因素。此外,你可能需要编写额外的代码来处理数据库迁移、模型定义、关联关系等高级功能。

相关推荐
次次皮1 天前
Linux 下通过 XShell 手动更新 Tomcat 应用并重启
前端·tomcat·jar
Listen·Rain2 天前
用AI开发出一个AI
java·人工智能·spring boot·tomcat·intellij-idea·mybatis·visual studio
Full Stack Developme3 天前
SpringBoot 内嵌 Tomcat 的启动流程
spring boot·后端·tomcat
Full Stack Developme3 天前
Tomcat 如何处理HTTP请求
java·http·tomcat
Full Stack Developme4 天前
Tomcat 设计原理
java·tomcat
Full Stack Developme4 天前
Tomcat NIO连接器内部如何实现零拷贝 Session管理如何实现集群同步
java·tomcat·nio
BullSmall5 天前
Tomcat 部署 Jenkins → Docker Jenkins 完整迁移方案
docker·tomcat·jenkins
baozhengw6 天前
信创改造-SpringBootJar包改为WAR包部署Tomcat
java·tomcat
Java面试题总结11 天前
mybatis插件
java·tomcat·mybatis
左左右右左右摇晃11 天前
手写Tomcat原理整理
java·开发语言·笔记·tomcat