文章目录
- 一、springJDBC实现 DAO层
- 1、创建springMVC工程,导入对应的依赖
- 2、创建dto实体类
- 3、创建数据源对象,jdbc模板对象jdbcTemplate
- 4、编写对应CRUD操作的DAO
- 二、service层
- 三 、restful实现Controller层
- 1、配置编码过滤器,前端控制器,HiddenHttpMethodFilter过滤器
- 2、配置spring的xml配置文件
- 3、对数据库的操作
- (1)查——GET
- (2)增——POST
- (3)改——PUT
- (3)删——DELETE
一、springJDBC实现 DAO层
spring对的jdbc封装,用springJDBC访问数据库,不用考虑复杂的获取连接,关闭连接等操作,可以直接执行sql语句实现对数据库的增删改查操作。
1、创建springMVC工程,导入对应的依赖
我把我用到的依赖都放在下面,导入MVC依赖就不用导入web依赖了,MVC里面包含web的依赖。
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.4.RELEASE</version>
</dependency>
<!-- 日志依赖 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!--spring mvc依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.4.RELEASE</version>
</dependency>
<!--spring与thymeleaf整合依赖-->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.15.RELEASE</version>
</dependency>
<!--c3p0依赖-->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!-- druid依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.14.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.1.14.RELEASE</version>
</dependency>
2、创建dto实体类
我用的是一个水果信息表,下面是数据库表和添加的一些信息。实体类属性名要与数据库表的对应属性名对应。
public class Fruit {
private String f_id;
private int s_id;
private String f_name;
private float f_price;
private int quantity;
public Fruit() {
}
public Fruit(String f_id, int s_id, String f_name, float f_price, int quantity) {
this.f_id = f_id;
this.s_id = s_id;
this.f_name = f_name;
this.f_price = f_price;
this.quantity = quantity;
}
public String getF_id() {
return f_id;
}
public void setF_id(String f_id) {
this.f_id = f_id;
}
public int getS_id() {
return s_id;
}
public void setS_id(int s_id) {
this.s_id = s_id;
}
public String getF_name() {
return f_name;
}
public void setF_name(String f_name) {
this.f_name = f_name;
}
public float getF_price() {
return f_price;
}
public void setF_price(float f_price) {
this.f_price = f_price;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
@Override
public String toString() {
return "fruit{" +
"f_id='" + f_id + '\'' +
", s_id=" + s_id +
", f_name='" + f_name + '\'' +
", f_price=" + f_price +
", quantity=" + quantity +
'}';
}
}
DROP TABLE IF EXISTS `fruits1`;
CREATE TABLE `fruits1` (
`f_id` char(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`s_id` int NOT NULL,
`f_name` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`f_price` decimal(8, 2) NOT NULL,
`quantity` int NULL DEFAULT 1000,
PRIMARY KEY (`f_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = DYNAMIC;
INSERT INTO `fruits1` VALUES ('001', 100, '香蕉', 3.50, 1005);
INSERT INTO `fruits1` VALUES ('002', 100, '苹果', 3.20, 975);
INSERT INTO `fruits1` VALUES ('003', 100, '梨', 4.00, 1000);
INSERT INTO `fruits1` VALUES ('004', 100, '香蕉', 3.60, 1000);
INSERT INTO `fruits1` VALUES ('005', 100, '芒果', 5.00, 1000);
INSERT INTO `fruits1` VALUES ('008', 99, '苹果', 3.50, 1000);
3、创建数据源对象,jdbc模板对象jdbcTemplate
数据源对象需要数据库驱动,数据库的url,用户名,用户密码,所以我创建了一个配置文件jdbc.propertie。对应配置如下:
# 我的数据库信息
jdbc.driver= com.mysql.cj.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/fruitshop
jdbc.user_name = root
jdbc.password = 1234
<!-- 加载jdbc.properties-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!-- 数据源对象-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.user_name}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- jdbc模板对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
4、编写对应CRUD操作的DAO
DAO接口
public interface FruitDao {
int insertFruit(Fruit fruit);
int deleteFruitById(String id);
int updateFruit(Fruit fruit);
Fruit selectFruitById(String id);
List<Fruit> selectAllFruit();
}
DAO代码
使用JdbcTemplate模板对象之前先属性注入,才能使用里面的方法。使用JdbcTemplate比jdbc操作简单许多,基本上只用编写sql语句就行。增删改查都是用update方法,可以使用占位符,查询一条用queryForObject方法,查询多条用query。下面一一介绍增删改查对应方法:
增:
public int insertFruit(Fruit fruit) {
int i = jdbcTemplate.update("insert into fruits1 values (?,?,?,?,?)",
fruit.getF_id(), fruit.getS_id(), fruit.getF_name(), fruit.getF_price(), fruit.getQuantity());
return i;
}
删:
@Override
public int deleteFruitById(String id) {
int i = jdbcTemplate.update("delete from fruits1 where f_id = ?",id);
return i;
}
改:
@Override
public int updateFruit(Fruit fruit) {
String sql = "update fruits1 set " +
"s_id = "+ fruit.getS_id() +", " +
"f_name = '"+fruit.getF_name()+ "', " +
"f_price = "+fruit.getF_price()+" ," +
"quantity = "+fruit.getQuantity()+" " +
"where f_id = '"+fruit.getF_id()+"'";
int i =jdbcTemplate.update(sql);
return i;
}
查询一条:
@Override
public Fruit selectFruitById(String id) {
Fruit fruit = jdbcTemplate.queryForObject("select * from fruits1 where f_id = ?",new BeanPropertyRowMapper<Fruit>(Fruit.class),id);
return fruit;
}
查询所有:
@Override
public List<Fruit> selectAllFruit() {
List<Fruit> fruits = jdbcTemplate.query("select * from fruits1", new BeanPropertyRowMapper<Fruit>(Fruit.class));
return fruits;
}
现在dao层代码简单实现了。
二、service层
service层比较简单
接口:
public interface FruitService {
boolean insertFruit(Fruit fruit);
boolean deleteFruitById(String id);
boolean updateFruit(Fruit fruit);
Fruit selectFruitById(String id);
List<Fruit> selectAllFruit();
}
实现类:
@Service
public class FruitServiceImpl implements FruitService {
@Autowired
private FruitDaoImpl fruitDao;
@Override
public boolean insertFruit(Fruit fruit) {
if(fruitDao.insertFruit(fruit)>0){
return true;
}
return false;
}
@Override
public boolean deleteFruitById(String id) {
if (fruitDao.deleteFruitById(id)>0){
return true;
}
return false;
}
@Override
public boolean updateFruit(Fruit fruit) {
if(fruitDao.updateFruit(fruit)>0){
return true;
}
return false;
}
@Override
public Fruit selectFruitById(String id) {
return fruitDao.selectFruitById(id);
}
@Override
public List<Fruit> selectAllFruit() {
return fruitDao.selectAllFruit();
}
}
三 、restful实现Controller层
1、配置编码过滤器,前端控制器,HiddenHttpMethodFilter过滤器
<!-- 扩展配置方式-->
<servlet>
<servlet-name>rest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置spring配置文件的初始化名称和位置-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-rest.xml</param-value>
</init-param>
<!-- 将dispatcherServlet前端控制器初始化时间改为服务器启动时初始化-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 编码过滤器-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置处理请求方式为PUT和DELETE的HiddenHttpMethodFilter过滤器-->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2、配置spring的xml配置文件
这里把我的全部贴到下面,
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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">
<!-- 加载jdbc.properties-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!-- 组件扫描-->
<context:component-scan base-package="com.cx.fruit"></context:component-scan>
<!-- 数据源对象-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.user_name}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- jdbc模板对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- thymeleaf视图解析器-->
<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="order" value="1"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<!-- 视图前缀-->
<property name="prefix" value="/WEB-INF/templates/"/>
<!-- 视图后缀-->
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
</property>
</bean>
</property>
</bean>
<!-- 配置视图解析器-->
<mvc:view-controller path="/" view-name="index"></mvc:view-controller>
<mvc:view-controller path="/addfruit" view-name="addfruit"></mvc:view-controller>
<!-- 开放对静态资源的访问-->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
<!-- 开启mvc注解驱动-->
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
3、对数据库的操作
对数据库增删改restful都有对应的请求方式:增:POST,删:DELETE,改:PUT,查:GET。下面从易到难一一介绍各个操作
(1)查——GET
查询表里面的信息用的是GET方法,html默认的请求方式就是GET方法。
先写控制层方法:请求方式由于是get请求,可写可不写,由于查询到的结果需要响应到前端去,需要Model共享数据,当然还要其它方式也可以共享,可以根据你自己的想法。然后通过调用service层的selectAllFruit获取数据,在通过addAttribute方法将数据响应到前端,最后返回视图。
// 查看所有水果信息
@RequestMapping(value = "fruit" ,method = RequestMethod.GET)
// @RequestWrapper(value = "fruit")
public String selectAllFruit(Model model){
List<Fruit> fruits = fruitService.selectAllFruit();
model.addAttribute("fruits",fruits);
return "fruit-item";
}
对应表单,先不看删除和修改里面的内容。利用thymeleaf视图解析器循环遍历后端响应到前端的数据,在一一打印出来。
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>水果清单</title>
</head>
<body>
<table border="1" cellspacing="0" cellpadding="0" style="text-align: center">
<tr style="text-align: center">
<th colspan="6">
水果详情表(<a th:href="@{/addfruit}" >添加</a>)
</th>
</tr>
<tr style="text-align: center">
<th>水果ID</th>
<th>订单ID</th>
<th>水果名称</th>
<th>价格</th>
<th>订单数量</th>
<th>操作</th>
</tr>
<tr th:each="fruit :${fruits}">
<td th:text="${fruit.f_id}"></td>
<td th:text="${fruit.s_id}"></td>
<td th:text="${fruit.f_name}"></td>
<td th:text="${fruit.f_price}"></td>
<td th:text="${fruit.quantity}"></td>
<td>
<form th:action="@{'/fruit/'+${fruit.f_id}}" method="post">
<input type="hidden" name="_method" value="DELETE">
<input type="submit" value="删除">
</form>
<form th:action="@{'/fruit/'+${fruit.f_id}}" method="GET">
<input type="hidden" name="_method" value="GET">
<input type="submit" value="修改">
</form>
</td>
</tr>
</table>
</body>
</html>
结果如下:
(2)增——POST
增加用的请求方式是POST。增加信息没有什么可说的,和普通的servlet一样,先是从前端获取信息,然后通过执行sql语句操作数据库。
// 添加信息
@RequestMapping(value = "/fruit",method = RequestMethod.POST)
public String addFruit(Fruit fruit){
boolean b = fruitService.insertFruit(fruit);
if (b) {
return "redirect:/fruit";
}else {
return "redirect:/error";
}
}
(3)改——PUT
修改数据库信息restful用的请求方式是PUT。表单的method属性里面只有get和post,你要告诉后端你要用的是PUT和DELETE请求,就必须瞒住以下三个条件:
- 配置HiddenHttpMethodFilter过滤器,这个过滤器可以实现PUT和DELETE请求的对应操作。
- 提交表单里面必须是POST请求。
- 需要有一个属性名为“-method”,值为对应请求方式的请求参数。
下面先实现controller的代码,修改时我先通过id值找到对应属性的信息,回显到前端页面,在通过表单提交到后端。注意配置请求映射时方法为PUT
// 回显订单信息
@RequestMapping(value = "/fruit/{f_id}",method = RequestMethod.GET)
public String selectById(@PathVariable("f_id") String f_id,Model model){
Fruit fruit = fruitService.selectFruitById(f_id);
model.addAttribute("fruit",fruit);
return "updatefruit";
}
//
@RequestMapping(value = "fruit",method = RequestMethod.PUT)
public String uodateFruit(Fruit fruit){
boolean b = fruitService.updateFruit(fruit);
if (b) {
return "redirect:/fruit";
}else {
return "redirect:/error";
}
}
表单请求方式为POST,必须要有属性名为“-method”,值为“PUT”的请求参数。
(3)删——DELETE
删除处理方式和修改大致相同
// 根据id删除
@RequestMapping(value = "/fruit/{f_id}",method = RequestMethod.DELETE)
public String deleteFruitById(@PathVariable("f_id") String id){
boolean b = fruitService.deleteFruitById(id);
if (b) {
return "redirect:/fruit";
}else {
return "redirect:/error";
}
}
表单请求方式为POST,必须要有属性名为“-method”,值为“DELETE”的请求参数。