新闻详情

新闻详情

首页 / 资讯中心 / 详情

SpringBoot+MyBatis+JSP图书管理系统实战:从搭建到部署避坑

发布时间:2026/9/26 16:53:03来源:尧图网络
SpringBoot+MyBatis+JSP图书管理系统实战:从搭建到部署避坑
简介这是一套面向Java Web初学者与课程设计者的图书管理系统完整源码采用SpringBoot整合MyBatis持久层与JSP视图覆盖图书增删改查、分类管理、借阅归还及分页展示等核心业务适合作为毕业设计、实训项目或框架入门练手。压缩包共1192个文件约95.3MB其中648个class与65个jar构成可运行依赖173个jsp与51个java对应视图与业务代码148个xml承载MyBatis映射与Spring配置另有properties、js、css及图片等资源目录结构完整导入即可编译运行。系统按MVC分层集成Spring Security做权限控制并支持打包为jar部署。目前已有2207人学习下载读者可借此理解SpringBoot自动配置、MyBatis映射与JSP渲染的协作方式掌握从数据库设计到前后端交互的完整开发流程快速积累企业级项目经验。1. 图书管理系统选型为什么 SpringBoot MyBatis JSP 仍是毕设与中小馆藏的稳妥解如果你正在做基于 JSP 的毕设选题或者要给学校图书馆、社区阅览室搭一套能跑起来、能交付、能维护的图书管理系统那 SpringBoot MyBatis JSP 这套组合大概率是你绕不开的选项。它不像前后端分离那样需要你同时维护两套工程、处理跨域和 Token 续期也不像纯 Servlet 那样把 JDBC 连接和 SQL 散落一地。SpringBoot 负责把 Tomcat、数据源、事务、拦截器这些基础设施一次性配好MyBatis 负责把借阅记录、图书库存、读者信息这些关系型数据映射成 Java 对象JSP 负责在服务端把结果渲染成页面直接返回浏览器。三者拼在一起一个 war 包丢进容器就能跑对预算有限、人手有限、只求稳定可用的场景来说这套方案的性价比依然很高。这篇文章面向两类人一类是要在两周内交出一个能演示、能答辩的图书管理系统另一类是真的要把它部署到一台内网服务器上让管理员每天用它做借书、还书、查库存。我会从工程搭建讲到分页、缓存、事务、JSP 渲染再到打包部署和排错把每个环节的参数和坑都摊开说。你不需要先精通 MyBatis 源码但跟着走完至少能拿到一个结构清晰、能二次开发的骨架。2. 工程骨架搭建从 IDEA 新建到第一个 JSP 页面跑通2.1 用 Spring Initializr 建项目时那几个必须改的选项很多人卡在第一步IDEA 里新建 SpringBoot 项目选完依赖发现 JSP 根本渲染不出来访问接口直接返回 JSON 或者 404。问题出在打包方式和依赖范围上。JSP 在 SpringBoot 里属于“非默认支持”的视图技术官方推荐 Thymeleaf但 JSP 依然能用前提是你得把项目打成 war 而不是 jar并且引入正确的 Tomcat 支持。在 IDEA 里用 Spring Initializr 创建时注意这几个选项Project 类型选 Maven语言 JavaJDK 选 8 或 11SpringBoot 2.x 对这两个版本最稳别一上来就上 17 配老版本 MyBatis。Packaging 一定要选War不是 Jar。Jar 包内嵌 Tomcat 对 JSP 的支持有历史遗留问题war 包外置容器或内嵌容器都更省心。Dependencies 勾选 Spring Web、MyBatis Framework、MySQL Driver。JSP 相关依赖 Initializr 不会帮你加需要手动补。建好之后pom.xml里要补三样东西。第一是 JSP 和 JSTL 的依赖第二是spring-boot-starter-tomcat的作用域要改成provided第三是如果要用内嵌 Tomcat 跑 JSP还得加tomcat-embed-jasper。!-- JSP 渲染核心jasper 是 Tomcat 的 JSP 引擎 -- dependency groupIdorg.apache.tomcat.embed/groupId artifactIdtomcat-embed-jasper/artifactId scopeprovided/scope /dependency !-- JSTL 标签库JSP 里做循环和判断全靠它 -- dependency groupIdjavax.servlet/groupId artifactIdjstl/artifactId version1.2/version /dependency !-- servlet API同样 provided避免和容器冲突 -- dependency groupIdjavax.servlet/groupId artifactIdjavax.servlet-api/artifactId scopeprovided/scope /dependency这里有个容易翻车的点tomcat-embed-jasper的 scope 如果写成默认的 compile打 war 包时会和外部 Tomcat 的 jasper 冲突启动报ClassNotFoundException或者 JSP 编译异常。写成provided表示编译时需要、打包时不带交给运行容器提供。如果你坚持用内嵌 Tomcat 跑java -jar方式那 jasper 就不能是 provided得是 compile同时打包方式改回 jar——但这条路对 JSP 支持不稳定我一般不建议。2.2 application.yml 里数据源和 JSP 视图解析器的配置配置文件是第二个高频翻车区。SpringBoot 2.x 默认数据源是 HikariCP性能足够但连接参数写错会导致启动时一直重连。JSP 的视图前缀后缀如果配错Controller 返回的字符串就找不到页面。server: port: 8080 servlet: context-path: /library # 项目访问前缀部署到 Tomcat 时和 war 包名保持一致 spring: datasource: url: jdbc:mysql://127.0.0.1:3306/library_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalse username: root password: your_password driver-class-name: com.mysql.cj.jdbc.Driver hikari: maximum-pool-size: 10 # 中小系统 10 个连接足够别开太大 minimum-idle: 2 connection-timeout: 30000 idle-timeout: 600000 mvc: view: prefix: /WEB-INF/jsp/ # JSP 文件统一放这里外部无法直接访问 suffix: .jsp mybatis: mapper-locations: classpath:mapper/*.xml # XML 映射文件位置 type-aliases-package: com.example.library.entity configuration: map-underscore-to-camel-case: true # 数据库 book_name 自动映射 bookName log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 开发期打印 SQLcontext-path这一项很多人忽略结果本地跑得好好的部署到 Tomcat 后所有静态资源 404。原因是 war 包名和 context-path 不一致浏览器请求路径对不上。要么把 war 包名改成library.war和 context-path 一致要么在 Tomcat 的server.xml里配 Context 的 path。我一般直接让两者一致省心。map-underscore-to-camel-case是 MyBatis 最实用的开关之一。数据库字段习惯用下划线book_name、borrow_dateJava 实体用驼峰bookName、borrowDate打开这个开关就不用每个字段写result columnbook_name propertybookName/能省掉大量重复 XML。2.3 第一个 Controller 到 JSP 的最小闭环配置就绪后写一个最小的图书列表页验证链路。Controller 返回逻辑视图名Spring MVC 用视图解析器拼成/WEB-INF/jsp/book/list.jspJasper 编译后输出 HTML。Controller RequestMapping(/book) public class BookController { Autowired private BookService bookService; // 返回 book/list视图解析器拼成 /WEB-INF/jsp/book/list.jsp GetMapping(/list) public String list(Model model) { ListBook books bookService.findAll(); model.addAttribute(books, books); // JSP 里用 ${books} 取 return book/list; } }对应的 JSP 放在src/main/webapp/WEB-INF/jsp/book/list.jsp。注意webapp目录在 SpringBoot 项目里默认不存在需要手动创建并且 IDEA 要把它标记为 Web 资源目录否则打包时 JSP 不会进 war。% page contentTypetext/html;charsetUTF-8 languagejava % % taglib prefixc urihttp://java.sun.com/jsp/jstl/core % html headtitle图书列表/title/head body table border1 trth书名/thth作者/thth库存/th/tr c:forEach items${books} varbook tr td${book.bookName}/td td${book.author}/td td${book.stock}/td /tr /c:forEach /table /body /html跑起来访问http://localhost:8080/library/book/list如果看到表格说明链路通了。如果 404先检查webapp目录是否被识别如果 500 且报Circular view path说明视图解析器没生效Controller 被当成了返回 JSON 的 RestController。3. MyBatis 映射与分页图书检索、借阅记录查询的落地写法3.1 实体、Mapper 接口与 XML 的三层对应关系MyBatis 的核心是把 SQL 和 Java 方法绑定。图书管理系统里最典型的查询有三类按条件查图书、查某读者的借阅记录、查逾期未还。这三类都涉及多表关联和动态条件用 XML 写比注解清晰得多。先定义实体。Book对应book表BorrowRecord对应borrow_record表后者需要关联出读者姓名和图书名所以要多几个非表字段。public class BorrowRecord { private Long id; private Long bookId; private Long readerId; private Date borrowDate; private Date dueDate; private Date returnDate; private Integer status; // 0 借出 1 已还 2 逾期 // 关联字段不映射到 borrow_record 表 private String bookName; private String readerName; // getter/setter 省略 }Mapper 接口只声明方法SQL 写在 XML。接口方法名要和 XML 的id一致参数用Param标注否则多参数时 MyBatis 会按param1、param2命名XML 里引用容易错。Mapper public interface BorrowRecordMapper { // 分页查询借阅记录支持按读者名和状态过滤 ListBorrowRecord selectByPage(Param(readerName) String readerName, Param(status) Integer status, Param(offset) int offset, Param(limit) int limit); // 统计总数分页必须配套 long countByCondition(Param(readerName) String readerName, Param(status) Integer status); }XML 里用if做动态条件用resultMap处理关联字段。注意borrow_record和book、reader的关联查询如果只是取名字用子查询或 join 都行数据量不大时 join 更直观。resultMap idBorrowRecordMap typecom.example.library.entity.BorrowRecord id columnid propertyid/ result columnbook_id propertybookId/ result columnreader_id propertyreaderId/ result columnborrow_date propertyborrowDate/ result columndue_date propertydueDate/ result columnreturn_date propertyreturnDate/ result columnstatus propertystatus/ result columnbook_name propertybookName/ result columnreader_name propertyreaderName/ /resultMap select idselectByPage resultMapBorrowRecordMap SELECT br.*, b.book_name, r.reader_name FROM borrow_record br LEFT JOIN book b ON br.book_id b.id LEFT JOIN reader r ON br.reader_id r.id where if testreaderName ! null and readerName ! AND r.reader_name LIKE CONCAT(%, #{readerName}, %) /if if teststatus ! null AND br.status #{status} /if /where ORDER BY br.borrow_date DESC LIMIT #{offset}, #{limit} /selectwhere标签会自动处理第一个AND避免WHERE AND的语法错误。LIKE CONCAT(%, #{readerName}, %)用#{}是预编译参数能防 SQL 注入如果写成${}拼接读者名里带单引号就能注入这是血泪经验别图省事。3.2 手写分页 vs PageHelper参数怎么设、坑在哪分页是图书管理系统里最常被问到的功能。MyBatis 本身不带分页常见做法有两种手写LIMIT分页或者用 PageHelper 插件。热搜里“mybatis的分页插件的用法”出现频率很高说明很多人在这上面踩过坑。手写分页的逻辑很直白Service 层算 offsetMapper 传 offset 和 limit再单独查一次 count。优点是可控、无额外依赖、SQL 清晰缺点是每个分页查询都要写两遍条件容易漏。public PageResultBorrowRecord pageQuery(String readerName, Integer status, int pageNum, int pageSize) { int offset (pageNum - 1) * pageSize; // 第 1 页 offset0 ListBorrowRecord list mapper.selectByPage(readerName, status, offset, pageSize); long total mapper.countByCondition(readerName, status); PageResultBorrowRecord result new PageResult(); result.setList(list); result.setTotal(total); result.setPageNum(pageNum); result.setPageSize(pageSize); return result; }PageHelper 的用法是加依赖后在查询前调PageHelper.startPage(pageNum, pageSize)它会用拦截器改写 SQL 自动加LIMIT。看起来省事但有几个坑必须知道startPage只对紧接着的第一条MyBatis 查询生效。如果中间插了别的查询分页会作用到错误的 SQL 上。它依赖Page对象或PageInfo包装结果直接返回List会丢失总数。和自定义的LIMIT同时用时SQL 会变成LIMIT ?, ? LIMIT ?直接报语法错误。我一般建议如果项目里分页场景不超过五处手写更稳如果到处都要分页用 PageHelper 但严格保证startPage和查询紧挨着。参数上pageSize别超过 100否则一次查太多数据JSP 渲染也慢。3.3 借书还书的事务与库存扣减借书和还书是典型的“多表写操作”必须放在事务里。借书要同时做三件事插入借阅记录、扣减图书库存、更新图书状态。任何一步失败都要回滚否则会出现“记录有了但库存没扣”的脏数据。Service public class BorrowService { Autowired private BorrowRecordMapper borrowMapper; Autowired private BookMapper bookMapper; Transactional(rollbackFor Exception.class) // 所有异常都回滚 public void borrow(Long bookId, Long readerId) { // 先查库存用行锁避免并发超借 Book book bookMapper.selectForUpdate(bookId); if (book null || book.getStock() 0) { throw new BizException(库存不足); } // 扣库存 bookMapper.decreaseStock(bookId); // 插借阅记录 BorrowRecord record new BorrowRecord(); record.setBookId(bookId); record.setReaderId(readerId); record.setBorrowDate(new Date()); record.setDueDate(DateUtil.addDays(new Date(), 30)); // 默认借期 30 天 record.setStatus(0); borrowMapper.insert(record); } }Transactional的rollbackFor Exception.class很关键。默认只对RuntimeException回滚如果抛的是受检异常比如某些 IO 异常事务不会回滚库存扣了记录没插数据就乱了。selectForUpdate对应 SQL 里的SELECT ... FOR UPDATE在库存扣减这种并发场景下能防止两个请求同时读到库存 1 然后都扣成 0。4. JSP 页面渲染与个人信息展示从标签库到表单回填4.1 JSTL 循环、判断与格式化在图书列表里的用法JSP 本身是模板技术真正让它好用的是 JSTL 标签库。图书管理系统里最常见的页面元素是列表、状态徽标、日期格式化。用c:forEach遍历用c:if判断状态用fmt:formatDate格式化日期。% taglib prefixc urihttp://java.sun.com/jsp/jstl/core % % taglib prefixfmt urihttp://java.sun.com/jsp/jstl/fmt % c:forEach items${records} varr varStatusst tr td${st.index 1}/td td${r.bookName}/td td${r.readerName}/td tdfmt:formatDate value${r.borrowDate} patternyyyy-MM-dd//td td c:choose c:when test${r.status 0}span classbadge借出中/span/c:when c:when test${r.status 1}span classbadge已归还/span/c:when c:otherwisespan classbadge red已逾期/span/c:otherwise /c:choose /td /tr /c:forEachvarStatus提供index从 0 开始和count从 1 开始做序号列很方便。c:choose相当于 switch比多个c:if清晰。日期格式化一定要用fmt:formatDate直接${r.borrowDate}会输出Tue Jan 01 00:00:00 CST 2025这种用户看不懂。4.2 个人信息展示页面的数据回填与表单提交热搜里“jsp个人信息展示页面”是个高频需求。读者登录后要看到自己的姓名、借阅卡号、已借数量、逾期数量还要能修改联系方式。展示页用 EL 表达式直接取编辑页需要把当前值回填到 input 的value里。!-- 展示页 -- div classprofile p姓名${reader.readerName}/p p卡号${reader.cardNo}/p p已借${borrowCount} 本/p p逾期${overdueCount} 本/p /div !-- 编辑页value 回填 -- form action${pageContext.request.contextPath}/reader/update methodpost input typehidden nameid value${reader.id}/ input typetext namereaderName value${reader.readerName}/ input typetext namephone value${reader.phone}/ button typesubmit保存/button /form${pageContext.request.contextPath}取的是context-path拼在表单 action 前面避免部署后路径错乱。如果 context-path 是/library表单提交到/library/reader/updateController 的PostMapping(/reader/update)才能匹配上。很多人本地用http://localhost:8080/reader/update测试部署后忘了加前缀直接 404。表单提交后Controller 接收参数用ModelAttribute或逐个RequestParam。如果字段多建议用对象接收Spring 会自动按字段名绑定。PostMapping(/reader/update) public String update(Reader reader, RedirectAttributes ra) { readerService.update(reader); ra.addFlashAttribute(msg, 保存成功); // 重定向后仍能取到 return redirect:/reader/profile; }RedirectAttributes的addFlashAttribute把消息存到 session重定向后取出即删适合“操作成功”这类一次性提示。如果直接用model.addAttribute重定向后消息就丢了。4.3 静态资源与 JSP 共存的目录约定SpringBoot 默认静态资源目录是src/main/resources/static但 JSP 放在src/main/webapp/WEB-INF/jsp。CSS、JS、图片如果放staticJSP 里引用要写/css/style.css如果放webapp/static引用路径又不一样。混用会导致样式加载不出来。我的习惯是所有静态资源统一放src/main/resources/staticJSP 里用${pageContext.request.contextPath}/css/style.css引用。这样打包后静态资源在 classpathJSP 在 webapp互不干扰。注意WEB-INF下的 JSP 浏览器无法直接访问必须经过 Controller 转发这是安全设计别把 JSP 放到webapp根目录下。5. 避坑与排查图书管理系统上线前必须过的五道坎5.1 坑一JSP 页面 404日志却没有任何报错现象访问/book/list返回 404控制台没有异常Controller 的断点也没进。原因webapp目录没有被 IDEA 识别为 Web 资源目录或者pom.xml的 packaging 是 jar。jar 包内嵌 Tomcat 默认不处理 JSP视图解析器找不到文件直接 404。解决确认pom.xml里packagingwar/packaging在 IDEA 的 Project Structure → Modules → Web 里把src/main/webapp添加为 Web Resource Directory确认tomcat-embed-jasper依赖存在且 scope 正确。5.2 坑二MyBatis 查询返回字段全为 null现象SQL 在数据库客户端能查出数据但 Java 对象里字段都是 null。原因数据库字段book_name和实体属性bookName没有映射且map-underscore-to-camel-case没开或者 XML 里用了resultMap但列名和属性名对不上。解决优先打开mybatis.configuration.map-underscore-to-camel-case: true如果用了自定义resultMap逐列核对column和property关联查询的字段如book_name必须在resultMap里显式声明否则不会自动映射。5.3 坑三分页查询第二页数据重复或丢失现象第一页正常翻到第二页出现和第一页相同的记录或者跳过了一些记录。原因ORDER BY的字段不唯一。比如按borrow_date排序同一天有多条记录MySQL 的排序不稳定两次查询顺序可能不同LIMIT截取的就乱了。解决ORDER BY后面追加唯一字段比如ORDER BY br.borrow_date DESC, br.id DESC。这样排序结果确定分页才不会错位。这是最隐蔽的坑之一数据量小的时候看不出来上量后必现。5.4 坑四事务不生效库存扣了记录没插现象借书时库存减了但借阅记录没插入或者反过来。原因Transactional标注的方法被同一个类内部的其他方法直接调用Spring AOP 代理没生效或者异常类型是受检异常默认不回滚。解决确保事务方法是通过 Spring 注入的 Bean 调用的不要在同类里this.borrow()Transactional加上rollbackFor Exception.class检查数据库引擎是不是 InnoDBMyISAM 不支持事务。5.5 坑五部署到外部 Tomcat 后静态资源和接口全 404现象本地内嵌 Tomcat 跑得好好的war 包丢进外部 Tomcat 后页面样式丢失接口 404。原因war 包名和context-path不一致或者 SpringBoot 的启动类没有继承SpringBootServletInitializer。解决war 包名改成和context-path一致如library.war对应/library启动类继承SpringBootServletInitializer并重写configure方法外部 Tomcat 的版本要和 SpringBoot 内嵌版本兼容SpringBoot 2.x 配 Tomcat 9别配 Tomcat 10包名从javax变成jakartaJSP 和 Servlet 全不兼容。6. 进阶技巧用 MyBatis 二级缓存和 SQL 日志把性能问题钉死图书管理系统上线后最先暴露的性能问题通常是“图书列表页每次都要查数据库”。图书数据变动频率低读多写少非常适合开 MyBatis 二级缓存。二级缓存是 Mapper 级别的多个 SqlSession 共享配置得当能把重复查询挡在数据库外面。开启方式分两步。第一步在application.yml里打开全局开关mybatis: configuration: cache-enabled: true第二步在需要缓存的 Mapper XML 顶部加cache标签并让查询语句用useCachetruemapper namespacecom.example.library.mapper.BookMapper !-- eviction 淘汰策略flushInterval 刷新间隔毫秒size 最大缓存对象数 -- cache evictionLRU flushInterval600000 size512 readOnlytrue/ select idfindAll resultTypecom.example.library.entity.Book useCachetrue SELECT * FROM book ORDER BY id DESC /select /mapperevictionLRU是最近最少使用淘汰适合图书这种热点集中的数据。flushInterval600000表示 10 分钟刷新一次图书信息变动不频繁这个间隔够用。readOnlytrue表示缓存对象只读性能更好但要求返回的对象不被修改——如果 Service 层拿到 Book 后改了字段再返回缓存里的对象也会被改下次取出来就是脏数据。我一般建议readOnlyfalse牺牲一点性能换安全。二级缓存有个必须注意的边界增删改操作会自动清空该 Mapper 的缓存。所以借书还书后图书列表缓存会失效下次查询重新加载这是符合预期的。但如果你的图书库存更新写在BookMapper而列表查询也在BookMapper那每次借书都会清空列表缓存缓存命中率上不去。解决办法是把库存更新单独放到BookStockMapper让缓存粒度更细。配合缓存SQL 日志是排查性能问题的黑匣子。开发期用StdOutImpl把 SQL 打到控制台上线后改成日志框架输出到文件并打开慢 SQL 监控mybatis: configuration: log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl logging: level: com.example.library.mapper: debug # 只打 Mapper 包的 SQLlogging.level精确到 Mapper 包避免全量 debug 日志把磁盘写满。如果发现某条 SQL 执行超过 1 秒优先看执行计划检查borrow_record表的reader_id、book_id有没有索引。借阅记录表数据量会随时间增长没索引的话按读者查借阅历史会越来越慢。最后说一个我自己的习惯每次改完 Mapper XML先在数据库客户端把 SQL 粘出来跑一遍确认结果集和字段名再回到 Java 里调。JSP 页面渲染出来的数据不对九成是 SQL 的问题不是 JSP 的问题。把 SQL 钉死页面自然就对了。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

代码展示组件设计:用 TaoToken 统一 Key 打通 Syntax Highlight 与 Copy 交互工程 2026/9/26 17:32:30

代码展示组件设计:用 TaoToken 统一 Key 打通 Syntax Highlight 与 Copy 交互工程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
加了LIMIT 1反而变慢?优化器选错索引的坑与根治方案 2026/9/26 17:32:30

加了LIMIT 1反而变慢?优化器选错索引的坑与根治方案

DBA这行干久了,什么鬼事都能见到。这个标题里的场景,我至少有三次在同事的工位前见过:一条订单查询SQL,本来跑得好好的,几百毫秒返回,为了减少接口返回的数据量,加了个 LIMIT 1,结果…

阅读更多 →
大模型训练师实战:从LoRA微调到本地部署的完整指南 2026/9/26 17:32:30

大模型训练师实战:从LoRA微调到本地部署的完整指南

1. 大模型训练师到底在训什么:从岗位画像到能力拆解很多人第一次听到“大模型训练师”这个称呼,脑子里浮现的画面是坐在机房里盯着显卡跑进度条。实际上,这个岗位的日常远比“等模型跑完”复杂得多。它更像是一个介于数据工程师、算法工程师和…

阅读更多 →
大数据驱动音乐爆款预测:特征工程与多模型融合的完整实践 2026/9/26 17:32:30

大数据驱动音乐爆款预测:特征工程与多模型融合的完整实践

做音乐流行趋势预测这个项目,前后折腾了快三个月。最初的想法很简单:手里攒着一大堆音乐平台的播放数据、社交媒体的讨论数据,能不能用大数据的手段,提前判断一首歌会不会火?说白了,就是给"流行"…

阅读更多 →
AI 工作流工具终极对比:Agent Builder vs n8n/dify/coze,TaoToken 统一 Key 接入怎么选? 2026/9/26 17:32:24

AI 工作流工具终极对比:Agent Builder vs n8n/dify/coze,TaoToken 统一 Key 接入怎么选?

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
用Go搭建AI Agent流水线:从商品图到淘宝详情页的全自动生成 2026/9/26 17:32:24

用Go搭建AI Agent流水线:从商品图到淘宝详情页的全自动生成

一条流水线从一张商品图开始,跑完之后吐出一整套淘宝详情页——标题、卖点、详情文案、场景图、参数表格,全齐了。这就是我最近用 Go 搭的一条 AI Agent 流水线。作为常年写后端服务的人,我这次刻意没有跟风用 Python,而是选了 Go…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉