工作过的项目用的是非常老旧的框架:Spring + Hibernate + DWR,DAO 层的绝大多数现成的方法基本还是内部老前辈们写的,什么 queryList、queryMap、querySingleObj 乱七八糟的,平时都是直接拿来用,也是方便
最近闲下来,就了解一下当下(其实也不是)比较主流的框架,SSH 好像都比较少了,目前大都是 SpringMVC 了来着,持久层要么是 Hibernate,要么是 MyBatis,因为好歹用过 Hibernate,所以先学着写了个小 demo 熟悉下这个框架
Eclipse 新建一个 Dynamic Web Project,然后转成的 Maven Project
随便建一张 book 表:
CREATE TABLE `book` (
`id` int(6) NOT NULL AUTO_INCREMENT,
`book_name` varchar(20) DEFAULT NULL,
`book_author` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8;
<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.0modelVersion>
<groupId>BookDemogroupId>
<artifactId>BookDemoartifactId>
<version>1.0.0version>
<packaging>warpackaging>
<build>
<finalName>BookDemofinalName>
<sourceDirectory>srcsourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-pluginartifactId>
<version>3.6.1version>
<configuration>
<source>1.8source>
<target>1.8target>
configuration>
plugin>
<plugin>
<artifactId>maven-war-pluginartifactId>
<version>3.0.0version>
<configuration>
<warSourceDirectory>WebContentwarSourceDirectory>
configuration>
plugin>
plugins>
build>
<properties>
<spring.version>4.1.5.RELEASEspring.version>
<hibernate.version>4.3.8.Finalhibernate.version>
<mysql.version>5.1.40mysql.version>
<junit-version>4.11junit-version>
<servlet-api-version>3.1.0servlet-api-version>
<jsp-version>2.1jsp-version>
<jstl-version>1.2jstl-version>
properties>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-ormartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>${spring.version}version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.hibernategroupId>
<artifactId>hibernate-coreartifactId>
<version>${hibernate.version}version>
dependency>
<dependency>
<groupId>org.hibernategroupId>
<artifactId>hibernate-c3p0artifactId>
<version>${hibernate.version}version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>${mysql.version}version>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>${servlet-api-version}version>
dependency>
<dependency>
<groupId>javax.servlet.jspgroupId>
<artifactId>jsp-apiartifactId>
<version>${jsp-version}version>
<scope>providedscope>
dependency>
<dependency>
<groupId>jstlgroupId>
<artifactId>jstlartifactId>
<version>${jstl-version}version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>${junit-version}version>
<scope>testscope>
dependency>
dependencies>
project>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>Archetype Created Web Applicationdisplay-name>
<welcome-file-list>
<welcome-file>index.jspwelcome-file>
welcome-file-list>
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>/WEB-INF/bookDemo-servlet.xmlparam-value>
context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>
<servlet>
<servlet-name>bookDemoservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>bookDemoservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
<filter>
<filter-name>SpringEncodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
<init-param>
<param-name>forceEncodingparam-name>
<param-value>trueparam-value>
init-param>
filter>
<filter-mapping>
<filter-name>SpringEncodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
web-app>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="com.priest.book" />
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/springmvc_demo?useUnicode=true&characterEncoding=UTF-8" />
<property name="username" value="root" />
<property name="password" value="mysql" />
bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource">property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialectprop>
<prop key="hibernate.show_sql">trueprop>
<prop key="hibernate.format_sql">trueprop>
props>
property>
<property name="packagesToScan" value="com.priest.book.model">property>
bean>
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory">property>
bean>
<tx:annotation-driven transaction-manager="txManager" />
beans>
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "book")
public class BookVO implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@Column(name="book_name")
private String bookName;
@Column(name="book_author")
private String bookAuthor;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getBookAuthor() {
return bookAuthor;
}
public void setBookAuthor(String bookAuthor) {
this.bookAuthor = bookAuthor;
}
}
import java.util.List;
import com.priest.book.model.BookVO;
public interface IBookDao {
public void saveOrUpdateBook(BookVO book);
public List<BookVO> getBooks();
public BookVO getBookById(int id);
public void deleteBookById(int id);
}
import java.util.List;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.object.SqlQuery;
import org.springframework.stereotype.Repository;
import com.priest.book.model.BookVO;
@Repository
public class BookDaoImpl implements IBookDao {
@Autowired
private SessionFactory sessionFactory;
@Override
public void saveOrUpdateBook(BookVO book) {
Session session = sessionFactory.getCurrentSession();
session.saveOrUpdate(book);
}
@Override
public List<BookVO> getBooks() {
Session session = sessionFactory.getCurrentSession();
SQLQuery query = session.createSQLQuery("select * from book").addEntity(BookVO.class);
List<BookVO> list = query.list();
//List list = session.createQuery(" from BookVO ").list();
return list;
}
@Override
public BookVO getBookById(int id) {
Session session = sessionFactory.getCurrentSession();
BookVO book = new BookVO();
// SQLQuery query = session.createSQLQuery("select * from book where id = ?").addEntity(BookVO.class);
// query.setInteger(0, id);
// List result = query.list();
// if(result != null && result.size() > 0) {
// book = result.get(0);
// }
book = (BookVO) session.get(BookVO.class, id);
return book;
}
@Override
public void deleteBookById(int id) {
Session session = sessionFactory.getCurrentSession();
// SQLQuery query = session.createSQLQuery(" delete from book where id = ? ").addEntity(BookVO.class);
// query.setInteger(0, id);
// query.executeUpdate();
BookVO book = (BookVO) session.get(BookVO.class, id);
session.delete(book);
}
}
import java.util.List;
import com.priest.book.model.BookVO;
public interface IBookService {
public void saveOrUpdateBook(BookVO book);
public List<BookVO> getBooks();
public BookVO getBookById(int id);
public void deleteBookById(int id);
}
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.priest.book.dao.IBookDao;
import com.priest.book.model.BookVO;
@Service
@Transactional
public class BookServiceImpl implements IBookService {
@Autowired
private IBookDao bookDao;
@Override
public void saveOrUpdateBook(BookVO book) {
bookDao.saveOrUpdateBook(book);
}
@Override
public List<BookVO> getBooks() {
return bookDao.getBooks();
}
@Override
public BookVO getBookById(int id) {
return bookDao.getBookById(id);
}
@Override
public void deleteBookById(int id) {
bookDao.deleteBookById(id);
}
}
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.priest.book.model.BookVO;
import com.priest.book.service.IBookService;
@Controller
@RequestMapping("/book")
public class BookController {
@Autowired
private IBookService bookService;
@RequestMapping(value= {"/bookList","/"}, method = RequestMethod.GET)
public ModelAndView listAllBooks(ModelAndView model) {
List<BookVO> books = bookService.getBooks();
model.addObject("bookList", books);
model.setViewName("books");
return model;
}
//另一种写法
// @RequestMapping(value= {"/bookList","/"}, method = RequestMethod.GET)
// public String listAllBooks(Model model) {
// List books = bookService.getBooks();
//
// model.addAttribute("bookList", books);
//
// return "books";
// }
@RequestMapping(value = "/newBook", method = RequestMethod.GET)
public ModelAndView newBook(ModelAndView model) {
BookVO book = new BookVO();
model.addObject("book", book);
model.setViewName("addOrUpdateBook");
return model;
}
@RequestMapping(value = "saveOrUpdateBook", method = RequestMethod.POST)
public ModelAndView saveOrUpdateBook(@ModelAttribute BookVO book) {
bookService.saveOrUpdateBook(book);
return new ModelAndView("operationSuccess");
}
@RequestMapping(value = "modifyBook", method = RequestMethod.GET)
public ModelAndView modifyBook(HttpServletRequest request) {
int id = Integer.parseInt(request.getParameter("id"));
BookVO book = bookService.getBookById(id);
ModelAndView model = new ModelAndView("addOrUpdateBook");
model.addObject("book", book);
return model;
}
@RequestMapping(value = "deleteBook", method = RequestMethod.GET)
public ModelAndView deleteBook(HttpServletRequest request) {
int id = Integer.parseInt(request.getParameter("id"));
bookService.deleteBookById(id);
return new ModelAndView("operationSuccess");
}
}
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>书title>
head>
<body>
<table border="1">
<tr>
<th>IDth>
<th>书名th>
<th>作者th>
<th>操作th>
tr>
<c:forEach items="${bookList}" var="book">
<tr>
<td>${book.id}td>
<td>${book.bookName}td>
<td>${book.bookAuthor}td>
<td><a href="' /book/modifyBook?id=${book.id}' />">编辑a>
<a href="' /book/deleteBook?id=${book.id}' />">删除a>
td>
tr>
c:forEach>
table>
<br />
<a href="' /book/newBook' />">添加图书a>
body>
html>
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>新增/修改图书title>
head>
<body>
<h3>新增/修改图书h3>
<form:form action="saveOrUpdateBook" method="post" modelAttribute="book">
<table>
<form:hidden path="id" />
<tr>
<td>书名:td>
<td><form:input path="bookName" />td>
tr>
<tr>
<td>作者:td>
<td><form:input path="bookAuthor" />td>
tr>
<tr>
<td><input type="submit" value="保存" />td>
tr>
table>
form:form>
body>
html>
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>书title>
head>
<body>
操作成功!<br/>
<a href="' /book/bookList' />">返回列表a>
body>
html>
新打开的页面:
操作的页面:
操作完成:
返回列表:
第一个最头大的问题当属引入了 jar 包,类中引用一直提示找不到的问题,在我[上一篇博客]({{ site.url }}/编程工具/2017/11/26/Eclipse通过Maven引入jar包但类中依旧找不到的问题/)中讲了这个问题
在 jsp 中本来可以使用 对象.属性 的方式取得内容,就像这样:
<c:forEach items="${bookList}" var="book">
<tr>
<td>${book.id}td>
<td>${book.bookName}td>
<td>${book.bookAuthor}td>
tr>
c:forEach>
在写代码的过程中,由于一个地方的失误:
把 model 的包路径写错了,导致:
查到的对象不能绑定为 BookVO,而是 Object,这样的话在 jstl 中使用 对象.属性 的时候就报错了
虽然是自己的一个小失误,除了配置中修改错误,映射正确的 VO 类外,这时候还可以使用下标的方式取的内容:
<c:forEach items="${bookList}" var="book">
<tr>
<td>${book[0]}td>
<td>${book[1]}td>
<td>${book[2]}td>
tr>
c:forEach>
项目中有几个地方要注意编码:
MySQL 数据库的配置
.xml 配置文件中数据源链接
jsp 页面的编码
最后参考学习,在 web.xml 中添加了 spring 的编码过滤器:
<filter>
<filter-name>SpringEncodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
<init-param>
<param-name>forceEncodingparam-name>
<param-value>trueparam-value>
init-param>
filter>
<filter-mapping>
<filter-name>SpringEncodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
一开始只在代码里给 VO 类注解了 ID 是自增,调用保存的时候报错:
java.sql.SQLException: Field 'id' doesn't have a default value
查询后发现是数据库里忘记给主键设置自增导致的
参考学习:
http://javawebtutor.com/articles/spring/spring-mvc-hibernate-crud-example.php
https://howtodoinjava.com/spring/spring-mvc/spring-mvc-hello-world-example/