在数据库中创建表(表名最好为单数英文形式)
CREATE TABLE `book` (
`bid` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_unicode_ci',
`author` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
`status` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
`title` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
PRIMARY KEY (`bid`) USING BTREE
)
COLLATE='utf8mb4_unicode_ci'
ENGINE=InnoDB
;
在NetBeans IDE中创建maven web应用
使用向导从数据库表创建实体类:
自动生成的实体类代码如下:
/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
*/
package com.example.jpawebtomcat;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
/**
*
* @author Administrator
*/
@Entity
@Table(name = "book")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Book.findAll", query = "SELECT b FROM Book b"),
@NamedQuery(name = "Book.findByBid", query = "SELECT b FROM Book b WHERE b.bid = :bid"),
@NamedQuery(name = "Book.findByAuthor", query = "SELECT b FROM Book b WHERE b.author = :author"),
@NamedQuery(name = "Book.findByStatus", query = "SELECT b FROM Book b WHERE b.status = :status"),
@NamedQuery(name = "Book.findByTitle", query = "SELECT b FROM Book b WHERE b.title = :title")})
public class Book implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 255)
@Column(name = "bid")
private String bid;
@Size(max = 255)
@Column(name = "author")
private String author;
@Size(max = 255)
@Column(name = "status")
private String status;
@Size(max = 255)
@Column(name = "title")
private String title;
public Book() {
}
public Book(String bid) {
this.bid = bid;
}
public String getBid() {
return bid;
}
public void setBid(String bid) {
this.bid = bid;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@Override
public int hashCode() {
int hash = 0;
hash += (bid != null ? bid.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Book)) {
return false;
}
Book other = (Book) object;
if ((this.bid == null && other.bid != null) || (this.bid != null && !this.bid.equals(other.bid))) {
return false;
}
return true;
}
@Override
public String toString() {
return "com.example.jpawebtomcat.Book[ bid=" + bid + " ]";
}
}
使用向导从实体类创建控制器类:
自动生成的JPA控制器代码如下:
/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
*/
package com.example.jpawebtomcat;
import com.example.jpawebtomcat.exceptions.NonexistentEntityException;
import com.example.jpawebtomcat.exceptions.PreexistingEntityException;
import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
/**
*
* @author Administrator
*/
public class BookJpaController implements Serializable {
public BookJpaController(EntityManagerFactory emf) {
this.emf = emf;
}
private EntityManagerFactory emf = null;
public EntityManager getEntityManager() {
return emf.createEntityManager();
}
public void create(Book book) throws PreexistingEntityException, Exception {
EntityManager em = null;
try {
em = getEntityManager();
em.getTransaction().begin();
em.persist(book);
em.getTransaction().commit();
} catch (Exception ex) {
if (findBook(book.getBid()) != null) {
throw new PreexistingEntityException("Book " + book + " already exists.", ex);
}
throw ex;
} finally {
if (em != null) {
em.close();
}
}
}
public void edit(Book book) throws NonexistentEntityException, Exception {
EntityManager em = null;
try {
em = getEntityManager();
em.getTransaction().begin();
book = em.merge(book);
em.getTransaction().commit();
} catch (Exception ex) {
String msg = ex.getLocalizedMessage();
if (msg == null || msg.length() == 0) {
String id = book.getBid();
if (findBook(id) == null) {
throw new NonexistentEntityException("The book with id " + id + " no longer exists.");
}
}
throw ex;
} finally {
if (em != null) {
em.close();
}
}
}
public void destroy(String id) throws NonexistentEntityException {
EntityManager em = null;
try {
em = getEntityManager();
em.getTransaction().begin();
Book book;
try {
book = em.getReference(Book.class, id);
book.getBid();
} catch (EntityNotFoundException enfe) {
throw new NonexistentEntityException("The book with id " + id + " no longer exists.", enfe);
}
em.remove(book);
em.getTransaction().commit();
} finally {
if (em != null) {
em.close();
}
}
}
public List<Book> findBookEntities() {
return findBookEntities(true, -1, -1);
}
public List<Book> findBookEntities(int maxResults, int firstResult) {
return findBookEntities(false, maxResults, firstResult);
}
private List<Book> findBookEntities(boolean all, int maxResults, int firstResult) {
EntityManager em = getEntityManager();
try {
CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
cq.select(cq.from(Book.class));
Query q = em.createQuery(cq);
if (!all) {
q.setMaxResults(maxResults);
q.setFirstResult(firstResult);
}
return q.getResultList();
} finally {
em.close();
}
}
public Book findBook(String id) {
EntityManager em = getEntityManager();
try {
return em.find(Book.class, id);
} finally {
em.close();
}
}
public int getBookCount() {
EntityManager em = getEntityManager();
try {
CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
Root<Book> rt = cq.from(Book.class);
cq.select(em.getCriteriaBuilder().count(rt));
Query q = em.createQuery(cq);
return ((Long) q.getSingleResult()).intValue();
} finally {
em.close();
}
}
}
手工编写Servlet调用自动生成的Controller进行CRUD
package com.example.jpawebtomcat;
import com.example.jpawebtomcat.exceptions.NonexistentEntityException;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(name = "BookServlet", urlPatterns = {"/BookServlet"})
public class BookServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final String PERSISTENCE_UNIT_NAME = "com.example_jpawebtomcat_war_1.0-SNAPSHOTPU";
private BookJpaController bookDao;
@Override
public void init() {
EntityManagerFactory emFactory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
bookDao = new BookJpaController(emFactory);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String action = request.getParameter("action");
if (action == null) {
action = "";
}
switch (action) {
case "new":
showNewForm(request, response);
break;
case "insert":
insertBook(request, response);
break;
case "delete":
deleteBook(request, response);
break;
case "edit":
showEditForm(request, response);
break;
case "update":
updateBook(request, response);
break;
default:
listBook(request, response);
break;
}
}
private void listBook(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
List<Book> listBook = bookDao.findBookEntities();
request.setAttribute("listBook", listBook);
RequestDispatcher dispatcher = request.getRequestDispatcher("book-list.jsp");
dispatcher.forward(request, response);
}
private void showNewForm(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
RequestDispatcher dispatcher = request.getRequestDispatcher("book-form.jsp");
dispatcher.forward(request, response);
}
private void showEditForm(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Book existingBook = bookDao.findBook(request.getParameter("bid"));
RequestDispatcher dispatcher = request.getRequestDispatcher("book-form.jsp");
request.setAttribute("book", existingBook);
dispatcher.forward(request, response);
}
private void insertBook(HttpServletRequest request, HttpServletResponse response)
throws IOException {
Book newBook = new Book();
newBook.setAuthor(request.getParameter("author"));
newBook.setBid(request.getParameter("bid"));
newBook.setTitle(request.getParameter("title"));
newBook.setStatus(request.getParameter("status"));
try {
bookDao.create(newBook);
} catch (Exception ex) {
Logger.getLogger(BookServlet.class.getName()).log(Level.SEVERE, null, ex);
}
response.sendRedirect("?action=list");
}
private void updateBook(HttpServletRequest request, HttpServletResponse response)
throws IOException {
Book book = new Book();
book.setAuthor(request.getParameter("author"));
book.setBid(request.getParameter("bid"));
book.setTitle(request.getParameter("title"));
book.setStatus(request.getParameter("status"));
try {
bookDao.edit(book);
} catch (Exception ex) {
Logger.getLogger(BookServlet.class.getName()).log(Level.SEVERE, null, ex);
}
response.sendRedirect("?action=list");
}
private void deleteBook(HttpServletRequest request, HttpServletResponse response)
throws IOException {
try {
bookDao.destroy(request.getParameter("bid"));
} catch (NonexistentEntityException ex) {
Logger.getLogger(BookServlet.class.getName()).log(Level.SEVERE, null, ex);
}
response.sendRedirect("?action=list");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
手工编写html和jsp页面
book-list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>Book Management Application</title>
</head>
<body>
<center>
<h1>Book Management</h1>
<h2>
<a href="?action=new">Add New Book</a>
<a href="?action=list">List All Books</a>
</h2>
</center>
<div align="center">
<table border="1" cellpadding="5">
<caption><h2>List of Books</h2></caption>
<tr>
<th>ID</th>
<th>Author</th>
<th>Status</th>
<th>Title</th>
<th>Actions</th>
</tr>
<c:forEach var="book" items="${listBook}">
<tr>
<td><c:out value="${book.bid}" /></td>
<td><c:out value="${book.author}" /></td>
<td><c:out value="${book.status}" /></td>
<td><c:out value="${book.title}" /></td>
<td>
<a href="?action=edit&bid=<c:out value='${book.bid}' />">Edit</a>
<a href="?action=delete&bid=<c:out value='${book.bid}' />">Delete</a>
</td>
</tr>
</c:forEach>
</table>
</div>
</body>
</html>
book-form.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>Book Management Application</title>
</head>
<body>
<center>
<h1>Book Management</h1>
<h2>
<a href="?action=new">Add New Book</a>
<a href="?action=list">List All Books</a>
</h2>
</center>
<div align="center">
<c:if test="${book != null}">
<form action="?action=update" method="post">
</c:if>
<c:if test="${book == null}">
<form action="?action=insert" method="post">
</c:if>
<table border="1" cellpadding="5">
<caption>
<h2>
<c:if test="${book != null}">
Edit Book
</c:if>
<c:if test="${book == null}">
Add New Book
</c:if>
</h2>
</caption>
<tr>
<th>Book ID: </th>
<td>
<input type="text" name="bid" size="45"
value="<c:out value='${book.bid}' />"
/>
</td>
</tr>
<tr>
<th>Book Author: </th>
<td>
<input type="text" name="author" size="45"
value="<c:out value='${book.author}' />"
/>
</td>
</tr>
<tr>
<th>Book Status: </th>
<td>
<input type="text" name="status" size="45"
value="<c:out value='${book.status}' />"
/>
</td>
</tr>
<tr>
<th>Book Title: </th>
<td>
<input type="text" name="title" size="15"
value="<c:out value='${book.title}' />"
/>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="Save" />
</td>
</tr>
</table>
</form>
</div>
</body>
</html>
在pom.xml中增加数据库驱动包
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>jpawebtomcat</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>jpawebtomcat</name>
<properties>
<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.core</artifactId>
<version>2.7.9</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.asm</artifactId>
<version>9.1.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.antlr</artifactId>
<version>2.7.9</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>2.7.9</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa.jpql</artifactId>
<version>2.7.9</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.moxy</artifactId>
<version>2.7.9</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
<version>2.7.9</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<compilerArguments>
<endorseddirs>${endorsed.dir}</endorseddirs>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<outputDirectory>${endorsed.dir}</outputDirectory>
<silent>true</silent>
<artifactItems>
<artifactItem>
<groupId>javax</groupId>
<artifactId>javaee-endorsed-api</artifactId>
<version>7.0</version>
<type>jar</type>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
向导使用的JPA实现是EclipseLink:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="com.example_jpawebtomcat_war_1.0-SNAPSHOTPU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>com.example.jpawebtomcat.Book</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<shared-cache-mode>NONE</shared-cache-mode>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/db?autoReconnect=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="javax.persistence.jdbc.password" value="root"/>
</properties>
</persistence-unit>
</persistence>
TOMCAT下运行输出:
源码下载: