栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

使用 Stripes、MyBatis 和 Derby 创建 Java Web 应用程序

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用 Stripes、MyBatis 和 Derby 创建 Java Web 应用程序

在本教程中,我们将使用 Stripes、MyBatis 和 Derby 创建一个 Java Web 应用程序。我们使用 NetBeans 来构建应用程序。Apache Tomcat 用作 JSP 和 servlet 容器。项目源代码可在作者的 Github 存储库中获得。

Stripes是一个开源的轻量级 Java Web 应用程序框架。Stripes 的目标是使 Java 中基于 Servlet/JSP 的 Web 开发变得简单、直观和直接。Stripes 是一个基于动作的 MVC(模型视图控制器)框架。它在 JEE Web 容器中运行,使用最少的配置文件,并具有灵活简单的参数绑定。

MyBatis是一个 Java 持久性框架,它使用 XML 描述符或注释将对象与存储过程或 SQL 语句耦合在一起。与 ORM 框架不同,MyBatis 不会将 Java 对象映射到数据库表,而是将 Java 方法映射到 SQL 语句。MyBatis 允许使用所有数据库功能,如存储过程、视图、任何复杂性的查询和供应商专有功能。

Derby是一个用Java 编写的关系数据库管理系统。Oracle 以 Java DB 的名义分发相同的二进制文件。Derby 的占用空间很小,约为 2MB。Derby 使用的数据库格式是可移植的且独立于平台的。

图书申请

我们在 NetBeans 中创建一个新的 Web 应用程序。在应用程序中,我们将能够将新书添加到数据库中,通过 ID 选择单个书籍,并选择表中的所有书籍。该项目需要 Stripes、MyBatis 和 JSTL 库。前三个 JAR 是 MyBatis 库,接下来的三个是 Stripes 的库。我们必须从他们的项目页面下载它们。JSTL JAR 可用于 NebBeans。

图:项目库

在 NetBeans Services 选项卡中,我们展开 Databases 节点并右键单击 Java DB 节点并选择 Create Database 选项。数据库名称将是books,用户和密码app和app。

书籍.sql
CREATE TABLE Books(Id INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY 
    (START WITH 1, INCREMENT BY 1), Author VARCHAr(30), Title VARCHAr(60), 
    Published INTEGER, Remark VARCHAr(150));
INSERT INTO Books(Author, Title, Published, Remark) VALUES ('Leo Tolstoy', 'War and Peace', 1869, 'Napoleonic wars');    
INSERT INTO Books(Author, Title, Published, Remark) VALUES ('Leo Tolstoy', 'Anna Karenina', 1878, 'Greatest book of love');
INSERT INTO Books(Author, Title, Published, Remark) VALUES ('Jeff Prosise', 'Programming Windows with MFC', 1999, 'Classic book about MFC');
INSERT INTO Books(Author, Title, Published, Remark) VALUES ('Tom Marrs', 'JBoss at Work', 2005, 'JBoss practical guide');
INSERT INTO Books(Author, Title, Published, Remark) VALUES ('Debu Panda', 'EJB3 in Action', 2007, 'Introduction to Enterprice Java Beans');

我们为创建的数据库创建一个新的数据库连接并执行此 SQL 代码。我们有一张Books桌子,里面放着几本书。

web.xml



    
    
        Stripes Filter
        StripesFilter
        net.sourceforge.stripes.controller.StripesFilter
        
            ActionResolver.Packages
            com.zetcode.action
        
    
 
    
        StripesFilter
        *.jsp
        REQUEST
    
 
    
        StripesFilter
        StripesDispatcher
        REQUEST
    
 
    
        StripesDispatcher
        net.sourceforge.stripes.controller.DispatcherServlet
        1
    
 
    
        StripesDispatcher
        *.action
        
    
    
        index.jsp
    
    

在web.xml部署描述符中,我们设置了 Stripes 框架。该index.jsp文件是默认主页文件。在com.zetcode.action 我们有我们的ActionBeans.

资源

在resources目录中,我们有三个文件。该resources目录是通过右键单击项目文件并选择属性来创建的。在源类别中,我们添加了一个新的源包文件夹。

图:资源

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
            
            
    

包含指向两个 JSP 页面的index.jspStripes 链接以添加一本新书并查找一本书以及一个指向ActionBean显示所有书籍的链接。<%@taglib prefix="stripes" uri="http://stripes.sourceforge.net/stripes.tld"%> 声明了 Stripes 使用的标签,包括.

findBook.jsp
<%@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
        
        
                
Id Author Title Published Remark

显示从数据库中检索到的showAllBooks.jsp所有书籍。该<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>指令声明了 JSTL 核心标签,包括。可以使用${actionBean}表达式访问返回的数据,其中actionBean 是转发视图的操作bean(即这个JSP 页面)。在这种情况下,动作 bean 是SelectAllBooksActionBean.

showOneBook.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>


    
        
        Show one book
    
    
        A book

        
Id Author Title Published Remark

显示showOneBook.jsp一本书,我们通过它的 ID 找到了它。

书豆

Bookbean 是一个 Java 类,它代表我们应用程序的域对象——一本书 。

Book.java
package com.zetcode.bean;

public class Book {

    private Long id;

    private String author;
    private String title;
    private int yearPublished;
    private String remark;
    
    public Book() {};

    public Book(String author, String title, int published, 
            String remark) {
        
        this.author = author;
        this.title = title;
        this.yearPublished = published;
        this.remark = remark;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public int getPublished() {
        return yearPublished;
    }

    public void setPublished(int published) {
        this.yearPublished = published;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }
}

bean 具有必要的属性以及getter 和setter 方法。请注意,还需要添加一个空的构造函数。

动作豆

Stripes'ActionBean是一个接收请求中提交的数据并处理用户输入的对象。它既定义了表单的属性,也定义了表单的处理逻辑。最后它返回一个视图给用户。在我们的应用程序中,我们有三个动作 bean: AddBookActionBean、SelectAllBooksActionBean和SelectOneBookActionBean。它们中的每一个都代表要在应用程序中执行的一些操作。

图:动作豆

我们将动作 bean 放入com.zetcode.action包中。

AddBookActionBean.java
package com.zetcode.action;

import com.zetcode.bean.Book;
import com.zetcode.service.BookService;
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;
import net.sourceforge.stripes.validation.Validate;

public class AddBookActionBean implements ActionBean {

    private static final String VIEW = "/bookAdded.jsp";
    private ActionBeanContext context;

    @Validate(required = true)
    private String author;

    @Validate(required = true)
    private String title;

    @Validate(required = true)
    private int yearPublished;

    @Validate(required = true)
    private String remark;

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public int getYearPublished() {
        return yearPublished;
    }

    public void setYearPublished(int yearPublished) {
        this.yearPublished = yearPublished;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    @DefaultHandler
    public Resolution addBook() {

        Book book = new Book(this.author, this.title,
                this.yearPublished, this.remark);
        BookService.saveBook(book);

        return new ForwardResolution(VIEW);
    }

    @Override
    public void setContext(ActionBeanContext context) {

        this.context = context;
    }

    @Override
    public ActionBeanContext getContext() {

        return context;
    }
}

在AddBookActionBean我们填写表格以添加新书后调用。action bean 自动将请求属性绑定到它自己的属性。

private static final String VIEW = "/bookAdded.jsp";

图书成功保存到数据库时的 返回AddBookActionBean页面。bookAdded.jsp

@Validate(required=true)
private String author;

@Validate(required=true)
private String title;
...

通过@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注释指定此操作 bean 的默认处理程序方法 。(可以定义多个处理程序。)处理程序创建Bookbean,调用BookService.saveBook 并转发到适当的视图。

SelectOneBookActionBean.java
package com.zetcode.action;

import com.zetcode.bean.Book;
import com.zetcode.service.BookService;
import java.io.IOException;
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;
import net.sourceforge.stripes.validation.Validate;

public class SelectOneBookActionBean implements ActionBean {
    
    private static final String VIEW = "/showOneBook.jsp";
    private ActionBeanContext context;    
    
    private Book book;
    
    @Validate(required=true)
    private Long bookId;

    public Book getBook() {
        return book;
    }

    public void setBook(Book book) {
        this.book = book;
    }

    public Long getBookId() {
        return bookId;
    }

    public void setBookId(Long bookId) {
        this.bookId = bookId;
    }
    
    @DefaultHandler
    public Resolution showOneBook() throws IOException {
        
        this.book = BookService.getBook(bookId);

        return new ForwardResolution(VIEW);
    }

    @Override
    public void setContext(ActionBeanContext context) {

        this.context = context;
    }

    @Override
    public ActionBeanContext getContext() {
        
        return context;
    }
}

在SelectOneBookActionBean我们单击 中的 Submit 按钮后调用findBook.jsp.

@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;
}

该getAllBooks方法创建MyBatisDAO 并调用其findAll方法。它返回检索到的书籍列表。

DAO

数据访问对象(DAO)模式用于 将低级数据访问 API 或操作与高级业务服务分开。

BookDAO.java
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 实现。

@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();
        }
    }        
}

该saveBook方法将一本新书保存到数据库中。AnSqlSessionFactory的创建是为了产生一个SqlSession,它是使用 MyBatis 的主要 Java 接口。工厂的创建委托给ServiceLocator. 会话的insert方法使用给定的参数对象执行插入语句。该commit方法将更改提交到数据库。

SqlSessionFactory factory = ServiceLocator.getSessionFactory();
session = factory.openSession();
book = session.selectOne("selectBook", id);

对于单本书的选择,我们将id参数传递给会话的selectOne方法。

SqlSessionFactory factory = ServiceLocator.getSessionFactory();
session = factory.openSession();
retrieveList = session.selectList("selectAllBooks");

该selectList方法返回书籍对象的列表。

ServiceLocator.java
package com.zetcode.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class ServiceLocator {

    public static SqlSessionFactory getSessionFactory() {

        InputStream inputStream = null;
        SqlSessionFactory sqlSessionFactory = null;

        try {
            String resource = "mybatis-config.xml";
            inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        } catch (IOException ex) {
            Logger.getLogger(ServiceLocator.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException ex) {
                Logger.getLogger(ServiceLocator.class.getName()).log(Level.WARNING, null, ex);
            }
        }

        return sqlSessionFactory;
    }
}

从提供的配置文件ServiceLocator构建。SqlSessionFactory这个工厂后来被用来生产一个SqlSession,它是与 MyBatis 通信的主要接口。

mybatis-config.xml



  
    
          
      
     
    
        
            
            
                
                
                
                
            
        
    
    
        
    

在该mybatis-config.xml文件中,我们创建一个新的图书Book类型,为 Derby 定义数据源,并指定映射器文件。

BookMapper.xml


  

    
    
        SELECT * FROM Books WHERe Id = #{id}
        
    
    
        INSERT INTO Books(Author, Title, Published, Remark) VALUES 
        (#{author}, #{title}, #{published}, #{remark})
    

在BookMapper.xml我们的应用程序中使用了 SQL 命令。它有两个选择和一个插入命令。

请注意,对于结果类型,我们没有定义集合,而是定义集合项的类型。

图:显示所有书籍

屏幕截图显示了从示例数据库中选择的所有书籍。

在本教程中,我们使用 Stripes、MyBatis 和 Derby 创建了一个 Web 应用程序。我们使用了三层和 DAO 软件模式。NetBeans 用于构建应用程序。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/851228.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号