Spring MVC系列之JDBC Demo(SpringBoot)(七)
前言
前面我们了解了Spring MVC的基本使用,其实和.NET或.NET Core MVC无异,只是语法不同而已罢了,本节我们将和和数据库打交道,从最基础的JDBC讲解起,文中若有错误之处,还望指正。
JDBC Demo
我们需要下载三个包:JDBC驱动包(mysql-connector-java)、spring boot启用jdbc(spring-boot-starter-jdbc)、对数据进行序列化的json包(jackson-databind),如下:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
接下来我们在配置文件中,通过JDBC连接MySQL数据库,如下:
spring.datasource.url = jdbc:mysql://localhost:3306/user?serverTimezone=UTC
spring.datasource.username = root
spring.datasource.password = root
这里需要注意的是:对于不同的JDBC驱动版本,可能会抛出如下错误,这是由于在JDBC指定版本中存在的bug,所以要么如上显式指定serverTimezone,要么添加JDBC版本
The server time zone value '�й���ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver
(via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support
接下来我们定义对用户进行增、删、改、查的接口,如下:
public interface UserRepository {
    int save(User user);
    int update(User user);
    int deleteById(int id);
    List<User> findAll();
}
接下来我们再来看用户类,我们将对提交用户信息通过注解进行校验,同时我们对之前添加的爱好的数据类型为数组序列化为JSON后存到MySQL数据库,如下:
public class User {
    private ObjectMapper objectMapper = new ObjectMapper();
    public User() {
    }
    public User(int userId,
                String firstName,
                String lastName,
                String gender,
                String email,
                String userName,
                String password,
                String country,
                String favoritesJson) throws JsonProcessingException {
        this.userId = userId;
        this.firstName = firstName;
        this.lastName = lastName;
        this.gender = gender;
        this.email = email;
        this.userName = userName;
        this.password = password;
        this.country = country;
        this.favorites = objectMapper.readValue(favoritesJson, new TypeReference<String[]>() {
        });
    }
    private int userId;
    @NotNull(message = "名字必填")
    private String firstName;
    @NotNull(message = "姓氏必填")
    private String lastName;
    @NotNull(message = "性别必填")
    private String gender;
    @NotNull(message = "邮箱必填")
    @Email(message = "请输入有效的邮箱")
    private String email;
    @NotNull(message = "用户名必填")
    private String userName;
    @NotNull(message = "密码必填")
    private String password;
    private String country;
    public int getUserId() {
        return userId;
    }
    public String getFavoritesJson() {
        String favoritesJson = null;
        try {
            favoritesJson = objectMapper.writeValueAsString(this.favorites);
        } catch (JsonProcessingException ex) {
        }
        return favoritesJson;
    }
    public void setUserId(int userId) {
        this.userId = userId;
    }
    private String[] favorites;
    public String[] getFavorites() {
        return favorites;
    }
    public void setFavorites(String[] favorites) {
        this.favorites = favorites;
    }
    public String getCountry() {
        return country;
    }
    public void setCountry(String country) {
        this.country = country;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public String getGender() {
        return gender;
    }
    public void setGender(String gender) {
        this.gender = gender;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}
最后则是实现上述用户接口,这里我们使用JDBC中的参数化类(避免SQL注入)进行增删改查,如下:
@Repository
public class NamedParameterJdbcUserRepository implements UserRepository { @Autowired
public NamedParameterJdbcTemplate namedParameterJdbcTemplate; @Override
public int save(User user) {
MapSqlParameterSource mapSqlParameterSource = new MapSqlParameterSource();
mapSqlParameterSource.addValue("userName",user.getUserName());
mapSqlParameterSource.addValue("password",user.getPassword());
mapSqlParameterSource.addValue("firstName",user.getFirstName());
mapSqlParameterSource.addValue("lastName",user.getLastName());
mapSqlParameterSource.addValue("gender",user.getGender());
mapSqlParameterSource.addValue("email",user.getEmail());
mapSqlParameterSource.addValue("country",user.getCountry());
mapSqlParameterSource.addValue("favorites",user.getFavoritesJson()); return namedParameterJdbcTemplate.update(
"insert into users (userName, password,firstName,lastName,gender,email,country,favorites)" +
" values(:userName,:password,:firstName,:lastName,:gender,:email,:country,:favorites)",
mapSqlParameterSource);
} @Override
public int update(User user) {
return 0;
} @Override
public int deleteById(int id) {
MapSqlParameterSource mapSqlParameterSource = new MapSqlParameterSource();
mapSqlParameterSource.addValue("userId", id);
return namedParameterJdbcTemplate.update("delete from users where userId = :userId", mapSqlParameterSource);
} @Override
public List<User> findAll() {
return namedParameterJdbcTemplate.query(
"select * from users",
(rs, rowNum) ->
{
try {
return new User(
rs.getInt("userId"),
rs.getString("firstName"),
rs.getString("lastName"),
rs.getString("gender"),
rs.getString("email"),
rs.getString("userName"),
rs.getString("password"),
rs.getString("country"),
rs.getString("favorites")
);
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
});
}
}
然后在进行提交用户时,在上一节内容基础上进行改造,添加校验注解,若有错误则返回,否则提交成功后则跳转到用户列表,如下:
@RequestMapping(value = "/user", method = RequestMethod.POST)
public String user(@Valid @ModelAttribute("user") User user, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "user";
} else {
jdbcUserRepository.save(user);
return "users";
}
}
这里需要注意的是:对于空字符串即使添加了校验注解后依然会忽略,所以我们还需要初始化绑定器注解去除空字符串并对其进行校验,如下:
@InitBinder
public void initBinder(WebDataBinder dataBinder) { StringTrimmerEditor stringTrimmerEditor = new StringTrimmerEditor(true); dataBinder.registerCustomEditor(String.class, stringTrimmerEditor);
}
表单提交我们使用的是spring提供给我们的库,渲染用户列表,我们则是通过脚本并利用bootstrap-table实现,最终界面所呈现出的效果,如下:


总结
如上只是给出了部分重要代码,这里我已经将本节通过JDBC进行增删改查代码上传到github(https://github.com/wangpengxpy/SpringBoot),切换分支即可,后续会将每一块内容分别创建一个分支,以便供我复习和有需要的童鞋使用,本节我们到此结束,我们下节见。
Spring MVC系列之JDBC Demo(SpringBoot)(七)的更多相关文章
- 【Spring MVC系列】--(4)返回JSON
		
[Spring MVC系列]--(4)返回JSON 摘要:本文主要介绍如何在控制器中将数据生成JSON格式并返回 1.导入包 (1)spring mvc 3.0不需要任何其他配置,添加一个jackso ...
 - Spring mvc系列一之 Spring mvc简单配置
		
Spring mvc系列一之 Spring mvc简单配置-引用 Spring MVC做为SpringFrameWork的后续产品,Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块 ...
 - Spring MVC系列之模型绑定(SpringBoot)(七)
		
前言 上一节我们在SpringBoot中启用了Spring MVC最终输出了HelloWorld,本节我们来讲讲Spring MVC中的模型绑定,这个名称来源于.NET或.NET Core,不知是否恰 ...
 - Spring 框架系列之 JDBC 整合实例
		
微信公众号:compassblog 欢迎关注.转发,互相学习,共同进步! 有任何问题,请后台留言联系! 1.Spring框架整合 DAO 模板 JDBC:org.springframework.jdb ...
 - Spring Mvc + Maven + BlazeDS 与 Flex 通讯 (七)
		
BlazeDS 说明 BlazeDS是由Adobe开源的基于amf协议的,用于解决flex与java通讯的组件; 基于传统的文本协议的XML传输方式,在抽象层方面会有很大的压力,特别在需要序列化与反序 ...
 - 我看Spring MVC系列(一)
		
1.Spring MVC是什么: Spring MVC:Spring框架提供了构建Web应用程序的全功能MVC模块. 2.Spring helloWorld应用(基于Spring 4.2) 1.添加S ...
 - Spring MVC系列[2]——参数传递及重定向
		
1.目录结构 2.代码 <?xml version="1.0" encoding="UTF-8"?> <web-app version=&qu ...
 - Spring MVC系列-(1) Spring概述
		
1. Spring概述 本章主要介绍Spring中的体系结构和常见概念,比如bean.控制反转(Inverse of Control,IoC)等. 1.1 体系结构 Spring 框架提供约 20 个 ...
 - Spring  Mvc   上传文件Demo 实例
		
返得利购物. 淘宝.京东500家商城合作,包括全面的商城返利网.注冊就送5元,购物就有返利.随时提现. 同学们,新一轮的返利大潮正在慢慢靠近,让购物都认为自己在赚钱.购物,机票.游戏.酒店旅游,地方特 ...
 
随机推荐
- CBV 序列化
			
一.模型表 from django.db import models # Create your models here. class Publish(models.Model): name = mo ...
 - (转)GET来的漏洞
			
转自呆子不开口在wooyun知识库的文章 0x00 前言 这篇文章主要讲目前互联网上get方法被不规范使用带来的一些安全漏洞.其中重点会讲get请求在账号登陆体系中被滥用的场景和攻击方式. 0x01 ...
 - Python错误与异常
			
1 异常和错误 1.1 错误和异常 从软件方面来说,错误是语法或者逻辑上的,语法错误指示软件的结构上有错误,导致不能被解释器解释.当程序的语法正确后,剩下的就是逻辑错误了,逻辑错误可能是由于不完整或者 ...
 - Python通过win32 com接口实现offic自动化
			
最近几天通过Python做一些自动生成office报表的东东,比如解析.xml文件,导出.html/WORD/PPT等格式,html不足一提,只需要简单的html静态网页知识即可,这儿要说的是怎么生成 ...
 - 双指针,BFS和图论(二)
			
(一)BFS 1.地牢大师 你现在被困在一个三维地牢中,需要找到最快脱离的出路! 地牢由若干个单位立方体组成,其中部分不含岩石障碍可以直接通过,部分包含岩石障碍无法通过. 向北,向南,向东,向西,向上 ...
 - Jmeter使用—使用 HTTP代理服务器抓取接口
			
这里说一下怎么使用jmeter的HTTP代理服务器来抓取接口. 首先,打开jmeter,进入主页面,然后在对工作台(Jmeter版本4.0)点击右键->添加->非测试元件->HTTP ...
 - Linux系统实时数据同步inotify+rsync
			
一.inotify简介 inotify是Linux内核的一个功能,它能监控文件系统的变化,比如删除.读.写和卸载等操作.它监控到这些事件的发生后会默认往标准输出打印事件信息.要使用inotify,Li ...
 - 2020.2,《The day after tomorrow》
			
“The day after tomorrow, where will you be?” 2020春节冠状病毒肆虐被迫禁足家里,无意间打开了2004年由德国罗兰·艾默里奇(Roland Emmeric ...
 - 一文教你一次性完成Helm 3迁移
			
2019年,Kubernetes软件包管理器--Helm发布了最新版本Helm 3,并且该版本已经stable.Helm 3中的一些关键特性我们在之前的文章中已经介绍过,其中一些功能吸引了许多开发人员 ...
 - 微信小程序如何创建云函数并安装wx-server-sdk依赖
			
时间:2020/01/23 步骤 1.在微信开发者工具中云函数所在的文件夹的图标与其他文件夹是不同的,如下(第一个是云函数): 如果需要使一个普通文件变为云函数文件夹,需要在project.confi ...