SpringMVC+Hibernate+Maven+MySQL实现增删改查的一个小Demo

写在前面

工作过的项目用的是非常老旧的框架:Spring + Hibernate + DWR,DAO 层的绝大多数现成的方法基本还是内部老前辈们写的,什么 queryList、queryMap、querySingleObj 乱七八糟的,平时都是直接拿来用,也是方便

最近闲下来,就了解一下当下(其实也不是)比较主流的框架,SSH 好像都比较少了,目前大都是 SpringMVC 了来着,持久层要么是 Hibernate,要么是 MyBatis,因为好歹用过 Hibernate,所以先学着写了个小 demo 熟悉下这个框架


项目结构

Eclipse 新建一个 Dynamic Web Project,然后转成的 Maven Project

SpringMVC+Hibernate+Maven+MySQL实现增删改查的一个小Demo_第1张图片


数据库表

随便建一张 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;

主要代码配置

0. pom.xml

<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>

1. web.xml


<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>

2. applicationContext.xml(bookDemo-servlet.xml)

<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>

3. BookVO.java

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

4. IBookDao.java

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

5. BookDaoImpl.java

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

6. IBookService.java

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

7. BookServiceImpl.java

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

8. BookController.java

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");
	}
}

9. books.jsp

<%@ 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>

10. addOrUpdateBook.jsp

<%@ 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>

11. operationSuccess.jsp

<%@ 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>

运行结果

新打开的页面:

SpringMVC+Hibernate+Maven+MySQL实现增删改查的一个小Demo_第2张图片

操作的页面:

SpringMVC+Hibernate+Maven+MySQL实现增删改查的一个小Demo_第3张图片

操作完成:

SpringMVC+Hibernate+Maven+MySQL实现增删改查的一个小Demo_第4张图片

返回列表:

SpringMVC+Hibernate+Maven+MySQL实现增删改查的一个小Demo_第5张图片


遇到的问题

0. jar包使用异常

第一个最头大的问题当属引入了 jar 包,类中引用一直提示找不到的问题,在我[上一篇博客]({{ site.url }}/编程工具/2017/11/26/Eclipse通过Maven引入jar包但类中依旧找不到的问题/)中讲了这个问题

1. jstl 获取对象属性

在 jsp 中本来可以使用 对象.属性 的方式取得内容,就像这样:

<c:forEach items="${bookList}" var="book">
	<tr>
		<td>${book.id}td>
		<td>${book.bookName}td>
		<td>${book.bookAuthor}td>
	tr>
c:forEach>

在写代码的过程中,由于一个地方的失误:

SpringMVC+Hibernate+Maven+MySQL实现增删改查的一个小Demo_第6张图片

把 model 的包路径写错了,导致:

SpringMVC+Hibernate+Maven+MySQL实现增删改查的一个小Demo_第7张图片

查到的对象不能绑定为 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>

2. 乱码

项目中有几个地方要注意编码:

  • 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>

3. 主键自增

一开始只在代码里给 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/

你可能感兴趣的:(小代码)