JavaWeb初学
1.idea选择新建项目——java——Web Application,选择路径。
2.Add configuration——Tomcat——Local——选择部署。
3.(可选)热部署,修改后不需要重新启动服务自动更新加载。
1.配置登录页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%--<!DOCTYPE html>--%> <html> <head> <%-- <link href="${pageContext.request.contextPath}/WEB-INF/mod.css" rel="stylesheet" type="text/css">--%> <title>登录页面</title> <style type="text/css"> h1{ text-align: center; } form{ text-align: center; } </style> </head> <body> <h1>登录页面</h1> <form action="login" method="get"> 账号:<input type="text" name="UserName"><br> 密码:<input type="text" name="PassWord"><br> <input type="submit" value="登录"> </form> </form> </body> </html>

<!-- 配置首页--> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list>

<!--配置首页form action跳转--> <servlet> <servlet-name>login</servlet-name> <servlet-class>com.dl.login.LoginServlet</servlet-class> <!-- 这里写LoginServlet路径--> </servlet> <servlet-mapping> <servlet-name>login</servlet-name> <!-- name与前面servlet-name匹配--> <url-pattern>/login</url-pattern> <!-- 这里对应form中action--> </servlet-mapping>
2.配置页面请求
LoginServlet:

package com.dl.login; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTF-8"); resp.setCharacterEncoding("GBK"); String name = req.getParameter("UserName"); String password = req.getParameter("PassWord"); if ((name != null && password != null) && name.equals("admin") && password.equals("123456"))//这里应该是从数据库中查找数据 { //登录成功 req.setAttribute("name",name); req.getRequestDispatcher("/home").forward(req,resp);//页面转发 } else { //登录失败 //页面转发or页面重定向 resp.sendRedirect("error.jsp");//重定向 } // super.doGet(req, resp);不用这句 } }
HomeServlet:
(含 页面转发数据处理 and 不知怎么称呼的前端写法(弹性布局?))

package com.dl.login; import com.dl.entity.goods; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList; import java.util.List; @WebServlet("/home") public class HomeServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // super.doGet(req, resp); List<goods> list = new ArrayList<>(); //这里应该从数据库里获取商品数据 list.add(new goods("平板", "详细介绍", "电子产品", 998)); list.add(new goods("手机", "详细介绍", "电子产品", 998)); list.add(new goods("电脑", "详细介绍", "电子产品", 998)); list.add(new goods("衣服", "详细介绍", "服装产品", 98)); list.add(new goods("裤子", "详细介绍", "服装产品", 128)); list.add(new goods("鞋子", "详细介绍", "服装产品", 68)); list.add(new goods("洗衣液", "详细介绍", "生活用品", 38)); list.add(new goods("沐浴露", "详细介绍", "生活用品", 999)); req.setAttribute("lt", list); req.getRequestDispatcher("home.jsp").forward(req,resp);//页面转发,携带数据 } }

package com.dl.entity; //实体类 商品的实体类 public class goods { private String name,info,kind; private double price; public goods(String name) { this.name = name; } public goods(String name, String info, String kind, double price) { this.name = name; this.info = info; this.kind = kind; this.price = price; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } public String getKind() { return kind; } public void setKind(String kind) { this.kind = kind; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } @Override public String toString() { return "goods{" + "name='" + name + '\'' + ", info='" + info + '\'' + ", kind='" + kind + '\'' + ", price=" + price + '}'; } }
3.任意配置页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>错误页面</title> </head> <body> <h1 align="center">您登录账号或密码错误</h1> <h1 align="center">点击<a href="login.jsp">返回</a>登录页面</h1> </body> </html>
4.JDBC连接数据库
建数据库表示范:
对应实体类:

package com.dl.entity; public class User { private Integer id; private String name,password; public User() { } public User(Integer id, String name, String password) { this.id = id; this.name = name; this.password = password; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", password='" + password + '\'' + '}'; } }

package com.dl.dao; import com.dl.entity.User; import com.dl.utils.JDBCUtils; import java.sql.*; import java.util.ArrayList; import java.util.List; public class UserDao { Connection con = null; PreparedStatement pt = null; public List<User> GetAllUser() throws ClassNotFoundException, SQLException { con = JDBCUtils.getConnection(); List<User> users = new ArrayList<>(); String sql = "select * from user"; try { pt = con.prepareStatement(sql); ResultSet res = pt.executeQuery(); while (res.next()) { User user = new User(res.getInt("id"), res.getString("name"), res.getString("password")); users.add(user); } } catch (SQLException e) { e.printStackTrace(); } finally { con.close(); } return users; } }

package com.dl.utils; import java.io.InputStream; import java.sql.*; import java.sql.Connection; import java.util.Properties; public class JDBCUtils { static Properties p = new Properties(); static { try { Class.forName("com.mysql.cj.jdbc.Driver"); } catch (Exception e) { e.printStackTrace(); } try (InputStream is = JDBCUtils.class.getResourceAsStream("/db.properties")) { p.load(is); } catch (Exception e) { e.printStackTrace(); } } public static Connection getConnection() { try { Connection con = DriverManager.getConnection(p.getProperty("str"), p.getProperty("name"), p.getProperty("password")); return con; } catch (Exception e) { e.printStackTrace(); return null; } } public static void closeConnect(Connection con, PreparedStatement st, ResultSet re) { try { if (con != null) con.close(); } catch (Exception e) { e.printStackTrace(); } try { if (st != null) st.close(); } catch (Exception e) { e.printStackTrace(); } try { if (re != null) re.close(); } catch (Exception e) { e.printStackTrace(); } } }

str= jdbc:mysql://localhost:3306/javaweb?useUnicode=true&characterEncoding=utf8 name=root password=root
5.Service层,写入功能

package com.dl.service; import com.dl.dao.UserDao; import com.dl.entity.User; import java.sql.SQLException; import java.util.List; public class UserService { UserDao userDao = new UserDao(); public boolean Login(String name, String password) throws SQLException, ClassNotFoundException { List<User> users = userDao.GetAllUser(); System.out.println("开始查找"); for (User user : users) { System.out.println(user); if (user.getName().equals(name) && user.getPassword().equals(password)) return true; } return false; } }
到这里以及可以实现了基本的页面登录。
6.添加商品页面,商品实体类,对商品查询,搜索,添加,修改,删除。

insert goods values(null,"平板","快捷方便又省电","电子产品",998); insert goods values(null,"小米手机","人手必备","电子产品",1998); insert goods values(null,"华为电脑","高大上不解释","电子产品",6998); insert goods values(null,"衣服","丝滑上档次","服装产品",98); insert goods values(null,"裤子","透气且舒适","服装产品",98); insert goods values(null,"鞋子","适合滑铲","服装产品",178); insert goods values(null,"沐浴露","芳香四溢","生活用品",68); insert goods values(null,"洗衣液","很快的","生活用品",28);

package com.dl.entity; //实体类 商品的实体类 public class Goods { private Integer id; private String name, info, kind; private double price; public Goods() { } public Goods(Integer id, String name, String info, String kind, double price) { this.id = id; this.name = name; this.info = info; this.kind = kind; this.price = price; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } public String getKind() { return kind; } public void setKind(String kind) { this.kind = kind; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } @Override public String toString() { return "Goods{" + "id=" + id + ", name='" + name + '\'' + ", info='" + info + '\'' + ", kind='" + kind + '\'' + ", price=" + price + '}'; } }

package com.dl.dao; import com.dl.entity.Goods; import com.dl.utils.JDBCUtils; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; public class GoodsDao { Connection con = null; PreparedStatement pt = null; // 查询所有商品+搜索商品 public List<Goods> GetAllGoods() throws SQLException { con = JDBCUtils.getConnection(); List<Goods> goodsList = new ArrayList<>(); String sql = "select * from goods"; try { pt = con.prepareStatement(sql); ResultSet res = pt.executeQuery(); while (res.next()) { Goods goods = new Goods(res.getInt("id"), res.getString("name"), res.getString("info"), res.getString("kind"), res.getDouble("price")); goodsList.add(goods); } } catch (SQLException e) { e.printStackTrace(); } finally { con.close(); } return goodsList; } //添加商品 public boolean AddGoods(Goods goods) throws SQLException { try { con = JDBCUtils.getConnection(); String sql = "insert goods values(NULL,?,?,?,?)"; pt = con.prepareStatement(sql); pt.setString(1, goods.getName()); pt.setString(2, goods.getInfo()); pt.setString(3, goods.getKind()); pt.setDouble(4, goods.getPrice()); if (pt.executeUpdate() > 0) return true; } catch (SQLException e) { e.printStackTrace(); } finally { con.close(); } return false; } //删除商品 public boolean DelGoods(Goods goods) throws SQLException { try { con = JDBCUtils.getConnection(); String sql = "delete from goods where name=? and kind=? and price=?"; pt = con.prepareStatement(sql); pt.setString(1, goods.getName()); pt.setString(2, goods.getKind()); pt.setDouble(3, goods.getPrice()); if (pt.executeUpdate() > 0) return true; } catch (SQLException e) { e.printStackTrace(); } finally { con.close(); } return false; } //修改商品 public boolean UpdataGoods(Goods goods) throws SQLException { try { con = JDBCUtils.getConnection(); String sql = "update goods set name=?,info=?,kind=?,price=? where id=?"; pt = con.prepareStatement(sql); pt.setString(1, goods.getName()); pt.setString(2, goods.getInfo()); pt.setString(3, goods.getKind()); pt.setDouble(4, goods.getPrice()); pt.setInt(5, goods.getId()); if (pt.executeUpdate() > 0) return true; } catch (SQLException e) { e.printStackTrace(); } finally { con.close(); } return false; } }

package com.dl.service; import com.dl.dao.GoodsDao; import com.dl.entity.Goods; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; public class GoodsService { GoodsDao goodsDao = new GoodsDao(); private boolean check(Goods x, Goods y) { if (y.getName() != null && x.getName().equals(y.getName())) return true; if (y.getInfo() != null && x.getInfo().equals(y.getInfo())) return true; if (y.getKind() != null && x.getKind().equals(y.getKind())) return true; if (y.getPrice() != 0 && x.getPrice() == y.getPrice()) return true; return false; } //查询所有商品 public List<Goods> GetAllGoods() throws SQLException { List<Goods> goodsList = goodsDao.GetAllGoods(); return goodsList; } //搜索商品 public List<Goods> findGoods(Goods goods) throws SQLException { List<Goods> goodsList = goodsDao.GetAllGoods(); List<Goods> ans = new ArrayList<>(); for (Goods i : goodsList) { if (check(i, goods)) ans.add(i); } return ans; } // 添加商品 public boolean AddGoods(Goods goods) throws SQLException { boolean flag = goodsDao.AddGoods(goods); return flag; } //删除商品 public boolean DelGoods(Goods goods) throws SQLException { boolean flag = goodsDao.DelGoods(goods); return flag; } //根据id修改商品 public boolean UpdataGoods(Goods goods) throws SQLException { boolean flag = goodsDao.UpdataGoods(goods); return flag; } }
临时homeservlet和home.jsp(home.jsp页面可显示\隐藏商品操作):

<%@ page import="com.dl.entity.Goods" %> <%@ page import="java.util.List" %><%-- Created by IntelliJ IDEA. User: Admin Date: 2022/5/14 Time: 16:25 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>商品管理页面</title> <link href="static/mod.css" rel="stylesheet" type="text/css"> <link rel="shortcut icon" href="static/images/mini.ico" type="image/x-icon"/> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script> $(document).ready(function () { $(".hide").click(function () { $(".pic").hide(1000); }); $(".show").click(function () { $(".pic").show(1000); //alert("显示方法完成") }); $("form").submit(function () { alert("提交成功"); }) $('.card>li').click(function () { $(".look").children('.look>li').toggle(); // $(".look").siblings().children('.look>li').hide(); }) $('.card>li').click(function () { $(".lookform").children('.lookform>form').toggle(); // $(".lookform").siblings().children('.lookform>form').hide(); }) }); </script> </head> <body> <h1 align="center">商品列表</h1> <table align="center" cellspacing="0" cellpadding="10px" border="1px"> <tr> <td>商品名称</td> <td>商品简介</td> <td>商品类别</td> <td>商品价格</td> </tr> <% List<Goods> list = (List<Goods>) request.getAttribute("lt"); if (list != null) { for (Goods i : list) { %> <tr> <td><%=i.getName()%> </td> <td><%=i.getInfo()%> </td> <td><%=i.getKind()%> </td> <td width="150px"><%=i.getPrice()%> </td> <%-- 这里width无效--%> </tr> <% } } %> </table> <ul class="card"> <li>添加商品</li> <li>删除商品</li> <li>修改商品</li> </ul> <h3><%=request.getAttribute("back")%></h3> <ul class="look"> <li>看不见我</li> <li>看不见我</li> <li>看不见我</li> </ul> <div class="lookform"> <form style="text-align: center"action="/home" method="get"> <p>输入商品信息:</p> 名字:<input type="text" name="goodsname"><br> 简介:<input type="text" name="info"><br> 类别:<input type="text" name="kind"><br> 价格:<input type="text" name="price"><br> <input type="submit" value="提交"> </form> </div> <%--<button class="hide">隐藏表格</button>--%> <%--<button class="show">显示表格</button>--%> <%--<div class="pic" style="text-align: center">--%> <%-- <p>添加商品信息:</p>--%> <%-- <form style="text-align: center" action="" method="get">--%> <%-- 名字:<input type="text" name="name"><br>--%> <%-- 简介:<input type="text" name="info"><br>--%> <%-- 类别:<input type="text" name="kind"><br>--%> <%-- 价格:<input type="text" name="price"><br>--%> <%-- <input type="submit" value="提交">--%> <%-- </form>--%> <%--</div>--%> </body> </html>

package com.dl.login; import com.dl.entity.Goods; import com.dl.service.GoodsService; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; @WebServlet("/home") public class HomeServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTF-8"); resp.setCharacterEncoding("GBK"); String back = ""; if (req.getParameter("goodsname") != null && !req.getParameter("goodsname").equals("")) { GoodsService goodsService = new GoodsService(); Goods goods = new Goods(); goods.setName(req.getParameter("goodsname")); goods.setInfo(req.getParameter("info")); goods.setKind(req.getParameter("kind")); String price = req.getParameter("price"); if (!"".equals(price)) goods.setPrice(Double.parseDouble(price)); else goods.setPrice(0); System.out.println(goods); try { boolean flag = goodsService.AddGoods(goods); //String back = ""; if (flag) back = "成功添加商品!"; else back = "添加商品失败!"; req.setAttribute("back", back); } catch (SQLException e) { e.printStackTrace(); } } List<Goods> list = new ArrayList<>(); //这里从数据库里获取商品数据 GoodsService goodsService = new GoodsService(); try { list = goodsService.GetAllGoods(); } catch (SQLException e) { e.printStackTrace(); } req.setAttribute("lt", list); req.getRequestDispatcher("home.jsp").forward(req, resp);//页面转发,携带数据 } }
2022.5.19,整理了home.jsp,添加了prepareservlet——为home页面提供增删改操作。异步添加和修改,同步(页面转发)删除。

package com.dl.login; import com.dl.entity.Goods; import com.dl.service.GoodsService; import javax.servlet.AsyncContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.sql.SQLException; @WebServlet("/prepare") public class PrepareServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //设置请求编码 req.setCharacterEncoding("UTF-8"); //设置响应编码 resp.setCharacterEncoding("UTF-8"); resp.setContentType("text/html;charset=UTF-8"); String back = "fail"; String way = req.getParameter("way"); System.out.println("way==" + way); GoodsService goodsService = new GoodsService(); if (way.equals("1")) { //添加商品 Goods goods = new Goods(); goods.setName(req.getParameter("goodsname")); goods.setInfo(req.getParameter("info")); goods.setKind(req.getParameter("kind")); String price = req.getParameter("price"); if (!"".equals(price)) goods.setPrice(Double.parseDouble(price)); else goods.setPrice(0); try { boolean flag = goodsService.AddGoods(goods); if (flag == true) back = "success"; } catch (SQLException e) { e.printStackTrace(); } } else if (way.equals("2")) { //删除商品 Integer id = Integer.valueOf(req.getParameter("id")); try { boolean flag = goodsService.DelGoods(id); if (flag == true) back = "success"; } catch (SQLException e) { e.printStackTrace(); } req.getRequestDispatcher("/home").forward(req, resp);//页面转发 } else { //修改商品 Goods goods = new Goods(); goods.setId(Integer.valueOf(req.getParameter("id"))); goods.setName(req.getParameter("goodsname")); goods.setInfo(req.getParameter("info")); goods.setKind(req.getParameter("kind")); String price = req.getParameter("price"); if (!"".equals(price)) goods.setPrice(Double.parseDouble(price)); else goods.setPrice(0); try { boolean flag = goodsService.UpdateGoods(goods); if (flag == true) back = "success"; } catch (SQLException e) { e.printStackTrace(); } } resp.getWriter().write(back); } }

<%@ page import="com.dl.entity.Goods" %> <%@ page import="java.util.List" %><%-- Created by IntelliJ IDEA. User: Admin Date: 2022/5/14 Time: 16:25 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>商品管理页面</title> <link href="static/mod.css" rel="stylesheet" type="text/css"> <link rel="shortcut icon" href="static/images/mini.ico" type="image/x-icon"/> <script src="static/jquery-3.3.1.js"></script> <script> $(document).ready(function () { $(".lookform").children().hide(); }) </script> </head> <body> <h1 align="center">商品列表</h1> <ul class="card"> <li class="a pick">添加商品</li> <li class="b pick">修改商品</li> </ul> <table align="center" cellspacing="0" cellpadding="10px" border="1px"> <tr> <td width="150px">商品序号</td> <td width="150px">商品名称</td> <td width="150px">商品简介</td> <td width="150px">商品类别</td> <td width="150px">商品价格</td> <td>操作</td> </tr> <% List<Goods> list = (List<Goods>) request.getAttribute("lt"); if (list != null) { for (Goods i : list) { %> <tr> <td> <%=i.getId()%> </td> <td> <%=i.getName()%> </td> <td> <%=i.getInfo()%> </td> <td> <%=i.getKind()%> </td> <td> <%=i.getPrice()%> </td> <td class="pick"> <a href="/prepare?way=2&id=<%=i.getId()%>">删除</a> </td> <%-- 这里width无效--%> </tr> <% } } %> </table> <hr> <div class="form"> <div class="lookform"> <div class="a"> 添加商品表<br> 名字:<input type="text" class="goodsname"><br> 简介:<input type="text" class="info"><br> 类别:<input type="text" class="kind"><br> 价格:<input type="text" class="price"><br> <input type="submit" class="submit" value="提交"> </div> </div> <div class="lookform"> <form class="b"> 修改商品表<br> id:<input type="text" class="id" placeholder="修改的商品的id"><br> 名字:<input type="text" class="goodsname"><br> 简介:<input type="text" class="info"><br> 类别:<input type="text" class="kind"><br> 价格:<input type="text" class="price"><br> <input type="submit" class="submit" value="提交"> </form> </div> </div> <script> // $(document).ready(function () { // };适用于页面加载完成后立即执行一次的函数 $(".hide").click(function () { $(".pic").hide(1000); }); $(".show").click(function () { $(".pic").show(1000); //alert("显示方法完成") }); $("form").submit(function () { alert("提交成功"); }) $('.pick>a').click(function () { alert("删除商品成功!"); }) $('.card .a').click(function () { $(".lookform").children('.a').toggle(); $(".lookform").children('.b').hide(); }); $('.card .b').click(function () { $(".lookform").children('.a').hide(); $(".lookform").children('.b').toggle(); }); $('.a>.submit').click(function () { var goodsname = $('.a>.goodsname').val(); var info = $('.a>.info').val(); var kind = $('.a>.kind').val(); var price = $('.a>.price').val(); $.ajax({ url: '/prepare', data: { way: '1', goodsname: goodsname, info: info, kind: kind, price: price }, type: 'get', success: function (res) { if (res == "success") { alert("添加商品成功!"); window.location.reload(); } else alert("添加商品失败!"); }, error: function () { alert("系统异常!"); } }) }); $('.b>.submit').click(function () { var id = $(".id").val(); var goodsname = $('.b>.goodsname').val(); var info = $('.b>.info').val(); var kind = $('.b>.kind').val(); var price = $('.b>.price').val(); $.ajax({ url: '/prepare', data: { way: '3', id: id, goodsname: goodsname, info: info, kind: kind, price: price }, type: 'get', success: function (res) { if (res == "success") { alert("修改商品成功!"); window.location.reload(); } else alert("修改商品失败!"); }, error: function () { alert("系统异常!"); } }) }) </script> </body> </html>

h1 { text-align: center; align-items: center; justify-items: center; } form { text-align: center; align-items: center; justify-items: center; } .card > li { border: 1px solid chartreuse; text-align: center; } .pick:hover { background-color: #eee; } ul { /*margin: 0 auto;*/ display: flex; text-align: center; } li { list-style-type: none; flex: 1; width: 100px; /*height: 80px;*/ /*border: 3px solid aquamarine;*/ } .look > li { display: none; } .lookform { /*display: none;*/ text-align: center; } .lookform > form { text-align: center; justify-items: center; align-items: center; display: none; }
【Over】
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!