SpringJDBC+RESTFUL实现对数据库的增删改查

一、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请求,就必须瞒住以下三个条件:

  1. 配置HiddenHttpMethodFilter过滤器,这个过滤器可以实现PUT和DELETE请求的对应操作。
  2. 提交表单里面必须是POST请求。
  3. 需要有一个属性名为“-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”的请求参数。
在这里插入图片描述

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我没得冰阔落.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值