SpringMVC4+thymeleaf3的一个简单实例(篇五:页面和MySql的数据交互-展示以及存储)
这一篇将介绍怎样把页面数据保存的MySQL数据库,并将数据库内容展示到页面上。
首先做一个基础工作,添加以下jar到lib:
1: mysql-connector-Java-5.1.40-bin.jar 下载 http://dev.mysql.com/downloads/connector/j/
2: spring-jdbc-4.3.3.RELEASE.jar
3: spring-tx-4.3.3.RELEASE.jar
2和3从spring framework发布包里面找。
继续沿用前面篇节的程序代码。我们开始吧!
一、创建数据库
打开ubuntu终端,输入命令: mysql -u root -p,提示输入用户root的密码后即可进入数据库,你也可用其它有创建数据库权限的用户进入:
创建名为test的schema(数据库):CREATE SCHEMA `test` DEFAULT CHARACTER SET utf8 ;
完成后进入test数据库:mysql> use test;
创建数据表:
CREATE TABLE `animals` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) DEFAULT NULL,
`count` int(11) DEFAULT NULL,
`memo` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
插入几条数据:
INSERT INTO animals(name, count, memo) VALUES('大马猴', 10, '散养');
INSERT INTO animals(name, count, memo) VALUES('小绵阳', 8, '圈养');
INSERT INTO animals(name, count, memo) VALUES('火星猿', 1, '圈养');
用select * from animals;看看结果:
大功告成!
以上所有操作也可通过MysqlWorkbench图形界面来操作完成,界面是这个样子:
二、在Spring中配置MySql数据库
添加以下代码到spring-mvc.xml文件
<context:component-scan base-package="com.zoo.dao"/>
<context:component-scan base-package="com.zoo.service"/>
<!-- 数据源配置 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
解释:
component-scan用于扫描dao包和service包以便让spring对有注解的组件进行配置,比如组件注册,绑定组件(用@Autowired标注的代码)等。
数据源让spring来管理,记得把password改成你自己的哦。重点说一下url属性,格式为 jdbc:mysql://host:port/database?prams,其中host是数据库所在服务器的ip或者名称;port为端口号,默认是3306;使用test数据库(我在我的数据库中创建了一个名叫test的库);问号后面是各种参数,本例设置了3个。
注意useUnicode和characterEncoding这两个参数,为了确保保存到数据库的字符不出现乱码,记得把它们设置成useUnicode=true&characterEncoding=UTF-8,否则很有可能在开发的时候碰到:页面传到后台程序的字符是正常的,但是保存到数据库就是乱码了。
另外细心的同学已经发现url的字符串里怎么会有”&“,这是因为”&“符号对xml来说是个特殊字符,如果不将其转义为"&",你会收到一个解析exception,类似这个:org.xml.sax.SAXParseException; lineNumber: 24; columnNumber: 95; 对实体 "characterEncoding" 的引用必须以 ';' 分隔符结尾?
三、添加几个java类
(1)新建三个包:com.zoo.service,com.zoo.service.impl,com.zoo.dao,com.zoo.entity
(2)在com.zoo.entity中添加类AnimalEntity.java,对应数据表内的一条数据,从数据库取出的数据会放在这个类的实例中
package com.zoo.entity; public class AnimalEntity { //数据库自动生成的id
private Long id; //动物名称
private String name; //动物数量
private Integer count; //备注
private String memo; //getters and setters
}
(3)在com.zoo.dao内添加AnimalDAO.java,dao用于操作数据表(增删改查等)
package com.zoo.dao; 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.stereotype.Service; import com.zoo.entity.AnimalEntity; @Repository
public class AnimalDAO { @Autowired
private JdbcTemplate jdbcTmplt; //从animals表检索出所有数据
public List<AnimalEntity> getAll() {
String sql = "SELECT id, name, count, memo FROM animals";
List<AnimalEntity> list = this.jdbcTmplt.query(sql, new BeanPropertyRowMapper<AnimalEntity>(AnimalEntity.class));
return list;
} //插入一条数据到animals表
public int insertOne(AnimalEntity entity){
int cnt = this.jdbcTmplt.update("INSERT INTO animals(name, count, memo) VALUES(?, ?, ?)",
entity.getName(), entity.getCount(), entity.getMemo());
return cnt;
}
}
解释:
@Service标注,还记得上面spring-mvc.xml中的context:component-scan么标签?它用于扫描指定包下(含子包)所有带@Component, @Service, @Controller以及@Repository的类,并将其注册到spring容器,以供其它代码使用。spring推荐将@Service用于业务逻辑层,@Controller用于控制层,@Repository用于持久化层。
@Autowired标注的字段,spring容器会自动从已经注册的组件中找到对应的component,并将其绑定。
注意:在getAll方法中我们用到了spring提供的一个非常实用的工具类:BeanPropertyRowMapper,它的作用就是将数据表里每条数据填充到指定类中,用了它好省心呀。注意指定类里的字段和数据表的字段名称要保持一致哦。
(4)在com.zoo.service里添加接口类AnimalService.java,controller会调用service层的方法
package com.zoo.service; import java.util.List; import com.zoo.entity.AnimalEntity; public interface AnimalService { public List<AnimalEntity> getAllAnimals(); public int insertOne(AnimalEntity entity);
}
(5)在com.zoo.service.impl中添加AnimalService的实现类AnimalServiceImpl.java:
package com.zoo.service.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import com.zoo.dao.AnimalDAO;
import com.zoo.entity.AnimalEntity;
import com.zoo.service.AnimalService; @Service
public class AnimalServiceImpl implements AnimalService { @Autowired
private AnimalDAO dao; @Override
public List<AnimalEntity> getAllAnimals() {
return dao.getAll();
} @Override
public int insertOne(AnimalEntity entity) {
return dao.insertOne(entity);
} }
(6)修改ZooController,定义AnimalService字段并将其标注为自动绑定@Autowired;修改showZooList方法,调用service取出数据库数据
@Autowired
private AnimalService service; @RequestMapping(path = "/list", method = RequestMethod.GET)
public ModelAndView showZooList(){
//从数据库取出数据
List<AnimalEntity> animals = service.getAllAnimals();
ModelAndView mav = new ModelAndView();
mav.setViewName("zoolist");
mav.addObject("animalForm", new AnimalForm());
mav.addObject("animalsList", animals);
return mav;
}
我们调用service的getAllAnimals方法,取得动物列表,并将这个list传递给页面用于展示。
(7)修改zoolist.html,由于我们在页面上一直用的是静态数据,现在有了数据库就可以用动态的了,但是需要修改代码以便显示list中的内容,只修改table那段
<table border="1">
<thead>
<tr>
<th>序号</th>
<th>动物名称</th>
<th>数量</th>
<th>备注</th>
</tr>
</thead>
<tbody th:remove="all-but-first">
<tr th:each="obj, objStat: ${animalsList}">
<td th:text="${objStat.count}">1</td>
<td th:text="${obj.name}">大马猴</td>
<td th:text="${obj.count}">10</td>
<td th:text="${obj.memo}">机灵古怪,俏皮活泼</td>
</tr>
<tr>
<td>2</td>
<td>大熊猫</td>
<td>80</td>
<td>体型笨重,喜欢吃竹子</td>
</tr>
<tr>
<td>3</td>
<td>澳洲羊驼</td>
<td>13</td>
<td>长相奇特,大国人俗称其草泥马</td>
</tr>
<tr>
<td>4</td>
<td>峨眉山猴</td>
<td>90</td>
<td>不怕人,有时候发贱抢游客面包吃</td>
</tr>
</tbody>
</table>
注意:我们在table里增加了thead和tbody标签,用于将table分成两部分;
在tbody标签中的th:remove="all-but-first",意思是只保留tbody中第一个子标签,其它子标签全都删掉,什么意思呢,让我们先看看tbody里的内容:它有4组tr标签,也就是有4条静态数据,当thymeleaf解析到这里的时候一看有个th:remove="all-but-first",好吧,它就会把第一组tr保留,剩下的三个给删掉,等下运行画面让你有个直观感受。
th:remove的5个备选值及其含义:
1. all:删除所在的标签以及所在标签的所有子节点
2. body:除所在标签外,删除所有所在标签的子节点
3. tag:删除所在标签,但保留所在标签的子节点
4. all-but-first:删除除所在标签第一个子节点外的所有其他子节点
5. none:不做任何事情,等同于不声明th:remove表达式
<tr th:each="obj, objStat: ${animalsList}">,里面的th:each表达式意思是把${animalList}变量进行迭代,以将list里的所有数据条目显示出来。注意前面的两个变量obj和objStat,obj表示list里面的具体实例,我们这里是AnimalEntity的实例;objStat是一个状态变量,表示迭代的当前状态,这个状态变量包含以下属性,代码中可直接使用:
index:当前迭代的index,从0开始
count:当前迭代的index,从1开始
size:迭代变量所含元素总数
current:表示当前迭代的元素,也就是某个AnimalEntity的实例
even/odd:布尔值,表示当前迭代是奇数还是偶数
first:布尔值,表示当前迭代是不是第一条记录
last:布尔值,表示当前迭代是不是最后一条记录
我们运行tomcat看看:
ok,一切正常,是我们想要的结果。
这个过程中你是否感受到了thymeleaf不同于其它template(比如jsp,freeMarker,volecity等)的地方?
thymeleaf同一个页面既可用于展示静态数据也可以用于运行动态数据。
如果把th:remove去掉会是怎样的效果呢:
嗯,聪明的你看懂了吧!有兴趣你还可以试一试th:remove其它的值。
ok,接下来我们制作最后一个步骤:插数据库。
四、保存数据到数据库
修改ZooCotroller,增加copyDataFromForm2Entity方法将form里的数据copy到entity中;
在doAdd方法中调用service的insertOne方法保存数据;
完整代码:
package com.zoo.web.controller; import java.util.List; import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView; import com.zoo.entity.AnimalEntity;
import com.zoo.service.AnimalService;
import com.zoo.web.form.AnimalForm; @Controller
public class ZooController { @Autowired
private AnimalService service; @RequestMapping(path = "/list", method = RequestMethod.GET)
public ModelAndView showZooList(){
//从数据库取出数据
List<AnimalEntity> animals = service.getAllAnimals();
ModelAndView mav = new ModelAndView();
mav.setViewName("zoolist");
mav.addObject("animalForm", new AnimalForm());
mav.addObject("animalsList", animals);
return mav;
} @RequestMapping(path = "/list", params = {"save"}, method = RequestMethod.POST)
public String doAdd(Model model, @Valid AnimalForm form, BindingResult result){
if(result.hasErrors()){
model.addAttribute("MSG", "出错啦!");
}else{
//保存数据到数据库
service.insertOne(this.copyDataFromForm2Entity(form));
model.addAttribute("MSG", "提交成功!");
}
//从数据库取出数据
List<AnimalEntity> animals = service.getAllAnimals();
model.addAttribute("animalsList", animals);
return "zoolist";
} //把form里的数据copy到entity中
private AnimalEntity copyDataFromForm2Entity(AnimalForm form){
AnimalEntity entity = new AnimalEntity();
entity.setName(form.getOname());
entity.setCount(Integer.valueOf(form.getOcount()));
entity.setMemo(form.getMemo());
return entity;
}
}
删除之前的system.out.print语句,在数据保存后,需要重新从数据库选出数据以刷新画面。
试一试吧!
嗯,这说明页面的数据已经保存到了数据库。聪明的你一定做出来了吧!
我们这个主题的实例小制作也就结束了,希望这些代码能让你对springMVC+thymeleaf+mysql有所了解,那我也就开心了!
末语:
在这个实例中,我仅简单的介绍了最基本的一些用法,希望能帮助到你们。本人水平有限,也只能写成这样了,如果哪里写错了请毫无保留的披头盖脸的向我指出来,在下必虚心改之!
springMVC和thymeleaf都是非常优秀的开源项目,而且相应的文档也很详细,如果大家遇到了问题,请先查阅文档以及API,应该会让你找到答案的。
END.
SpringMVC4+thymeleaf3的一个简单实例(篇五:页面和MySql的数据交互-展示以及存储)的更多相关文章
- SpringMVC4+thymeleaf3的一个简单实例(篇一:基本环境)
首语:用SpringMVC和thymeleaf实现一个简单的应用,包括基本环境搭建,SpringMVC4和thymeleaf3的整合,页面参数的获取,页面参数验证,以及用MySQL保存数据.我会把步骤 ...
- SpringMVC4+thymeleaf3的一个简单实例(篇二:springMVC与thymeleaf的整合)
延续前篇内容. 开始之前,我们首先要准备以下12个jar文件:spring-aop-4.3.3.RELEASE.jarspring-beans-4.3.3.RELEASE.jarspring-cont ...
- SpringMVC4+thymeleaf3的一个简单实例(篇三:页面参数获取)
本篇将通过示例介绍页面参数是如何传递到后台的.我们继续沿用之前搭好的程序结构,如果你不知道,请参照前两篇.为方便跳转页面,我们在首页以及zoolist.html页面都加上彼此地址的链接:首页: zoo ...
- SpringMVC4+thymeleaf3的一个简单实例(篇四:form表单数据验证)
关于表单数据验证有很多中方法,这里我仅介绍JSR303注解验证.JSR303仅仅是一个规范,这里我们要用到它的一个实现:hibernate-validator. 注意在spring的配置文件sprin ...
- C++ 容器的综合应用的一个简单实例——文本查询程序
C++ 容器的综合应用的一个简单实例——文本查询程序 [0. 需求] 最近在粗略学习<C++ Primer 4th>的容器内容,关联容器的章节末尾有个很不错的实例.通过实现一个简单的文本查 ...
- TERSUS无代码开发(笔记05)-简单实例电脑端页面设计
案例笔记电脑端页面设计 1.新建项目(请假管理qjgl) 2.开发软件界面介绍(常用的功能按键) 3.目录中显示元件对象 4.对元件对象的操作主要方式是双击(双击哪个元件, ...
- C#中缓存的使用 ajax请求基于restFul的WebApi(post、get、delete、put) 让 .NET 更方便的导入导出 Excel .net core api +swagger(一个简单的入门demo 使用codefirst+mysql) C# 位运算详解 c# 交错数组 c# 数组协变 C# 添加Excel表单控件(Form Controls) C#串口通信程序
C#中缓存的使用 缓存的概念及优缺点在这里就不多做介绍,主要介绍一下使用的方法. 1.在ASP.NET中页面缓存的使用方法简单,只需要在aspx页的顶部加上一句声明即可: <%@ Outp ...
- TERSUS无代码开发(笔记06)-简单实例手机端页面设计
手机端的设计 1.页面说明 2.默认页面===>提交请假单(上面页面双击进入,页面主要编辑区) 2.1默认页面===>提交请假单===>头部区(页面部份主要编辑区01) 2.1.1默 ...
- Ajax实现局部数据交互的一个简单实例
想要实现的功能:利用Ajax技术通过点击一个<button>按钮,然后在指定的文本框中输出想要的值. 1.使用Jsp创建一个前端页面. <body> <div style ...
随机推荐
- ResponseHelper
using System; using System.Collections.Generic; using System.Linq; using System.Web; using Cemetery_ ...
- 【转】unity3d 如何得到当前物体播放的动画
原文:http://blog.csdn.net/smilelance/article/details/22285125 public static string GetCurrentPlayingAn ...
- bzoj 1188 [HNOI2007]分裂游戏(SG函数,博弈)
1188: [HNOI2007]分裂游戏 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 733 Solved: 451[Submit][Status ...
- 更改mysql数据库latin1_swedish_ci为utf8
原文在http://bingu.net/472/latin1_swedish_ci-to-utf8_general_ci/把下列文件保存为一个.php文件,然后运行 <?phpdefine('D ...
- Codeforces 348A Mafia
题目链接:http://codeforces.com/problemset/problem/348/A 题目大意:N个人中找出1个人主持,剩下N-1个人参与游戏,给出每个人想参与游戏的次数,问要满足每 ...
- python 写的http后台弱口令爆破工具
今天来弄一个后台破解的Python小程序,哈哈,直接上代码吧,都有注释~~ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ...
- bzoj4447 SCOI2015 小凸解密码 password
传送门:bzoj4447 题解: 调试简直恶心,不过调完发现其实还是挺好写的. 用\(\mathrm{set}\)维护一段\(0\)区间的左右端点,每次最多修改两个点,所以很好维护. 查询的时候在\( ...
- 用Octopress在Github pages上写博客
安装Git环境 下载msysgit(git for windows),并安装. 可以选择安装TortoiseGit,这个在windows的资源管理器里装了很多git的右键菜单,对git命令行不熟悉的同 ...
- ArrayList and LinkedList
ArrayList and LinkedList List代表一种线性表的数据结构,ArrayList则是一种顺序存储的线性表.ArrayList底层采用数组来保存每个集合元素,LinkedList则 ...
- 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(4)-构建项目解决方案 创建EF DataBase Frist模式
原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(4)-构建项目解决方案 创建EF DataBase Frist模式 进行本次文章之前,我们可能需要补充一些 ...