首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Spring 整合 MyBatis 完整實戰:Maven + MySQL 圖書管理系統

     編輯:Java 綜合教學

項目概覽

技術棧:Spring 4.3 + MyBatis 3.4 + Maven + MySQL 5.5 + Tomcat 7/8 + C3P0 連接池 + Log4j2 + JUnit 4

實現功能:圖書增刪改查、事務管理、單元測試、簡易 MVC 架構

一、Maven Web 項目創建要點

  1. 創建 Maven 項目,設置 Java 1.7、Dynamic Web Module 3.0
  2. 調整 Deployment Assembly:移除 test 目錄、WebContent,添加 src/main/webapp
  3. 目錄結構遵循 Maven 標準:src/main/java、src/main/resources、src/main/webapp

二、數據庫設計

CREATE TABLE `books` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '編號',
  `title` varchar(100) NOT NULL COMMENT '書名',
  `price` decimal(10,2) DEFAULT NULL COMMENT '價格',
  `publishDate` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '出版日期',
  PRIMARY KEY (`id`),
  UNIQUE KEY `title` (`title`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- 初始數據
INSERT INTO `books` VALUES 
(1, 'Java編程思想', 98.50, '2005-01-02'),
(2, 'HeadFirst 設計模式', 55.70, '2010-11-09'),
(3, '第一行代碼Android', 69.90, '2015-06-23'),
(4, 'C++編程思想', 88.50, '2004-01-09'),
(5, 'HeadFirst Java', 55.70, '2013-12-17'),
(6, '瘋狂Android', 19.50, '2014-07-31');

三、核心依賴 pom.xml

<properties>
    <spring.version>4.3.0.RELEASE</spring.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
    <!-- Spring 核心 -->
    <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency>
    <dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>${spring.version}</version></dependency>
    <dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>${spring.version}</version></dependency>
    <dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.9</version></dependency>
    
    <!-- MyBatis 整合 -->
    <dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.1</version></dependency>
    <dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>1.3.0</version></dependency>
    
    <!-- 數據庫連接池 -->
    <dependency><groupId>c3p0</groupId><artifactId>c3p0</artifactId><version>0.9.1.2</version></dependency>
    <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.38</version></dependency>
    
    <!-- 其他 -->
    <dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency>
    <dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.6.1</version></dependency>
    <dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.10</version></dependency>
</dependencies>

四、實體類 Book.java

package com.zhangguo.bookstore.entities;

import java.util.Date;

public class Book {
    private int id;
    private String title;
    private double price;
    private Date publishDate;
    // 構造器、Getter/Setter 省略
}

五、MyBatis 映射層

DAO 接口

package com.zhangguo.bookstore.mapper;

import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.zhangguo.bookstore.entities.Book;

public interface BookDAO {
    List<Book> getAllBooks();
    Book getBookById(@Param("id") int id);
    int add(Book entity);
    int delete(int id);
    int update(Book entity);
}

XML 映射文件 BookMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhangguo.bookstore.mapper.BookDAO">
    <select id="getAllBooks" resultType="Book">
        select id, title, price, publishDate from books
    </select>
    <select id="getBookById" resultType="Book">
        select id, title, price, publishDate from books where id=#{id}
    </select>
    <insert id="add">
        insert into books(title, price, publishDate) values(#{title}, #{price}, #{publishDate})
    </insert>
    <delete id="delete">
        delete from books where id=#{id}
    </delete>
    <update id="update">
        update books set title=#{title}, price=#{price}, publishDate=#{publishDate} where id=#{id}
    </update>
</mapper>

六、Spring 整合配置 applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
    <!-- 1. 屬性佔位符 -->
    <context:property-placeholder location="classpath*:db.properties" />
    
    <!-- 2. C3P0 數據源 -->
    <bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <property name="driverClass" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.uid}"/>
        <property name="password" value="${jdbc.pwd}"/>
        <property name="acquireIncrement" value="5"/>
        <property name="initialPoolSize" value="10"/>
        <property name="minPoolSize" value="5"/>
        <property name="maxPoolSize" value="20"/>
    </bean>
    
    <!-- 3. SqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="datasource"/>
        <property name="typeAliasesPackage" value="com.zhangguo.bookstore.entities"/>
        <property name="mapperLocations" value="classpath*:com/zhangguo/bookstore/mapper/*Mapper.xml"/>
    </bean>
    
    <!-- 4. Mapper 掃描器 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <property name="basePackage" value="com.zhangguo.bookstore.mapper"/>
    </bean>
    
    <!-- 5. 聲明式事務 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="datasource"/>
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager"/>
    
    <!-- 6. 組件掃描 -->
    <context:component-scan base-package="com.zhangguo.bookstore"/>
    <aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>

七、服務層 BookService

@Service
public class BookService {
    @Resource BookDAO bookdao;
    
    public List<Book> getAllBooks() { return bookdao.getAllBooks(); }
    public Book getBookById(int id) { return bookdao.getBookById(id); }
    
    public int add(Book entity) throws Exception {
        if (entity.getTitle() == null || entity.getTitle().isEmpty())
            throw new Exception("書名不能為空");
        return bookdao.add(entity);
    }
    
    @Transactional
    public int add(Book entity1, Book entityBak) { // 事務測試用
        int rows = bookdao.add(entity1);
        rows += bookdao.add(entityBak);
        return rows;
    }
    
    public int delete(int id) { return bookdao.delete(id); }
    public int delete(String[] ids) { /* 批量刪除實現 */ }
    public int update(Book entity) { return bookdao.update(entity); }
}

八、JUnit 單元測試

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestBookService {
    @Autowired BookService bookService;
    
    @Test public void testGetAllBooks() { assertNotNull(bookService.getAllBooks()); }
    @Test public void testAdd() { /* 測試添加 */ }
    @Test public void testDeleteInt() { assertEquals(1, bookService.delete(9)); }
    @Test public void testDeleteStringArray() { /* 批量刪除 */ }
    @Test public void testUpdate() { /* 更新測試 */ }
    @Test public void testGetBookById() { assertNotNull(bookService.getBookById(1)); }
    @Test public void testAddDouble() { /* 事務回滾測試:同名書添加兩次應失敗 */ }
}

九、Web 層配置

web.xml 載入 Spring 容器

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:applicationContext.xml</param-value>
</context-param>

Spring 容器工具類 CtxUtil

@Component
public class CtxUtil implements ApplicationContextAware {
    public static ApplicationContext ctx;
    @Override public void setApplicationContext(ApplicationContext ctx) { CtxUtil.ctx = ctx; }
    public static <T> T getBean(Class<T> clazz) { return ctx.getBean(clazz); }
    public static Object getBean(String name) { return ctx.getBean(name); }
}

十、簡易 MVC 基礎控制器

public class BaseController extends HttpServlet {
    protected void service(HttpServletRequest req, HttpServletResponse resp) {
        req.setCharacterEncoding("UTF-8");
        String act = req.getParameter("act");
        if (act == null || act.isEmpty()) act = "execute";
        try {
            Method method = this.getClass().getMethod(act, HttpServletRequest.class, HttpServletResponse.class);
            String target = (String) method.invoke(this, req, resp);
            if (target.startsWith("redirect:")) resp.sendRedirect(target.substring(9));
            else req.getRequestDispatcher(target).forward(req, resp);
        } catch (Exception e) { resp.sendError(400, e.getMessage()); }
    }
    public String execute(HttpServletRequest req, HttpServletResponse resp) { return "error.jsp"; }
}

十一、業務控制器與視圖

BookController

@WebServlet("/BookController.do")
public class BookController extends BaseController {
    BookService bookService;
    @Override public void init() { bookService = CtxUtil.getBean(BookService.class); }
    
    public String ListBook(HttpServletRequest req, HttpServletResponse resp) {
        req.setAttribute("books", bookService.getAllBooks());
        return "ListBook.jsp";
    }
    public String Delete(HttpServletRequest req, HttpServletResponse resp) {
        int id = Integer.parseInt(req.getParameter("id"));
        req.setAttribute("message", bookService.delete(id) > 0 ? "刪除成功" : "刪除失敗");
        req.setAttribute("books", bookService.getAllBooks());
        return "ListBook.jsp";
    }
}

ListBook.jsp

<%@ taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core" %>
<table border="1" width="100%">
    <tr><th>編號</th><th>書名</th><th>價格</th><th>出版日期</th><th>操作</th></tr>
    <c:forEach var="book" items="${books}">
        <tr>
            <td>${book.id}</td><td>${book.title}</td><td>${book.price}</td><td>${book.publishDate}</td>
            <td><a href="BookController.do?act=Delete&id=${book.id}">刪除</a></td>
        </tr>
    </c:forEach>
</table>
<p>${message}</p>

index.jsp 入口

<jsp:forward page="BookController.do?act=ListBook"/>
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved