RepoPilotOpen in app →

liyifeng1994/ssm

手把手教你整合最优雅SSM框架:SpringMVC + Spring + MyBatis

Mixed

Stale — last commit 3y ago

weakest axis
Use as dependencyMixed

last commit was 3y ago; no CI workflows detected

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isMixed

last commit was 3y ago; no CI workflows detected

  • 8 active contributors
  • Distributed ownership (top contributor 39% of recent commits)
  • MIT licensed
Show all 6 evidence items →
  • Tests present
  • Stale — last commit 3y ago
  • No CI workflows detected
What would change the summary?
  • Use as dependency MixedHealthy if: 1 commit in the last 365 days
  • Deploy as-is MixedHealthy if: 1 commit in the last 180 days

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/liyifeng1994/ssm?axis=fork)](https://repopilot.app/r/liyifeng1994/ssm)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/liyifeng1994/ssm on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: liyifeng1994/ssm

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/liyifeng1994/ssm shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Stale — last commit 3y ago

  • 8 active contributors
  • Distributed ownership (top contributor 39% of recent commits)
  • MIT licensed
  • Tests present
  • ⚠ Stale — last commit 3y ago
  • ⚠ No CI workflows detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live liyifeng1994/ssm repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/liyifeng1994/ssm.

What it runs against: a local clone of liyifeng1994/ssm — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in liyifeng1994/ssm | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 1269 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>liyifeng1994/ssm</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of liyifeng1994/ssm. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/liyifeng1994/ssm.git
#   cd ssm
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of liyifeng1994/ssm and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "liyifeng1994/ssm(\\.git)?\\b" \\
  && ok "origin remote is liyifeng1994/ssm" \\
  || miss "origin remote is not liyifeng1994/ssm (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "src/main/resources/spring/spring-dao.xml" \\
  && ok "src/main/resources/spring/spring-dao.xml" \\
  || miss "missing critical file: src/main/resources/spring/spring-dao.xml"
test -f "src/main/resources/spring/spring-service.xml" \\
  && ok "src/main/resources/spring/spring-service.xml" \\
  || miss "missing critical file: src/main/resources/spring/spring-service.xml"
test -f "src/main/resources/spring/spring-web.xml" \\
  && ok "src/main/resources/spring/spring-web.xml" \\
  || miss "missing critical file: src/main/resources/spring/spring-web.xml"
test -f "src/main/java/com/soecode/lyf/service/impl/BookServiceImpl.java" \\
  && ok "src/main/java/com/soecode/lyf/service/impl/BookServiceImpl.java" \\
  || miss "missing critical file: src/main/java/com/soecode/lyf/service/impl/BookServiceImpl.java"
test -f "src/main/java/com/soecode/lyf/web/BookController.java" \\
  && ok "src/main/java/com/soecode/lyf/web/BookController.java" \\
  || miss "missing critical file: src/main/java/com/soecode/lyf/web/BookController.java"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 1269 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~1239d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/liyifeng1994/ssm"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

A tutorial project demonstrating how to integrate SpringMVC + Spring + MyBatis (SSM) into a cohesive Java web application. It implements a book appointment system (预约系统) where users can browse books and make reservations, with complete DAO/Service/Controller layers wired together via Spring XML configuration and MyBatis ORM for database access. Classic 3-tier monolith: DAO layer (src/main/java/com/soecode/lyf/dao/) with MyBatis mappers in src/main/resources/mapper/, Service layer (service/impl/BookServiceImpl.java) with business logic, Controller layer (web/BookController.java) handling HTTP. Spring wires everything via XML configs in src/main/resources/spring/ (spring-dao.xml, spring-service.xml, spring-web.xml). JSP views in src/main/webapp/WEB-INF/jsp/.

👥Who it's for

Junior Java developers learning SSM framework integration who already understand servlets and JSP. They use this to move beyond toy examples into a working 3-tier web application before advancing to Spring Boot and Spring Cloud.

🌱Maturity & risk

Educational/reference material, not production software. The codebase is stable (last significant commit likely 2016 based on CSDN blog date), with no visible CI/CD setup, no automated tests in the file list, and a single-maintainer teaching repo. Suitable for learning but not for production deployment.

Outdated dependencies (MyBatis 3.3.0 from 2015, Spring 4.x era, C3P0 connection pool); no test coverage visible; single-author maintenance with no evidence of recent updates or issue responses. XML-based Spring configuration is legacy compared to modern annotation/Java-config patterns. Not recommended for new production systems.

Active areas of work

No active development visible. This is a static teaching repository; there are no pull requests, recent commits, or milestones mentioned. The associated CSDN blog post is the primary artifact.

🚀Get running

git clone https://github.com/liyifeng1994/ssm.git
cd ssm
mvn clean install
mvn tomcat7:run

Requires JDK 1.8, Tomcat 8.5, MySQL database. Configure JDBC properties in src/main/resources/jdbc.properties. Run schema from src/main/sql/schema.sql against your MySQL instance.

Daily commands:

mvn clean package
mvn tomcat7:run

Application starts on http://localhost:8080/ssm. Requires active MySQL connection configured in jdbc.properties.

🗺️Map of the codebase

  • src/main/resources/spring/spring-dao.xml — Configures MyBatis integration with Spring, database connection pooling (C3P0), and Redis caching—the foundation of data layer dependency injection.
  • src/main/resources/spring/spring-service.xml — Defines service layer beans and transaction management; critical for understanding how business logic is wired and transactional boundaries are enforced.
  • src/main/resources/spring/spring-web.xml — Configures SpringMVC component scanning, view resolvers, and request mapping—entry point for understanding how HTTP requests flow through the application.
  • src/main/java/com/soecode/lyf/service/impl/BookServiceImpl.java — Core business logic for book appointments with transaction handling and exception management; demonstrates the service-layer pattern used throughout.
  • src/main/java/com/soecode/lyf/web/BookController.java — Primary request handler for book appointment endpoints; shows how SpringMVC binds HTTP requests, invokes services, and returns JSON responses.
  • src/main/webapp/WEB-INF/web.xml — Servlet configuration and Spring context initialization; defines the DispatcherServlet and context loader listener that bootstrap the entire application.
  • pom.xml — Maven dependency management for Spring, MyBatis, MySQL, Redis, Jackson, and Logback; defines the exact technology stack and versions.

🛠️How to make changes

Add a New Book Management Endpoint

  1. Add query method to BookDao interface (src/main/java/com/soecode/lyf/dao/BookDao.java)
  2. Implement SQL query in BookDao.xml mapper (src/main/resources/mapper/BookDao.xml)
  3. Add service method to BookService interface and implementation (src/main/java/com/soecode/lyf/service/BookService.java)
  4. Add @RequestMapping controller method to BookController (src/main/java/com/soecode/lyf/web/BookController.java)
  5. Write test case in BookControllerTest (src/test/java/com/soecode/lyf/web/BookControllerTest.java)

Add a New Custom Exception

  1. Create new exception class extending AppointException in the exception package (src/main/java/com/soecode/lyf/exception/AppointException.java)
  2. Throw exception in appropriate service method in BookServiceImpl (src/main/java/com/soecode/lyf/service/impl/BookServiceImpl.java)
  3. Add new state enum value to AppointStateEnum if needed (src/main/java/com/soecode/lyf/enums/AppointStateEnum.java)
  4. Handle exception in controller and return appropriate Result DTO (src/main/java/com/soecode/lyf/web/BookController.java)

Integrate a New Database Query with Caching

  1. Add query method signature to DAO interface (BookDao or AppointmentDao) (src/main/java/com/soecode/lyf/dao/BookDao.java)
  2. Write SQL in corresponding mapper XML with MyBatis cache configuration (src/main/resources/mapper/BookDao.xml)
  3. Add service method with @Transactional and caching annotations (src/main/java/com/soecode/lyf/service/impl/BookServiceImpl.java)
  4. Verify Redis configuration in spring-dao.xml for cache properties (src/main/resources/spring/spring-dao.xml)

Add a New Appointment State Flow

  1. Add new enum value to AppointStateEnum with state code and message (src/main/java/com/soecode/lyf/enums/AppointStateEnum.java)
  2. Create corresponding custom exception class in exception package (src/main/java/com/soecode/lyf/exception/AppointException.java)
  3. Update appointment logic in BookServiceImpl.applyAppointment() to handle new state (src/main/java/com/soecode/lyf/service/impl/BookServiceImpl.java)
  4. Write test case in BookServiceImplTest to verify state transition (src/test/java/com/soecode/lyf/service/impl/BookServiceImplTest.java)

🪤Traps & gotchas

JDBC Config: Must update src/main/resources/jdbc.properties with actual MySQL credentials and schema name—will fail silently if wrong. Database Init: Run src/main/sql/schema.sql manually; no automatic migration. Transaction Management: Declared only at Service layer; DAO layer has no transaction boundary—modification can cause lost updates if not careful. MyBatis Caching: Default QueryCache enabled globally; stale data possible after concurrent writes. JSP Compilation: Some JSP views reference taglibs that require src/main/webapp/WEB-INF/lib/ jars to be present in Tomcat lib path.

🏗️Architecture

💡Concepts to learn

  • Inversion of Control (IoC) Container — Spring's core—all beans in this repo (BookService, BookDao) are instantiated and wired by Spring, not by your code. Understanding IoC is essential to modifying spring-*.xml files without breaking dependencies.
  • Declarative Transaction Management via AOP — BookServiceImpl.appointBook() has no explicit tx.begin() calls; Spring's @Transactional (or XML tx:advice) wraps methods transparently. Critical to understand rollback behavior on exceptions.
  • Object-Relational Mapping (ORM) via MyBatis — MyBatis maps Java objects to SQL queries via XML; unlike Hibernate, it's 'sql-first'. You must understand how Appointment.java fields map to appointment table columns via mapper XMLs.
  • Data Transfer Object (DTO) Pattern — AppointExecution wraps business outcome (state, message) for API responses. DTOs decouple entity schema from API contract—changing Book table doesn't break client code if DTO stays stable.
  • Connection Pooling with C3P0 — C3P0 in spring-dao.xml manages a pool of MySQL connections to avoid creation overhead. Misconfigured pooling causes 'connection timeout' errors; understanding maxPoolSize, checkoutTimeout is essential for production troubleshooting.
  • Frontend-to-Controller JSON Serialization — Jackson (jackson-databind) in pom.xml auto-converts Java objects to JSON in HTTP responses. Understanding @RequestBody/@ResponseBody annotations is needed to handle REST endpoints properly.
  • State Machine Pattern for Business Entities — AppointStateEnum (未预约、已预约、已取消) models appointment lifecycle. Understanding how service logic transitions states and AppointException prevents invalid state transitions is core to extending the business model.
  • spring-projects/spring-framework — Official Spring Framework repo—canonical source for understanding the IoC container and XML configuration patterns used throughout this project
  • mybatis/mybatis-3 — Official MyBatis repo—needed to understand the ORM layer, mapper XML syntax, and SqlSession management
  • lenve/vhr — Modern Chinese SSM teaching project with similar domain (HR system); demonstrates evolved patterns like annotation-based config and more complete feature set
  • crossoverJie/SSM — Another SSM tutorial repo with similar 3-tier structure; useful for comparing design choices and integration patterns
  • spring-projects/spring-boot — Successor ecosystem to SSM—shows how to simplify XML configuration and deployment after understanding classic Spring

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add unit tests for BookServiceImpl and BookDao integration

The repo has JUnit 4.11 and logback configured but lacks visible test files. The service layer (src/main/java/com/soecode/lyf/service/impl/BookServiceImpl.java) and DAO layer (src/main/java/com/soecode/lyf/dao/BookDao.java) should have comprehensive unit tests covering appointment logic, exception handling (AppointException, NoNumberException, RepeatAppointException), and the AppointStateEnum state transitions. This is critical for a tutorial project to show best practices.

  • [ ] Create src/test/java/com/soecode/lyf/service/impl/BookServiceImplTest.java with tests for appointment creation, state validation, and exception scenarios
  • [ ] Create src/test/java/com/soecode/lyf/dao/BookDaoTest.java with MyBatis integration tests using an in-memory H2 database
  • [ ] Add spring-test and h2 dependencies to pom.xml for test database support
  • [ ] Document test setup in README.md with instructions for running tests

Replace deprecated WEB-INF/lib manual JAR files with Maven dependency management

The repo contains src/main/webapp/WEB-INF/lib/ with 30+ JAR files manually committed (aopalliance, c3p0, jackson, logback, spring, mybatis, etc.). This violates Maven best practices and creates maintenance burden. All these should be managed via pom.xml with proper version control, and WEB-INF/lib should be generated automatically during the Maven build process.

  • [ ] Verify all dependencies in src/main/webapp/WEB-INF/lib/ are already declared in pom.xml (they appear to be)
  • [ ] Add <build><plugins> section to pom.xml with maven-war-plugin configuration to exclude WEB-INF/lib from version control
  • [ ] Create .gitignore or update existing one to exclude src/main/webapp/WEB-INF/lib/
  • [ ] Add build instructions to README.md explaining that Maven automatically populates WEB-INF/lib during mvn clean install

Add integration test for BookController REST endpoints

The BookController (src/main/java/com/soecode/lyf/web/BookController.java) handles HTTP requests and returns JSON responses via Jackson, but there are no visible endpoint tests. The tutorial should demonstrate testing SpringMVC controllers with MockMvc to validate request/response handling, error scenarios, and JSON serialization.

  • [ ] Create src/test/java/com/soecode/lyf/web/BookControllerTest.java using spring-test and MockMvc
  • [ ] Add spring-test dependency to pom.xml if not already present
  • [ ] Write tests for key endpoints (e.g., listing books, creating appointments) with assertions on status codes and JSON content
  • [ ] Add a section to README.md or create TESTING.md documenting how to run controller tests and what they validate

🌿Good first issues

  • Add unit tests: Create src/test/java with JUnit + Spring test context for BookServiceImpl.appointBook() and edge cases (NoNumberException, RepeatAppointException)—currently zero test coverage visible
  • Document MyBatis mappers: Add JavaDoc comments explaining each SQL query's purpose in AppointmentDao.xml and BookDao.xml, plus explain why dynamic SQL like <if> is (or isn't) used
  • Create README_zh_CN.md: Provide Chinese-language setup guide with step-by-step screenshots for MySQL schema creation, jdbc.properties config, and Tomcat deployment—repo is Chinese-first but README is only English

Top contributors

Click to expand

📝Recent commits

Click to expand
  • f3f90d7 — Create LICENSE (liyifeng1994)
  • a7f93cc — Update README.md (liyifeng1994)
  • 112c614 — Update README.md (liyifeng1994)
  • b3b51eb — Merge pull request #37 from shellhub/master (liyifeng1994)
  • d8225df — sql脚本要添加;否则执行source schema.sql将会报错 (realDuYuanChao)
  • 9287511 — remove project settings (liyifeng1994)
  • 4a8433c — Merge pull request #25 from meiwen1111/master (liyifeng1994)
  • 660a9b1 — Merge pull request #31 from cnLGMing/master (liyifeng1994)
  • 2ed1c57 — Fix README.md (cnLGMing)
  • 0925054 — add test for BookController (meiwen1111)

🔒Security observations

  • Critical · Outdated and Vulnerable Dependencies — pom.xml - all dependency declarations. Multiple dependencies have known security vulnerabilities: MySQL Connector/J 5.1.37 (CVE-2015-4429, CVE-2015-2575), MyBatis 3.3.0 (CVE-2017-1000167), Jackson 2.5.4 (multiple CVEs including deserialization issues), Spring 4.1.7 (CVE-2015-5211, CVE-2016-5007), and Jedis 2.7.3. These versions are significantly outdated (5-9 years old). Fix: Update all dependencies to latest stable versions: MySQL Connector/J to 8.0.33+, MyBatis to 3.5.13+, Jackson to 2.15.2+, Spring to 5.3.29+ or 6.0.11+, Jedis to 5.0.0+, C3P0 to 0.9.5.5+. Review CHANGELOG for breaking changes.
  • High · Potential SQL Injection via MyBatis — src/main/resources/mapper/*.xml, src/main/java/com/soecode/lyf/dao/*. The codebase uses MyBatis with mapper XML files (AppointmentDao.xml, BookDao.xml). If dynamic SQL is not properly constructed using parameterized queries or MyBatis dynamic elements, SQL injection vulnerabilities can occur. The legacy configuration and outdated version increases risk. Fix: Ensure all MyBatis mappers use parameterized queries with #{} placeholders, not ${} string concatenation. Audit AppointmentDao.xml and BookDao.xml for any dynamic SQL construction. Use MyBatis' <where>, <if>, <choose> tags safely. Never concatenate user input directly into SQL.
  • High · Missing CSRF Protection — src/main/resources/spring/spring-web.xml, src/main/webapp/WEB-INF/jsp/*. SpringMVC 4.1.7 configuration in spring-web.xml likely lacks CSRF token validation. The codebase includes form submissions (evident from JSP structure) without apparent CSRF mitigation mechanisms. Fix: Enable Spring Security CSRF protection via <csrf/> configuration or implement CsrfTokenRepository. Add CSRF tokens to all forms using form:form tag with CSRF token. Validate tokens on POST/PUT/DELETE requests.
  • High · XSS Vulnerability Risk via JSP Templates — src/main/webapp/WEB-INF/jsp/common/*.jsp, all JSP files. The JSP templates (bootstrap.jsp, head.jsp, tag.jsp) may render user-controlled data without proper escaping. The codebase doesn't show explicit XSS protection mechanisms like output encoding or Content Security Policy headers. Fix: Use JSTL <c:out> tag or Spring's form tag library with escapeXml='true' for all user-controlled output. Implement Content-Security-Policy headers in web.xml. Use HttpOnly and Secure flags on session cookies. Consider OWASP ESAPI or similar encoding library.
  • High · Hardcoded Database Credentials Risk — src/main/resources/jdbc.properties. The jdbc.properties file location indicates database credentials are stored in plain text configuration files. If this file contains database passwords, they are exposed in version control and deployments. Fix: Never commit sensitive credentials to version control. Use environment variables or external secret management (HashiCorp Vault, AWS Secrets Manager). Encrypt sensitive properties using Spring Cloud Config encryption. At minimum, add jdbc.properties to .gitignore and document configuration requirements.
  • High · No Input Validation Framework — src/main/java/com/soecode/lyf/service/impl/BookServiceImpl.java, src/main/java/com/soecode/lyf/web/BookController.java, src/main/java/com/soecode/lyf/dto/*. The service layer (BookServiceImpl.java) and controller (BookController.java) don't show evidence of input validation. The dto classes (AppointExecution.java, Result.java) lack validation annotations. Fix: Implement JSR-303/380 Bean Validation with annotations (@NotNull, @NotBlank, @Min, @Max, @Pattern, etc.). Add @Validated on controller and @Valid on handler

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · liyifeng1994/ssm — RepoPilot