zoukankan      html  css  js  c++  java
  • 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;
    创建数据表:

    1 CREATE TABLE `animals` (  
    2   `id` int(11) NOT NULL AUTO_INCREMENT,  
    3   `name` varchar(45) DEFAULT NULL,  
    4   `count` int(11) DEFAULT NULL,  
    5   `memo` varchar(45) DEFAULT NULL,  
    6   PRIMARY KEY (`id`),  
    7   UNIQUE KEY `id_UNIQUE` (`id`)  
    8 ) 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&amp;useUnicode=true&amp;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的字符串里怎么会有”&amp;“,这是因为”&“符号对xml来说是个特殊字符,如果不将其转义为"&amp;",你会收到一个解析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用于操作数据表(增删改查等)

     1     package com.zoo.dao;  
     2       
     3     import java.util.List;  
     4       
     5     import org.springframework.beans.factory.annotation.Autowired;  
     6     import org.springframework.jdbc.core.BeanPropertyRowMapper;  
     7     import org.springframework.jdbc.core.JdbcTemplate;  
     8     import org.springframework.stereotype.Service;  
     9       
    10     import com.zoo.entity.AnimalEntity;  
    11       
    12     @Repository  
    13     public class AnimalDAO {  
    14       
    15         @Autowired  
    16         private JdbcTemplate jdbcTmplt;  
    17           
    18         //从animals表检索出所有数据  
    19         public List<AnimalEntity> getAll() {  
    20             String sql = "SELECT id, name, count, memo FROM animals";  
    21             List<AnimalEntity> list = this.jdbcTmplt.query(sql, new BeanPropertyRowMapper<AnimalEntity>(AnimalEntity.class));  
    22             return list;  
    23         }  
    24           
    25         //插入一条数据到animals表  
    26         public int insertOne(AnimalEntity entity){  
    27             int cnt = this.jdbcTmplt.update("INSERT INTO animals(name, count, memo) VALUES(?, ?, ?)",   
    28                     entity.getName(), entity.getCount(), entity.getMemo());  
    29             return cnt;  
    30         }  
    31     }  

    解释:
    @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层的方法

     1     package com.zoo.service;  
     2       
     3     import java.util.List;  
     4       
     5     import com.zoo.entity.AnimalEntity;  
     6       
     7     public interface AnimalService {  
     8       
     9         public List<AnimalEntity> getAllAnimals();  
    10           
    11         public int insertOne(AnimalEntity entity);  
    12     }  

    (5)在com.zoo.service.impl中添加AnimalService的实现类AnimalServiceImpl.java:

     1     package com.zoo.service.impl;  
     2       
     3     import java.util.List;  
     4       
     5     import org.springframework.beans.factory.annotation.Autowired;  
     6     import org.springframework.stereotype.Service;  
     7       
     8     import com.zoo.dao.AnimalDAO;  
     9     import com.zoo.entity.AnimalEntity;  
    10     import com.zoo.service.AnimalService;  
    11       
    12     @Service  
    13     public class AnimalServiceImpl implements AnimalService {  
    14           
    15         @Autowired  
    16         private AnimalDAO dao;  
    17       
    18         @Override  
    19         public List<AnimalEntity> getAllAnimals() {  
    20             return dao.getAll();  
    21         }  
    22       
    23         @Override  
    24         public int insertOne(AnimalEntity entity) {  
    25             return dao.insertOne(entity);  
    26         }  
    27       
    28     }  

    (6)修改ZooController,定义AnimalService字段并将其标注为自动绑定@Autowired;修改showZooList方法,调用service取出数据库数据

     1     @Autowired  
     2     private AnimalService service;  
     3       
     4     @RequestMapping(path = "/list", method = RequestMethod.GET)  
     5     public ModelAndView showZooList(){  
     6         //从数据库取出数据  
     7         List<AnimalEntity> animals = service.getAllAnimals();  
     8         ModelAndView mav = new ModelAndView();  
     9         mav.setViewName("zoolist");  
    10         mav.addObject("animalForm", new AnimalForm());  
    11         mav.addObject("animalsList", animals);  
    12         return mav;  
    13     }  

    我们调用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里增加了theadtbody标签,用于将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方法保存数据;
    完整代码:

     1 package com.zoo.web.controller;
     2 
     3 import java.util.List;
     4 
     5 import javax.validation.Valid;
     6 
     7 import org.springframework.beans.factory.annotation.Autowired;
     8 import org.springframework.stereotype.Controller;
     9 import org.springframework.ui.Model;
    10 import org.springframework.validation.BindingResult;
    11 import org.springframework.web.bind.annotation.RequestMapping;
    12 import org.springframework.web.bind.annotation.RequestMethod;
    13 import org.springframework.web.servlet.ModelAndView;
    14 
    15 import com.zoo.entity.AnimalEntity;
    16 import com.zoo.service.AnimalService;
    17 import com.zoo.web.form.AnimalForm;
    18 
    19 @Controller
    20 public class ZooController {
    21 
    22     @Autowired
    23     private AnimalService service;
    24     
    25     @RequestMapping(path = "/list", method = RequestMethod.GET)
    26     public ModelAndView showZooList(){
    27         //从数据库取出数据
    28         List<AnimalEntity> animals = service.getAllAnimals();
    29         ModelAndView mav = new ModelAndView();
    30         mav.setViewName("zoolist");
    31         mav.addObject("animalForm", new AnimalForm());
    32         mav.addObject("animalsList", animals);
    33         return mav;
    34     }
    35     
    36     @RequestMapping(path = "/list", params = {"save"}, method = RequestMethod.POST)
    37     public String doAdd(Model model, @Valid AnimalForm form, BindingResult result){
    38         if(result.hasErrors()){
    39             model.addAttribute("MSG", "出错啦!");
    40         }else{
    41             //保存数据到数据库
    42             service.insertOne(this.copyDataFromForm2Entity(form));
    43             model.addAttribute("MSG", "提交成功!");
    44         }
    45         //从数据库取出数据
    46         List<AnimalEntity> animals = service.getAllAnimals();
    47         model.addAttribute("animalsList", animals);
    48         return "zoolist";
    49     }
    50     
    51     //把form里的数据copy到entity中
    52     private AnimalEntity copyDataFromForm2Entity(AnimalForm form){
    53         AnimalEntity entity = new AnimalEntity();
    54         entity.setName(form.getOname());
    55         entity.setCount(Integer.valueOf(form.getOcount()));
    56         entity.setMemo(form.getMemo());
    57         return entity;
    58     }
    59 }

    删除之前的system.out.print语句,在数据保存后,需要重新从数据库选出数据以刷新画面。

    试一试吧!

    嗯,这说明页面的数据已经保存到了数据库。聪明的你一定做出来了吧!

    我们这个主题的实例小制作也就结束了,希望这些代码能让你对springMVC+thymeleaf+mysql有所了解,那我也就开心了!

    末语:
    在这个实例中,我仅简单的介绍了最基本的一些用法,希望能帮助到你们。本人水平有限,也只能写成这样了,如果哪里写错了请毫无保留的披头盖脸的向我指出来,在下必虚心改之!

    springMVC和thymeleaf都是非常优秀的开源项目,而且相应的文档也很详细,如果大家遇到了问题,请先查阅文档以及API,应该会让你找到答案的。

    END.

    ---------------------------------------------------
    如果这些内容能给读者带来帮助,那将是莫大欢喜。
    ---------------------------------------------------
  • 相关阅读:
    (转)UIMenuController的使用,对UILabel拷贝以及定制菜单
    (转)ios多线程开发——NSOperation详解
    IOS custom statusBar 思路
    objectiveC的@property(atomic, retain)对引用计数的影响
    A Generic Particle IO Library
    RenderMan与CG生产流程简述
    Maya Mesh Relaxation Deformer
    个人黄金市场交易记录/Personal Gold Market Operation Record
    Implementation of TLRW ReadWrite Lock
    给想雇佣我的人说的话/Some words to somebody who want to hire me.
  • 原文地址:https://www.cnblogs.com/asdop/p/6094137.html
Copyright © 2011-2022 走看看