Derby是一个用Java 编写的关系数据库管理系统。Oracle 以 Java DB 的名义分发相同的二进制文件。Derby 的占用空间很小,约为 2MB。Derby 使用的数据库格式是可移植的且独立于平台的。
图书申请
我们在 NetBeans 中创建一个新的 Web 应用程序。在应用程序中,我们将能够将新书添加到数据库中,通过 ID 选择单个书籍,并选择表中的所有书籍。该项目需要 Stripes、MyBatis 和 JSTL 库。前三个 JAR 是 MyBatis 库,接下来的三个是 Stripes 的库。我们必须从他们的项目页面下载它们。JSTL JAR 可用于 NebBeans。
BookMapper.xml和mybatis-config.xml是 MyBatis 使用的 XML 文件 。这StripesResources.properties是 Stripes 框架的默认资源包文件。它包含应用程序的错误消息和标签。它位于libStripes 下载文件的子目录中。
表示层
表示层由六个 JSP 页面组成。这index.jsp是应用程序的默认主页。addBook.jsp 是向数据库添加新书的findBook.jsp页面,是通过 ID 查找书的页面。将bookAdded.jsp书籍成功插入数据库后显示一条消息,showOneBook.jsp 显示所选书籍,并showAllBooks.jsp显示数据库中的所有书籍。
索引.jsp
<%@taglib prefix="stripes" uri="http://stripes.sourceforge.net/stripes.tld"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
Welcome page
Add a new book
Find one book
Show all books
<%@taglib prefix="stripes" uri="http://stripes.sourceforge.net/stripes.tld"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
Find a book
Book ID:
在findBook.jsp表格中,我们有一个通过 ID 查找书籍的表单。该表单由一个文本字段和一个提交按钮组成。插入的值被验证;如果用户添加了无效值,应用程序将返回错误消息。
addBook.jsp
<%@taglib prefix="stripes" uri="http://stripes.sourceforge.net/stripes.tld"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
Add new book
Author:
Title:
Year of publishing:
Remark
将addBook.jsp一本新书添加到数据库中。它包含一个表单,其中包含书籍对象的四个文本字段。该 ID 由 Derby 数据库自动生成。
bookAdded.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
Book added
Book added to database
当一本新书添加到数据库中时,应用程序返回bookAdded.jsp,其中包含一条简单的消息。
showAllBooks.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
Show all books
All books
通过@Validate注解,我们为我们的 HTML 字段提供验证服务。字段不能为空,并且必须匹配正确的数据类型。
图:验证
如果发布年份具有非整数字符,则提交操作失败。
@DefaultHandler
public Resolution addBook() {
Book book = new Book(this.author, this.title,
this.yearPublished, this.remark);
BookService.saveBook(book);
return new ForwardResolution(VIEW);
}
@DefaultHandler
public Resolution showOneBook() throws IOException {
this.book = BookService.getBook(bookId);
return new ForwardResolution(VIEW);
}
默认处理程序调用该BookService.getBook 方法,然后转发到视图。
SelectAllBooksActionBean.java
package com.zetcode.action;
import com.zetcode.bean.Book;
import com.zetcode.service.BookService;
import java.util.List;
import net.sourceforge.stripes.action.ActionBean;
import net.sourceforge.stripes.action.ActionBeanContext;
import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.Resolution;
public class SelectAllBooksActionBean implements ActionBean {
private static final String VIEW = "/showAllBooks.jsp";
private ActionBeanContext context;
private List books;
public List getBooks() {
return books;
}
public void setBooks(List books) {
this.books = books;
}
@DefaultHandler
public Resolution showAll() {
this.books = BookService.getAllBooks();
return new ForwardResolution(VIEW);
}
@Override
public void setContext(ActionBeanContext context) {
this.context = context;
}
@Override
public ActionBeanContext getContext() {
return context;
}
}
SelectAllBooksActionBean负责从数据库中选择所有书籍 。
@DefaultHandler
public Resolution showAll() {
this.books = BookService.getAllBooks();
return new ForwardResolution(VIEW);
}
被BookService.getAllBooks调用来完成这项工作。
服务
与数据库通信的BookServicecontains 方法。
BookService.java
package com.zetcode.service;
import com.zetcode.bean.Book;
import com.zetcode.persistence.MyBatisDAO;
import java.util.List;
public class BookService {
public static void saveBook(Book book) {
MyBatisDAO mbd = new MyBatisDAO();
mbd.saveBook(book);
}
public static List getAllBooks() {
MyBatisDAO mbd = new MyBatisDAO();
List books = mbd.findAll();
return books;
}
public static Book getBook(Long id) {
MyBatisDAO mbd = new MyBatisDAO();
Book book = mbd.findBook(id);
return book;
}
}
DAO 模式用于使示例更具可移植性。
public static List getAllBooks() {
MyBatisDAO mbd = new MyBatisDAO();
List books = mbd.findAll();
return books;
}
package com.zetcode.persistence;
import com.zetcode.bean.Book;
import java.util.List;
public interface BookDAO {
public void saveBook(Book book);
public Book findBook(Long id);
public List findAll();
}
访问数据的方法在BookDAO 接口中定义。当我们针对此接口进行编程时,代码的耦合度较低。
MyBatisDAO.java
package com.zetcode.persistence;
import com.zetcode.bean.Book;
import com.zetcode.util.ServiceLocator;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
public class MyBatisDAO implements BookDAO {
@Override
public void saveBook(Book book) {
SqlSession session = null;
try {
SqlSessionFactory factory = ServiceLocator.getSessionFactory();
session = factory.openSession();
session.insert("insertBook", book);
session.commit();
} finally {
if (session != null) {
session.close();
}
}
}
@Override
public Book findBook(Long id) {
SqlSession session = null;
Book book = null;
try {
SqlSessionFactory factory = ServiceLocator.getSessionFactory();
session = factory.openSession();
book = session.selectOne("selectBook", id);
} finally {
if (session != null) {
session.close();
}
}
return book;
}
@Override
public List findAll() {
SqlSession session = null;
List retrieveList = null;
try {
SqlSessionFactory factory = ServiceLocator.getSessionFactory();
session = factory.openSession();
retrieveList = session.selectList("selectAllBooks");
} finally {
if (session != null) {
session.close();
}
}
return retrieveList;
}
}
MyBatisDAO是接口的具体 实现BookDAO 。如果底层数据源发生变化,我们可以轻松切换到新的 DAO 实现。