本案例用于建立一个较为完整的案例,实现书本的增加删除修改查询
1 创建数据库
案例使用Mysql,数据库脚本代码如下:
CREATE DATABASE IF NOT EXISTS `itcaststore` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `itcaststore`;
-- MySQL dump 10.13 Distrib 5.6.13, for Win32 (x86)
--
-- Host: localhost Database: itcaststore
-- ------------------------------------------------------
-- Server version 5.7.3-m13-log
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `notice`
--
DROP TABLE IF EXISTS `notice`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `notice` (
`n_id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(10) DEFAULT NULL,
`details` varchar(255) DEFAULT NULL,
`n_time` varchar(18) DEFAULT NULL,
PRIMARY KEY (`n_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `notice`
--
LOCK TABLES `notice` WRITE;
/*!40000 ALTER TABLE `notice` DISABLE KEYS */;
INSERT INTO `notice` VALUES (1,'暂停当日达业务','尊敬的网上书城用户, <br>\r\n 为了让大家有更好的购物体验,3月25日起,当日达业务关小黑屋回炉升级!<br>具体开放时间请留意公告,感谢大家的支持与理解,祝大家购物愉快!<br>\r\n3月23日<br>\r\n传智播客 网上书城系统管理部<br>','20160111113420'),(2,'年货礼包兑换时间通知','尊敬的网上书城用户:\r\n 非常抱歉,因为年后部分供应商工厂开工较晚,导致个别商品到货延迟。\r\n 基于此,15年年货礼包的兑换入口会延期到3月17日,请您在有效期内完成兑换。\r\n 以下礼包预计本周四,即3月12日到货。造成不便深表歉意,敬请谅解。','20160111113411');
/*!40000 ALTER TABLE `notice` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `orderitem`
--
DROP TABLE IF EXISTS `orderitem`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `orderitem` (
`order_id` varchar(100) NOT NULL DEFAULT '',
`product_id` varchar(100) NOT NULL DEFAULT '',
`buynum` int(11) DEFAULT NULL,
PRIMARY KEY (`order_id`,`product_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `orderitem`
--
LOCK TABLES `orderitem` WRITE;
/*!40000 ALTER TABLE `orderitem` DISABLE KEYS */;
INSERT INTO `orderitem` VALUES ('0c0796f2-0124-4a13-a891-5efbb63b04f9','79bbe618-d2f8-4081-b35a-62ebbe938b64',1),('305a7870-3820-4079-b6f9-5d2b63cbcd2a','72c52302-cd1e-4a22-8ac8-dc300a915be5',1),('611f80fa-4273-4674-be09-9530b6276e15','84c842da-16b6-4e87-953e-859a1ca62bab',1),('677a7314-0e16-4e18-8aec-552f848e0d75','3a0196b2-71c1-4d4d-a4e8-d1f875096f00',1),('677a7314-0e16-4e18-8aec-552f848e0d75','bf66a00c-4a78-458b-93c8-08896ee14976',1),('6f591522-7a2a-4a31-899d-ef1181c72f5f','9a7af97e-deea-417e-ad66-23ea755d2a51',1),('7ae96e6d-4600-41a5-bc5d-143b34ba61db','bdb32537-8f2c-4ba2-a752-94fdc0e9a250',1),('a5bfb13d-9085-4374-94d9-4864b4d618ab','9a7af97e-deea-417e-ad66-23ea755d2a51',1),('c4b2bfff-1694-4e28-bcf8-fa7169bfc978','3a0196b2-71c1-4d4d-a4e8-d1f875096f00',2),('c4b2bfff-1694-4e28-bcf8-fa7169bfc978','79bbe618-d2f8-4081-b35a-62ebbe938b64',2),('d88d75cd-15e3-4622-801d-4cad902aeaa1','3cdd01d2-95d4-4077-b512-ff4c3b340d6b',1);
/*!40000 ALTER TABLE `orderitem` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `orders`
--
DROP TABLE IF EXISTS `orders`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `orders` (
`id` varchar(100) NOT NULL,
`money` double DEFAULT NULL,
`receiverAddress` varchar(255) DEFAULT NULL,
`receiverName` varchar(20) DEFAULT NULL,
`receiverPhone` varchar(20) DEFAULT NULL,
`paystate` int(11) DEFAULT '0',
`ordertime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`user_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `orders`
--
LOCK TABLES `orders` WRITE;
/*!40000 ALTER TABLE `orders` DISABLE KEYS */;
INSERT INTO `orders` VALUES ('0c0796f2-0124-4a13-a891-5efbb63b04f9',44.5,'北京市昌平区金燕龙办公楼','hanyongmeng','15207545526',1,'2016-05-18 02:36:36',4),('305a7870-3820-4079-b6f9-5d2b63cbcd2a',59,'北京市昌平区建材城西路金燕龙办公楼','huangyun','13041019968',0,'2016-01-13 07:14:54',3),('611f80fa-4273-4674-be09-9530b6276e15',89,'北京市海淀区清河永泰园5号楼501','huangyun','13041019968',1,'2016-01-10 10:00:36',3),('677a7314-0e16-4e18-8aec-552f848e0d75',65,'北京市昌平区','hanyongmeng','15207545526',0,'2016-05-18 03:33:25',4),('6f591522-7a2a-4a31-899d-ef1181c72f5f',25,'北京市昌平区金燕龙办公楼一层传智播客','madan','13269219270',0,'2016-01-10 10:00:36',2),('7ae96e6d-4600-41a5-bc5d-143b34ba61db',35,'北京市昌平区建材城西路','madan','13269219270',0,'2016-02-25 02:44:56',2),('a5bfb13d-9085-4374-94d9-4864b4d618ab',25,'海淀区圆明园西路','hanyongmeng','13455260812',1,'2016-02-25 02:43:40',4),('c4b2bfff-1694-4e28-bcf8-fa7169bfc978',129,'北京市昌平区北七家镇','hanyongmeng','15207545526',1,'2016-05-18 02:36:22',4),('d88d75cd-15e3-4622-801d-4cad902aeaa1',25,'北京市昌平区建材城西路金燕龙办公楼','hanyongmeng','13848399998',1,'2016-02-25 02:44:23',4);
/*!40000 ALTER TABLE `orders` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `products`
--
DROP TABLE IF EXISTS `products`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `products` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(40) DEFAULT NULL,
`price` double DEFAULT NULL,
`category` varchar(40) DEFAULT NULL,
`pnum` int(11) DEFAULT NULL,
`imgurl` varchar(100) DEFAULT NULL,
`description` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `products`
--
LOCK TABLES `products` WRITE;
/*!40000 ALTER TABLE `products` DISABLE KEYS */;
INSERT INTO `products` VALUES (1,'.net设计规范',50,'计算机',16,'/productImg/12/13/bba5ddf2-2a56-4a88-9d1b-abc8e0202ec9.jpg',''),(2,'网管员必备宝典',20,'计算机',15,'/productImg/4/3/0270eba2-2b48-48df-956b-0341204384d9.jpg','计算机类'),(3,'学会宽容',25,'文学',5,'/productImg/6/5/a2da626c-c72d-4972-83de-cf48405c5563.jpg','该书阐述了宽容是一种智慧和力量,是对生命的洞悉,是成长的绿荫,更是家庭幸福的秘诀。常用宽容的眼光看世界,事业、家庭和友谊才能稳固和长久。'),(4,'杜拉拉升职记',54,'原版',198,'/productImg/5/8/c4ab442f-95c7-4d6f-a57e-3eb7dc6b83c4.jpg','职场生活'),(5,'时空穿行',42,'科技',200,'/productImg/12/12/6cc3c25b-2475-496e-9ad7-5e9491e7aaf8.jpg','《时空穿行(中国乡村人类学世纪回访)》对20世纪80年代以来中国云南大理西镇、广东潮州凤凰村、华南茶山等八个代表性乡村田野进行调查,探讨了中国乡村文化的多样性、宗族制度、农民社会等课题。'),(6,'培育男孩',59,'社科',94,'/productImg/3/1/81967f4f-0a39-4b03-8ecc-053365a35605.jpg','如何教育孩子'),(7,'Java基础入门',44.5,'计算机',7,'/productImg/9/0/697a23d6-225a-41a3-8c20-7ab624265ecc.png','《Java基础入门》从初学者的角度详细讲解了Java开发中重点用到的多种技术。全书共11章,包括Java开发环境的搭建及其运行机制、基本语法、面向对象的思想,采用典型翔实的例子、通俗易懂的语言阐述面向对象中的抽象概念。在多线程、常用API、集合、IO、GUI、网络编程章节中,通过剖析案例、分析代码结构含义、解决常见问题等方式,帮助初学者培养良好的编程习惯。最后,讲解了Eclipse开发工具,帮助初学者熟悉开发工具的使用。'),(8,'赢在影响力',89,'励志',47,'/productImg/2/8/acc9d557-f8c9-426b-9aec-50a5a7cf3960.jpg','《赢在影响力:人际交往的学问》创造了全球出版史上空前的发行记录。它深深地触动着读者的神经,满足了他们在人性方面的需要,因此成为经济萧条后期超越流行的读物。它居高不下的销售记录一直持续至20世纪80年代,经历了几乎半个世纪。'),(9,'大勇和小花的欧洲日记',26,'生活百科',100,'/productImg/3/0/3253aeee-5462-47d0-991c-afb568ab3b03.jpg','《大勇和小花的欧洲日记》串起了欧洲文明的溯源之旅。从屹立在近现代艺术之巅的巴黎拾级而下,依次是蓬皮杜博物馆(现代艺术)、奥塞博物馆(印象派艺术)、卢浮宫博物馆(古典主义)。在这里,蒙娜丽莎向文艺复兴的故乡微笔,那是意大利的佛罗伦萨。达芬奇、米开朗琪罗、拉菲尔等巨匠们开创了文艺复兴运动,他们心中的圣地是希腊,似乎已到了起源。然而,这并未到头,与这源头对接的还有遥远的希腊神话,其中有大西洲的传说。在希腊小岛圣托里尼,你看见Atlantica酒店吗?那是人们为大西洲刻下的念想。'),(10,'Java Web程序开发入门',44.5,'计算机',100,'/productImg/9/3/eac105d4-4ab5-4af9-9061-e255016b79d9.png','本书为Java Web开发入门教材,让初学者达到能够灵活使用Java语言开发Web应用程序的程度。为了让初学者易于学习,本书力求内容通俗易懂,讲解寓教于乐,同时针对书中的每个知识点,都精心设计了经典案例,让初学者真正理解这些知识点在实际工作中如何去运用。'),(11,'谁动了我的奶酪',26,'少儿',200,'/productImg/14/11/ebcee924-7d42-43f8-b974-fbdb900bdb58.jpg','儿童作品'),(12,'别做正常的傻瓜',18,'励志',2,'/productImg/14/1/792116e7-6d83-4be4-b3e5-4dd11b0b4565.jpg','本书结合了作者十余年的教学经验,融合了诺贝尔奖得主及其他学者数十年的研究成果,用深入浅出的方法帮助你发现自己决策中的误区,从而使你比大多数人少几分正常,多几分理性,本书所涉及的决策范围广,包括购买什么商品,和什么人结婚,雇用哪些员工,投资什么股票等等。除非你从不做决策,否则本书对你一定有所借鉴。'),(13,'培育男孩',25,'生活',8,'/productImg/2/7/7ede11f8-3ff9-4c12-ad58-b1d5e0e72032.jpg','本书是美国著名家庭问题和儿童教育问题专家、畅销书作家詹姆士·杜布森的新作。全书围绕值得令人类关注的培育男孩问题,讨论了家庭教育、学校教育、父母关爱,以及整个社会文化对男孩成长的影响。针对美国社会普遍存在的男孩教育问题,如父亲缺席、母亲上班、暴力泛滥、单亲家庭、同性恋、学校对男孩特点的忽视等等,提出了自己的看法和解决思路,具有很强的指导性和可操作性,是父母、教师和青年工作者的必读参考书。'),(14,'travelbook',20,'外语',20,'/productImg/15/1/5394df32-ed6e-4203-b9c0-fc175cfc187e.jpg',''),(15,'经济案例解析',35,'经营',98,'/productImg/11/1/8efe720f-fa72-435b-a3c3-69230f9677cc.jpg',''),(16,'美国纽约摄影学院摄影教材',45,'艺术',99,'/productImg/13/2/20788b05-d298-4a7c-91d9-370fb056f6a5.jpg','艺术教材'),(17,'系统分析师教程',54,'考试',300,'/productImg/5/11/e4d290ce-3355-466f-a51e-13c62552d2cb.jpg','系统分析师'),(18,'中国国家地理',20,'学术',20,'/productImg/2/0/2105fbe5-400f-4193-a7db-d7ebac389550.jpg','《中国国家地理》,原名《地理知识》,是关于地理的月刊,该刊的文章和图片经常被中央及地方媒体转载。具有很强的可读性和收藏价值,国内外很多家图书馆已经把该刊作为重点收藏期刊。内容以中国地理为主,兼具世界各地不同区域的自然、人文景观和事件,并揭示其背景和奥秘,另亦涉及天文、生物、历史和考古等领域。是中国大陆著名的有关地理的杂志。因该社隶属中国科学院,有一大批自然地理和人文地理的专家学者作为该社顾问,同时还有许多战斗在科考第一线的工作者与杂志社保持着密切联系,因此具有很强的独家性和权威性。');
/*!40000 ALTER TABLE `products` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `user`
--
DROP TABLE IF EXISTS `user`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(20) NOT NULL,
`PASSWORD` varchar(20) NOT NULL,
`gender` varchar(2) DEFAULT NULL,
`email` varchar(50) DEFAULT NULL,
`telephone` varchar(20) DEFAULT NULL,
`introduce` varchar(100) DEFAULT NULL,
`activeCode` varchar(50) DEFAULT NULL,
`state` int(11) DEFAULT '0',
`role` varchar(10) DEFAULT '普通用户',
`registTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `user`
--
LOCK TABLES `user` WRITE;
/*!40000 ALTER TABLE `user` DISABLE KEYS */;
INSERT INTO `user` VALUES (1,'admin','123456','男','huan9yun@163.com','13041019968','我是超级管理员,我可以登录后台管理系统','49338fdc-d8c9-46fa-8391-0fac7bf09707',1,'超级用户','2015-03-19 08:16:40'),(2,'madan','123456','女','huan9yun@163.com','13269219270','我是一个课程设计师','c1cc1229-f0ac-41b4-920c-dfef9f8a96a3',1,'普通用户','2015-03-19 10:12:36'),(3,'huangyun','123456','男','huan9yun@163.com','13041019968','大家好,我是黄云','d0827d1d-dc0d-4cdc-8710-678ce917880e',1,'普通用户','2015-03-20 09:36:38'),(4,'hanyongmeng','123456','男','itcast_hym@163.com','15207545526','课程设计师','da483412-1e34-43cf-aef2-4925748c811d',1,'普通用户','2016-01-21 07:19:32'),(5,'tianjiao','123456','男','hanyongmeng@126.cn','','','f8173f4f-debe-4d32-8117-b228d555d822',0,'普通用户','2016-02-18 07:32:01');
/*!40000 ALTER TABLE `user` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-10-08 10:23:52
2 创建Spring boot项目
名称为chap04-jdbc-mysql,
1配置lib
文件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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>chap04-jdbc-mysql</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>chap04-jdbc-mysql</name>
<description>使用jdbc连接mysql数据库</description>
<properties>
<java.version>1.8</java.version>
<!-- 消除pom文件第一行出错 -->
<maven-jar-plugin.version>3.0.0</maven-jar-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
</project>
2 配置项目
application.properties代码如下:
#mysql\u914D\u7F6E
spring.datasource.url=jdbc:mysql://localhost:3306/itcaststore?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
3 项目结构
项目结构如下图所示。
3 后台代码
1 数据实体
在包com.example.demo.models创建实体Product,Product.java代码如下:
package com.example.demo.models;
public class Product {
private long id;
private String name;
private double price;
private String category;
private int pnum;
private String imgurl;
private String description;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public int getPnum() {
return pnum;
}
public void setPnum(int pnum) {
this.pnum = pnum;
}
public String getImgurl() {
return imgurl;
}
public void setImgurl(String imgurl) {
this.imgurl = imgurl;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public String toString() {
return "Product [id=" + id + ", name=" + name + ", price=" + price + ", category=" + category + ", pnum=" + pnum
+ ", imgurl=" + imgurl + ", description=" + description + "]";
}
}
2 dao的实现
本层实现数据的增删改查。
1 创建IProductDao接口
在包com.example.demo.dao创建接口IProductDao,IProductDao.java代码如下:
package com.example.demo.dao;
import java.util.List;
import com.example.demo.models.Product;
/**
* 应用层定义对数据库Products表的的操作要求
* 对数据库的四个操作:增删改查
* @author Administrator
*
*/
public interface IProductDao {
/**
* 查所有书
* @return 所有的书本
*/
List<Product> findAll();
/**
* 添加一本书
* @return 返回添加的书本
*/
Product insertByProduct(Product product);
/**
* 更新书本信息
* @param product 要更新的书
* @return 跟新的书
*/
Product update(Product product);
/**
* 根据id删除书本
* @param id 要删除的书本的id
* @return 删除的书本
*/
void delete(long id);
/**
* 根据id查找书本
* @param id 要查找书本的id
* @return 返回要查找的书本
*/
Product findById(long id);
}
2 实现 IProductDao 接口
在包com.example.demo.dao创建类ProductDaoImpl,以实现IProductDao,ProductDaoImpl.java代码如下:
package com.example.demo.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;
import com.example.demo.models.Product;
/**
* 数据库维护人员实现应用层对数据库的操作要求 即:实现对表的增删改查操作
*
* @author Administrator
*
*/
@Repository
public class ProductDaoImpl implements IProductDao {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public List<Product> findAll() {
String sql = "SELECT id, name, price, category, pnum, imgurl, description FROM products;";
return jdbcTemplate.query(sql, new BeanPropertyRowMapper(Product.class));
}
@Override
public Product insertByProduct(Product product) {
String sql = "INSERT INTO products(name, price, category, pnum, imgurl, description) VALUES(?, ?, ?, ?, ?, ?)";
// 获得返回id的方法
KeyHolder keyHolder1 = new GeneratedKeyHolder();
jdbcTemplate.update(new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
PreparedStatement ps = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
ps.setString(1, product.getName());
ps.setDouble(2, product.getPrice());
ps.setString(3, product.getCategory());
ps.setInt(4, product.getPnum());
ps.setString(5, product.getImgurl());
ps.setString(6, product.getDescription());
return ps;
}
}, keyHolder1);
product.setId(keyHolder1.getKey().longValue());
// 无返回自增id
// jdbcTemplate.update(sql, product.getName(), product.getPrice(),
// product.getCategory(), product.getPnum(),
// product.getImgurl(), product.getDescription());
return product;
}
@Override
public Product update(Product product) {
String sql = "UPDATE products SET name=?, price=?, category=?, pnum=?, imgurl=?, description=? WHERE id=?";
int i = jdbcTemplate.update(sql, product.getName(), product.getPrice(), product.getCategory(),
product.getPnum(), product.getImgurl(), product.getDescription(), product.getId());
return product;
}
@Override
public void delete(long id) {
String sql = "DELETE FROM products WHERE id=?";
jdbcTemplate.update(sql, id);
}
@Override
public Product findById(long id) {
String sql = "SELECT id, name, price, category, pnum, imgurl, description FROM products WHERE id=?";
return (Product) jdbcTemplate.queryForObject(sql, new Object[] { id },
new BeanPropertyRowMapper(Product.class));
}
}
3 测试
在src/test/java目录下,创建包 com.example.demo.dao,在该包创建测试类ProductDaoImplTest,ProductDaoImplTest.java代码如下:
package com.example.demo.dao;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.example.demo.models.Product;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ProductDaoImplTest {
@Autowired
private ProductDaoImpl dao;
@Test
public void findAllTest() {
List<Product> list = dao.findAll();
for (Product product : list) {
System.out.println(product.toString());
}
System.out.println("打印结束");
}
@Test
public void insertByProductTest() {
Product p = new Product();
p.setName("1");
p.setPrice(1);
p.setCategory("计算机");
p.setPnum(1);
p.setImgurl("1");
p.setDescription("1");
p = dao.insertByProduct(p);
System.out.println("插入的结果为:\t" + p.toString());
}
@Test
public void updateTest() {
Product p = new Product();
p.setId(25);
p.setName("11");
p.setPrice(11);
p.setCategory("计算机");
p.setPnum(11);
p.setImgurl("11");
p.setDescription("11");
p = dao.update(p);
System.out.println("修改的结果为:\t" + p.toString());
}
@Test
public void findByIdTest() {
Product p = dao.findById(19);
System.out.println("查找到的记录为:" + p.toString());
}
@Test
public void deleteTest() {
for (int i = 25; i <= 26; i++) {
dao.delete(i);
}
System.out.println("删除成功!");
}
}
3 service实现
1 服务接口IProductService创建
在包com.example.demo.service中创建接口 IProductService,IProductService.java代码如下:
package com.example.demo.service;
import java.util.List;
import com.example.demo.models.Product;
/**
* 业务层接口
* @author Administrator
*
*/
public interface IProductService {
/**
* 获取所有 Product
*/
List<Product> findAll();
/**
* 新增 Product
*
* @param Product {@link Product}
*/
Product insertByProduct(Product Product);
/**
* 更新 Product
*
* @param Product {@link Product}
*/
Product update(Product Product);
/**
* 删除 Product
*
* @param id 编号
*/
void delete(Long id);
/**
* 获取 Product
*
* @param id 编号
*/
Product findById(Long id);
}
2 实现IProductService接口
在同一包中,创建ProductServiceImpl,实现IProductService接口。ProductServiceImpl.java代码如下:
package com.example.demo.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.demo.dao.IProductDao;
import com.example.demo.models.Product;
@Service
public class ProductServiceImpl implements IProductService {
@Autowired
private IProductDao dao;
@Override
public List<Product> findAll() {
return dao.findAll();
}
@Override
public Product insertByProduct(Product product) {
return dao.insertByProduct(product);
}
@Override
public Product update(Product product) {
return dao.update(product);
}
@Override
public void delete(Long id) {
dao.delete(id);
}
@Override
public Product findById(Long id) {
return dao.findById(id);
}
}
3 服务接口的测试
在src/test/java目录下,创建包com.example.demo.service,在该包中创建测试类ProductServiceTest,ProductServiceTest.java代码如下:
package com.example.demo.service;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.example.demo.models.Product;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ProductServiceTest {
@Autowired
private IProductService service;
@Test
public void findAllTest() {
List<Product> list = service.findAll();
for (Product product : list) {
System.out.println(product.toString());
}
System.out.println("打印结束");
}
@Test
public void insertByProductTest() {
Product p = new Product();
p.setName("1");
p.setPrice(1);
p.setCategory("计算机");
p.setPnum(1);
p.setImgurl("1");
p.setDescription("1");
p = service.insertByProduct(p);
System.out.println("插入的结果为:\t" + p.toString());
}
@Test
public void updateTest() {
Product p = new Product();
p.setId(25);
p.setName("11");
p.setPrice(11);
p.setCategory("计算机");
p.setPnum(11);
p.setImgurl("11");
p.setDescription("11");
p = service.update(p);
System.out.println("修改的结果为:\t" + p.toString());
}
@Test
public void findByIdTest() {
Product p = service.findById(1L);
System.out.println("查找到的记录为:" + p.toString());
}
@Test
public void deleteTest() {
for (long i = 25; i <= 26; i++) {
service.delete(i);
}
System.out.println("删除成功!");
}
}
4 控制器的实现
创建包 com.example.demo.cotroller ,在该包中创建控制器 ProductController, ProductController.java代码如下:
package com.example.demo.cotroller;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import com.example.demo.models.Product;
import com.example.demo.service.IProductService;
/**
* 用户处理对Product的增删改查请求
*
* @author Administrator
*
*/
@RestController
@RequestMapping("/product")
public class ProductController {
@Autowired
private IProductService service;
@RequestMapping("/list")
public List<Product> findAll() {
return service.findAll();
}
// RESTfull风格
// /product/1 /product/2 /product/18
@RequestMapping("/{id}")
public Product findById(@PathVariable long id) {
return service.findById(id);
}
@RequestMapping("/add")
public ModelAndView add(HttpServletRequest req, ModelAndView model) {
Product product = new Product();
product.setName(req.getParameter("name"));
product.setPrice(Float.parseFloat(req.getParameter("price")));
product.setPnum(Integer.parseInt(req.getParameter("pnum")));
product.setCategory(req.getParameter("category"));
product.setDescription(req.getParameter("description"));
service.insertByProduct(product);
return new ModelAndView("redirect:/index.html");
}
@RequestMapping("/add2")
public ModelAndView add(@ModelAttribute Product product) {
service.insertByProduct(product);
return new ModelAndView("redirect:/index.html");
}
@RequestMapping("/edit")
public ModelAndView edit(HttpServletRequest req, ModelAndView model) {
Product product = new Product();
product.setName(req.getParameter("name"));
product.setPrice(Float.parseFloat(req.getParameter("price")));
product.setPnum(Integer.parseInt(req.getParameter("pnum")));
product.setCategory(req.getParameter("category"));
product.setDescription(req.getParameter("description"));
product.setId(Long.parseLong(req.getParameter("id")));
service.update(product);
return new ModelAndView("redirect:/index.html");
}
@RequestMapping("/delete/{id}")
public boolean delete(@PathVariable long id) {
service.delete(id);
return true;
}
}
4 前台页面实现
本代码在src/main/resources/static目录中。
1 书店首页
首页为:index.html,代码为:
<!DOCTYPE html>
<html>
<head>
<title>我的书店</title>
<link href="//cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.min.css"
rel="stylesheet">
<script src="//cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdn.bootcss.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
</head>
<body>
<nav class="navbar navbar-default" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse"
data-target="#example-navbar-collapse">
<span class="sr-only">切换导航</span> <span class="icon-bar"></span> <span
class="icon-bar"></span> <span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">我的书店</a>
</div>
<div class="collapse navbar-collapse" id="example-navbar-collapse">
<ul class="nav navbar-nav">
<li><a onclick="showProduct('')">所有图书</a></li>
<li><a onclick="showProduct('计算机')">计算机</a></li>
<li><a onclick="showProduct('文学')">文学</a></li>
<li><a onclick="showProduct('原版')">原版</a></li>
<li><a onclick="showProduct('科技')">科技</a></li>
<li><a onclick="showProduct('社科')">社科</a></li>
</ul>
<div class="btn-group">
<a type="button" class="btn btn-default" href="add.html">
<span class="glyphicon" >添加</span>
</a>
</div>
</div>
</nav>
<table class="table">
<thead>
<tr>
<th>序号</th>
<th>书名</th>
<th>价格</th>
<th>种类</th>
<th>库存数量</th>
<th>简介</th>
<th>查看</th>
<th>修改</th>
<th>删除</th>
</tr>
</thead>
<tbody id="table">
</tbody>
</table>
<script type="text/javascript">
var max_length = 40;
function showProduct(category) {
$("#table").html("");
$.getJSON("/product/list", function(list) {
$.each(list, function(i, book) {
var desc = book.description;
if (desc.length > max_length) {
desc = desc.substring(0, max_length) + "...";
}
var line = "<tr>";
line = line + "<td>" + (i + 1) + "</td>";
line = line + "<td>" + book.name + "</td>";
line = line + "<td>" + book.price + "</td>";
line = line + "<td>" + book.category + "</td>";
line = line + "<td>" + book.pnum + "</td>";
line = line + "<td>" + desc + "</td>";
line = line + "<td><a href='/detail.html?id=" + book.id + "' target='_blank'>查看</a></td>";
line = line + "<td><a href='/edit.html?id=" + book.id + "' target='_blank'>修改</a></td>";
line = line + "<td><a href='/delete.html?id=" + book.id + "' target='_blank'>删除</a></td>";
line = line + "</tr>"
$("#table").append(line);
});
});
}
$(function() {
showProduct("");
});
</script>
</body>
</html>
2 书本详情
书本详情为detail.html页面,代码如下:
<!DOCTYPE html>
<html>
<head>
<title>我的书店</title>
<link href="//cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.min.css"
rel="stylesheet">
<script src="//cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdn.bootcss.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
</head>
<body>
<nav class="navbar navbar-default" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse"
data-target="#example-navbar-collapse">
<span class="sr-only">切换导航</span> <span class="icon-bar"></span> <span
class="icon-bar"></span> <span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">我的书店</a>
</div>
<div class="collapse navbar-collapse" id="example-navbar-collapse">
<ul class="nav navbar-nav">
<li><a onclick="showProduct('')">所有图书</a></li>
<li><a onclick="showProduct('计算机')">计算机</a></li>
<li><a onclick="showProduct('文学')">文学</a></li>
<li><a onclick="showProduct('原版')">原版</a></li>
<li><a onclick="showProduct('科技')">科技</a></li>
<li><a onclick="showProduct('社科')">社科</a></li>
</ul>
</div>
</nav>
<table class="table">
<tr>
<td>图片</td>
<td>
<table>
<tr>
<td>书名:</td>
<td id="name"></td>
</tr>
<tr>
<td>价格:</td>
<td id="price"></td>
</tr>
<tr>
<td>数量:</td>
<td id="pnum"></td>
</tr>
<tr>
<td>种类:</td>
<td id="category"></td>
</tr>
</table>
</td>
</tr>
<tr>
<td colspan="2" id="description"></td>
</tr>
</table>
<script type="text/javascript">
var max_length = 40;
//获取url中的参数
function getUrlParam(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
var r = window.location.search.substr(1).match(reg); //匹配目标参数
if (r != null)
return unescape(r[2]);
return null; //返回参数值
}
$(function() {
// 取得书本id号
var id = getUrlParam("id");
// 获取指定id的书本信息
$.getJSON("/product/"+id, function(product) {
$("#name").html(product.name);
$("#price").html(product.price);
$("#pnum").html(product.pnum);
$("#category").html(product.category);
$("#description").html(product.description);
});
});
</script>
</body>
</html>
3 增加书
书本详情为add.html页面,代码如下:
<!DOCTYPE html>
<html>
<head>
<title>我的书店</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="//cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.min.css"
rel="stylesheet">
<script src="//cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdn.bootcss.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
</head>
<body>
<nav class="navbar navbar-default" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse"
data-target="#example-navbar-collapse">
<span class="sr-only">切换导航</span> <span class="icon-bar"></span> <span
class="icon-bar"></span> <span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">我的书店</a>
</div>
<div class="collapse navbar-collapse" id="example-navbar-collapse">
<ul class="nav navbar-nav">
<li><a onclick="showProduct('')">所有图书</a></li>
<li><a onclick="showProduct('计算机')">计算机</a></li>
<li><a onclick="showProduct('文学')">文学</a></li>
<li><a onclick="showProduct('原版')">原版</a></li>
<li><a onclick="showProduct('科技')">科技</a></li>
<li><a onclick="showProduct('社科')">社科</a></li>
</ul>
</div>
</nav>
<form action="/product/add2" method="post">
<table class="table">
<tr>
<td>图片</td>
<td>
<table>
<tr>
<td>书名:</td>
<td><input type="text" name="name" /></td>
</tr>
<tr>
<td>价格:</td>
<td><input type="text" name="price" /></td>
</tr>
<tr>
<td>数量:</td>
<td><input type="text" name="pnum" /></td>
</tr>
<tr>
<td>种类:</td>
<td><input type="text" name="category" /></td>
</tr>
<tr>
<td>简介:</td>
<td><input type="text" name="description" /></td>
</tr>
</table>
</td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="提交" />
<input type="reset" value="重置" /></td>
</tr>
</table>
</form>
<script type="text/javascript">
</script>
</body>
</html>
4 修改书
书本详情为edit.html页面,代码如下:
<!DOCTYPE html>
<html>
<head>
<title>我的书店</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="//cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.min.css"
rel="stylesheet">
<script src="//cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdn.bootcss.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
</head>
<body>
<nav class="navbar navbar-default" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse"
data-target="#example-navbar-collapse">
<span class="sr-only">切换导航</span> <span class="icon-bar"></span> <span
class="icon-bar"></span> <span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">我的书店</a>
</div>
<div class="collapse navbar-collapse" id="example-navbar-collapse">
<ul class="nav navbar-nav">
<li><a onclick="showProduct('')">所有图书</a></li>
<li><a onclick="showProduct('计算机')">计算机</a></li>
<li><a onclick="showProduct('文学')">文学</a></li>
<li><a onclick="showProduct('原版')">原版</a></li>
<li><a onclick="showProduct('科技')">科技</a></li>
<li><a onclick="showProduct('社科')">社科</a></li>
</ul>
</div>
</nav>
<form action="/product/edit" method="post">
<table class="table">
<tr>
<td>图片</td>
<td>
<table>
<tr>
<td>书名:</td>
<td><input type="text" id="name" name="name" /></td>
</tr>
<tr>
<td>价格:</td>
<td><input type="text" id="price" name="price" /></td>
</tr>
<tr>
<td>数量:</td>
<td><input type="text" id="pnum" name="pnum" /></td>
</tr>
<tr>
<td>种类:</td>
<td><input type="text" id="category" name="category" /></td>
</tr>
<tr>
<td>简介:</td>
<td><input type="text" id="description" name="description" /></td>
</tr>
</table>
</td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="提交" />
<input type="reset" value="重置" />
<input type="hidden" id="id" name="id" value=""/>
</td>
</tr>
</table>
</form>
<script type="text/javascript">
var max_length = 40;
//获取url中的参数
function getUrlParam(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
var r = window.location.search.substr(1).match(reg); //匹配目标参数
if (r != null)
return unescape(r[2]);
return null; //返回参数值
}
$(function() {
// 取得书本id号
var id = getUrlParam("id");
// 获取指定id的书本信息
$.getJSON("/product/"+id, function(product) {
console.log(product);
$("#name").val(product.name);
$("#price").val(product.price);
$("#pnum").val(product.pnum);
$("#category").val(product.category);
$("#description").val(product.description);
$("#id").val(product.id);
});
});
</script>
</body>
</html>
5 删除书
书本详情为delete.html页面,代码如下:
<!DOCTYPE html>
<html>
<head>
<title>我的书店</title>
<link href="//cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.min.css"
rel="stylesheet">
<script src="//cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdn.bootcss.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
</head>
<body>
<nav class="navbar navbar-default" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse"
data-target="#example-navbar-collapse">
<span class="sr-only">切换导航</span> <span class="icon-bar"></span> <span
class="icon-bar"></span> <span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">我的书店</a>
</div>
<div class="collapse navbar-collapse" id="example-navbar-collapse">
<ul class="nav navbar-nav">
<li><a onclick="showProduct('')">所有图书</a></li>
<li><a onclick="showProduct('计算机')">计算机</a></li>
<li><a onclick="showProduct('文学')">文学</a></li>
<li><a onclick="showProduct('原版')">原版</a></li>
<li><a onclick="showProduct('科技')">科技</a></li>
<li><a onclick="showProduct('社科')">社科</a></li>
</ul>
</div>
</nav>
<table class="table">
<tr>
<td>图片</td>
<td>
<table>
<tr>
<td>书名:</td>
<td id="name"></td>
</tr>
<tr>
<td>价格:</td>
<td id="price"></td>
</tr>
<tr>
<td>数量:</td>
<td id="pnum"></td>
</tr>
<tr>
<td>种类:</td>
<td id="category"></td>
</tr>
</table>
</td>
</tr>
<tr>
<td colspan="2" id="description"></td>
</tr>
<tr>
<td colspan="2"><input type="hidden" id="id" name="id" value="">
<button onclick="javascript:del();">删除</button></td>
</tr>
</table>
<script type="text/javascript">
var max_length = 40;
var id;
//获取url中的参数
function getUrlParam(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
var r = window.location.search.substr(1).match(reg); //匹配目标参数
if (r != null)
return unescape(r[2]);
return null; //返回参数值
}
function closeWindow() {
var userAgent = navigator.userAgent;
if (userAgent.indexOf("Firefox") != -1 || userAgent.indexOf("Chrome") != -1) {
location.href = "about:blank";
} else {
window.opener = null;
window.open('', '_self');
}
window.close();
}
function del() {
$.ajax({
url: "/product/delete/"+id,
success: function(result) {
alert("删除成功!");
closeWindow();
},
error:function(result){
alert("删除失败!"+result);
}
});
}
$(function() {
// 取得书本id号
id = getUrlParam("id");
// 获取指定id的书本信息
$.getJSON("/product/"+id, function(product) {
$("#name").html(product.name);
$("#price").html(product.price);
$("#pnum").html(product.pnum);
$("#pnum").html(product.pnum);
$("#description").html(product.description);
$("#id").html(product.id);
});
});
</script>
</body>
</html>