這一篇將介紹怎樣把頁面數據保存的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.jarhtml
2和3從spring framework發佈包裏面找。
繼續沿用前面篇節的程序代碼。咱們開始吧!
1、建立數據庫
打開ubuntu終端,輸入命令: mysql -u root -p,提示輸入用戶root的密碼後便可進入數據庫,你也可用其它有建立數據庫權限的用戶進入:java
建立名爲test的schema(數據庫):CREATE SCHEMA `test` DEFAULT CHARACTER SET utf8 ;
完成後進入test數據庫:mysql> use test;
建立數據表:mysql
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;看看結果:web
大功告成!
以上全部操做也可經過MysqlWorkbench圖形界面來操做完成,界面是這個樣子:spring
2、在Spring中配置MySql數據庫
添加如下代碼到spring-mvc.xml文件sql
<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" 的引用必須以 ';' 分隔符結尾?
3、添加幾個java類
(1)新建三個包:com.zoo.service,com.zoo.service.impl,com.zoo.dao,com.zoo.entity
(2)在com.zoo.entity中添加類AnimalEntity.java,對應數據表內的一條數據,從數據庫取出的數據會放在這個類的實例中ubuntu
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用於操做數據表(增刪改查等)spring-mvc
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用於持久化層。tomcat
@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裏增長了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,接下來咱們製做最後一個步驟:插數據庫。
4、保存數據到數據庫
修改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.