距離上一次開發SpringMVC項目已經過去了大半年,有些細節已經開始遺忘,今天復習一下
先從標簽說起:
和struts有各種配置文件不同,spring用標簽開發。
1.@Controller
在SpringMVC中,控制器Controller負責處理由DispatcherServlet分發的請求
他把用戶請求的數據經過業務處理層處理之后封裝成一個model,然后再把該model
返回給對應的view進行展示。在SpringMVC中提供一個非常簡便的定義Controller
的方法,你無需繼承特定的類或實現特定的接口,
只需要使用@Controller標記一個類是controller,然后使用@RequestMapping,@RequestParam
等一些注解用以定義URL請求和Controller方法之間的映射,這樣Controller就能被外界訪問到
此外,Controller不會直接依賴於 HttpServletRequest 和 HttpServlet對象,他們可以通過Controller的 方法參數靈活的獲取到。
@Controller用於標記一個類上,使用他標記的類就是一個Spring'MVC Controller對象
分發處理器將會掃描用了該注解的類的方法,並檢測該方法是否使用了@RequestMapping注解
@Controller只是定義了一個控制器類,而使用@RequestMapping注解的方法才是真正處理請求的
處理器,單單使用@Controller標記在一個類上還不能真正意義上說他就是SpringMVC的一個控制類
因為這個時候Spring還不認識他,那么要如何做Spring才能認識她呢?
這個時候就需要我們把這個控制器類交給Spring來管理,有兩種方式
(1)在SpringMVC配置文件中定義MyController的bean對象
(2)在SpringMVC配置文件中告訴Spring該到哪里去找標記為@Controller的Controller控制器
<!--方式一-->
<bean class="com.host.app.web.controller.MyController"/>
<!--方式二-->
<context:component-scan base-package="com.host.app.web">
//路徑寫到controller的上一層(掃描包詳見下面解析)
2.@RequestMapping
RequestMapping是一個用來處理請求地址映射的注解,可用於類和方法上。
用於子類上表示類中的所有響應請求的方法都是以該地址作為父路徑
RequestMapping注解有六個屬性,下面我們把他分成三類進行說明(下面有相應實例)
1.value,method
value:指定請求的實際地址,指定的地址可以是URL Temple模式(后面將會說明)
method:指定請求的method類型,GET,POST,PUT,DELETE等
@RequestMapping(value="",method={"",""},header={},param={"",""})
參數:
value:設置訪問地址
method:設置訪問方式,常用的method=RequestMethod.POST和
method=RequestMethod.GET
headers:頭域,可以設置瀏覽器支持的格式
params:訪問參數設置
注解作用:
用來定義訪問url,可以是方法級別的,也可以是類級別的,兩者可以協同工作,縮小選擇范圍
也可以隱藏代碼的真實路徑,更加具有安全性和可讀性
3.@Autowired
注解作用:
可以對成員變量,方法和構造函數進行標注,來完成自動裝配工作,可以消除get/set方法
action里get/set注入
5.@PathVariable
用於將請求URL中的模板變量映射到功能處理方法的參數上,即將取出url模板中的變量作為參數
@PathVariable
注解作用:
用於方法中的參數,表示方法參數綁定到地址URL的模板
6.@RequestParam
@RequestParam主要用於在SpringMVC后台控制層獲取參數,
類似一種是request.getParameter("name"),他有三個常用參數,
defaultValue="0" ; required=false , value="isApp" ; defaultValue表示設置默認值,
required通過boolean設置是否必須要傳入的參數,value值表示接受的傳入的參數類型
@RequestParam(required= , value="",defaultValue="")
參數:
required:參數是否必須,boolean類型:默認為true
value:傳遞的參數名稱。String類型,可選項,有值則對應方法的參數
defaultValue:參數沒有傳遞時為參數默認指定的值
7.@ResponseBody
作用:該注解用於將Controller的方法返回的對象,通過適當的HttpMessageConverter
轉換為適當格式后,寫入到Response對象的body數據區
使用時機:返回的數據不是html標簽的頁面,而是其他某種格式的數據時(如json,xml等)、
8.@ResponseBody注解作用:
直接放在方法上,表示返回類型將會直接作為http響應字節流輸出,可以用於Ajax
9.@Service-表示業務處理層(一般在serviceImpl)
說明:@Service負責注冊一個bean到spring上下文中,bean的ID默認為類名稱開頭字母小寫
10.@Transactional
事務管理模式
spring支持編程式事務管理和聲明式事務管理兩種方式
編程式事務管理使用TransactionTemplate或者直接使用底層的PlatformTransactionManager
對於編程式事務管理,spring推薦使用TransactionTemple
聲明式事務管理建立在AOP之上,,其本質是對方法前后進行攔截,然后在目標方法開始之前創建或者加入一個事物,在執行完目標方法之后根據執行情況提交或者回滾事務。聲明式事務最大的優點是不需要通過編程的方式管理事務,這樣就不需要在業務邏輯代碼中摻雜事務管理的代碼,只需要在配置文件中做相關的事務規則聲明(或通過基於@Transaction注解的方式),便可以將事務規則應用到業務邏輯中。
顯然聲明式事務管理要優於編程式事務管理,這正式spring倡導的非侵入式的開發方式,聲明式事務管理使業務代碼不受到污染,一個普通的POJO對象,只要加上注解就可以獲得完全的事務支持。和編程式事務相比,聲明式事務3唯一不足的地方是后者最細粒度只能作用到方法級別,無法做到編程式事務那樣可以做到代碼塊級別,但是即便有這樣的需求,也存在很多變通的方法如可以將需要進行事務管理的代碼塊獨立為方法等等
聲明式事務管理也有兩種常用的方式,一種是基於tx和aop名字空間的xml配置文件,另一種就是基於@Transactional注解,顯然基於注解的方式更簡單易用,更清爽
TransactionDefinition.PROPAGATION_REQUIRED:如果當前存在事務,則加入該事事務,如果當前沒有事務,則創建一個新的事務,這是默認值。
TransactionDefinition.PROPAGATION_REQUIRES_NEW:創建一個新的事務,如果當前存在事務,則把當前事務掛起
TransactionDefinition.PROPAGATION_SUPPORTS:如果當前存在事務,則加入該事務,如果沒有則以非事務的方式繼續運行
TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事務方式運行,如果當前存在事務,把當前事務掛起
TransactionDefinition.PROPAGATION_NEVER:以非事務方式運行,如果存在當前事務,則拋出異常
TransactionDefinition.PROPAGATION_MANDATORY:如果當前存在事務,則加入該事事務,沒有事務則拋出異常
TransactionDefinition.PROPAGATION_NESTED如果當前存在事務,則創建一個事務作為當前事務的嵌套事務來運行,
如果當前沒有事務,則該取值等價於TransactionDefinition.PROPAGATION_REQUIRED
屬性:
Propagation可選的事務傳播行為設置
ReadOnly:讀寫或只讀事務,默認讀寫(boolean)
readOnly=true 只讀,不能更新,刪除
//設置超時時間
@Transactional(propagation=Propagation.REQUIRED,timeout=30)
注:
@Transactional注解應該只被應用到public方法上,這是由SpringAOP的本質決定的,
如果你在protected,private或者默認可見性的方法上使用@Transactional注解將被忽略
也不會拋出任何異常
在Service類前加上@Transactional,聲明這個service所有方法需要事務管理
每一個業務方法開始時都會打開一個事務
11.@SelectProvider
@SelectProvider注解用於生成查詢用的sql語句,有別於@Select注解,@SelectProvider指定一個Class及其方法,並且通過調用Class上的這個方法來獲得sql語句,在我們這個例子中,獲取查詢sql方法是SqlProvider selectUser
@SelectProvider中type參數指定的class類,必須要能夠通過無參數的構造函數來初始化,
@SelectProvider中method參數指定的方法必須是public的,返回值必須為String,可以為static
注:如果在getUser方法中,對userId方法使用了@Param注解,那么相應selectUser方法必須
接受Map<String,Object>作為參數
如果參數使用了@Param注解,那么參數在Map中以@Param的值為key
ps:很多人(包括我)在剛開始開發spring時,對那些xxxAction.class都報有一絲敬畏之心,但實際上,只有你在這個class里添加了@Controller標簽,他才會成為真正意義上的action,可以控制頁面跳轉和與前台交互數據,接下來放一一個登錄demo的栗子幫助理解springMV西
action:登錄功能代碼丟了,這個我日后補上
然后!controller 和 jsp 的地址一定要能對上,controller要記得初始化你想要跳轉到頁面(就像下面的22~24行、52~55行),否則會出現空頁面情況
1 package com.javen.modules.Test.web; 2 3 import java.util.List; 4 import java.util.Map; 5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.stereotype.Controller; 7 import org.springframework.ui.Model; 8 import org.springframework.web.bind.annotation.RequestMapping; 9 import org.springframework.web.bind.annotation.RequestParam; 10 import com.javen.common.controller.BaseController; 11 import com.javen.common.utils.MessageUtils; 12 import com.javen.modules.Test.dao.model.Table; 13 import com.javen.modules.Test.service.TestService; 14 15 @Controller 16 @RequestMapping("/wf/test") 17 public class TestController extends BaseController{ 18 19 @Autowired 20 private TestService service; 21 22 @RequestMapping("") 23 public String log(){ 24 return "test/testLog"; 25 } 26 27 @RequestMapping("/list") 28 public String list(Model model, 29 @RequestParam(value="name",required=false,defaultValue="") String name, 30 @RequestParam(value="sex",required=false,defaultValue="") String sex, 31 @RequestParam(value="cp", required=false, defaultValue="1") int currPage){ 32 List<Map<String,String>> list = service.getList(name, sex, currPage,2); 33 int cnt =service.getCnt(name,sex); 34 model.addAttribute("cnt",cnt); 35 if(cnt < 1){ 36 alertInfo(MessageUtils.getMessage("INF0003", "鎶辨瓑錛岃閲嶆柊杈撳叆"), model); 37 }else { 38 if("".equals(sex)){ 39 sex = "3"; 40 model.addAttribute("sex", sex); 41 } 42 model.addAttribute("offset", (currPage-1)*2); 43 model.addAttribute("currPage", currPage); 44 model.addAttribute("name", name); 45 model.addAttribute("list", list); 46 } 47 48 return "test/testList"; 49 50 } 51 52 @RequestMapping("/add") 53 public String add(){ 54 55 return "test/testAdd"; 56 } 57 58 @RequestMapping(value = "/add/exec") 59 public String a (Table table,Model model){ 60 int b = service.get(table); 61 if(b > 0){ 62 alertError(MessageUtils.getMessage("ERR0016", "閲嶅"), model); 63 return "forward:/wf/test/add"; 64 } 65 table.setDegree("紜曞+"); 66 table.setGradUni("鍝堝皵婊ㄧ悊宸ュぇ瀛�"); 67 table.setMail("1225165@qq.com"); 68 table.setTelNumber("13055465421"); 69 70 boolean add = service.addTable(table); 71 if (add) { 72 alertSuccess(MessageUtils.getMessage("INF0001", "鎴愬姛"), model); 73 alertSucc(model, 2); 74 } else { 75 alertError(MessageUtils.getMessage("ERR0016", "澶辮觸"), model); 76 77 } 78 79 80 return "forward:/wf/test/add"; 81 82 83 } 84 }
亂碼是我把文件亂保存出現了解碼錯誤吧,都是些自己設定的報錯或者提示信息,不影響功能
service:
package com.javen.modules.Test.service; import java.util.List; import java.util.Map; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.javen.common.service.BaseService; import com.javen.modules.Test.dao.mapper.TableMapper; import com.javen.modules.Test.dao.model.Table; import com.javen.modules.Test.dao.model.TableExample; import com.javen.modules.Test.dao.model.TableExample.Criteria; @Service @Transactional(readOnly=true) public class TestService extends BaseService{ @Transactional(propagation = Propagation.SUPPORTS) public int getCnt(String name ,String sex){ TableMapper mapper = readonlySQLSession.getMapper(TableMapper.class); TableExample example = new TableExample(); Criteria criteria = example.createCriteria(); if(!"".equals(name)){ criteria.andNameLike(name); }if(!"".equals(sex)){ criteria.andSexEqualTo(sex); } return mapper.countByExample(example); } @Transactional(propagation=Propagation.SUPPORTS) public List<Map<String, String>> getList(String name, String sex, int currPage, int size) { TableMapper mapper = readonlySQLSession.getMapper(TableMapper.class); int offset=(currPage-1)*size; return mapper.getList(name,sex,offset,size); } @Transactional(propagation=Propagation.SUPPORTS) public int get(Table table) { TableMapper mapper = readonlySQLSession.getMapper(TableMapper.class); return mapper.getmapper(table); } @Transactional(propagation=Propagation.SUPPORTS) public boolean addTable(Table table) { TableMapper mapper = writableSQLSession.getMapper(TableMapper.class); return mapper.insertSelective(table)>0; } }
連db部分是自動生成的文件,這里我挑有用的復制了
1 package com.javen.modules.Test.dao.mapper; 2 3 import com.javen.modules.Test.dao.model.Table; 4 import com.javen.modules.Test.dao.model.TableExample; 5 6 import java.util.List; 7 import java.util.Map; 8 9 import org.apache.ibatis.annotations.Delete; 10 import org.apache.ibatis.annotations.DeleteProvider; 11 import org.apache.ibatis.annotations.Insert; 12 import org.apache.ibatis.annotations.InsertProvider; 13 import org.apache.ibatis.annotations.Param; 14 import org.apache.ibatis.annotations.Result; 15 import org.apache.ibatis.annotations.Results; 16 import org.apache.ibatis.annotations.Select; 17 import org.apache.ibatis.annotations.SelectProvider; 18 import org.apache.ibatis.annotations.Update; 19 import org.apache.ibatis.annotations.UpdateProvider; 20 import org.apache.ibatis.type.JdbcType; 21 22 public interface TableMapper { 23 @SelectProvider(type=TableSqlProvider.class, method="countByExample") 24 int countByExample(TableExample example); 25 26 @DeleteProvider(type=TableSqlProvider.class, method="deleteByExample") 27 int deleteByExample(TableExample example); 28 29 @Delete({ 30 "delete from table", 31 "where id = #{id,jdbcType=INTEGER}" 32 }) 33 int deleteByPrimaryKey(Integer id); 34 35 @Insert({ 36 "insert into table (id, name, ", 37 "tel_number, degree, ", 38 "sex, grad_uni, mail, ", 39 "password)", 40 "values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, ", 41 "#{telNumber,jdbcType=VARCHAR}, #{degree,jdbcType=VARCHAR}, ", 42 "#{sex,jdbcType=CHAR}, #{gradUni,jdbcType=VARCHAR}, #{mail,jdbcType=VARCHAR}, ", 43 "#{password,jdbcType=VARCHAR})" 44 }) 45 int insert(Table record); 46 47 @InsertProvider(type=TableSqlProvider.class, method="insertSelective") 48 int insertSelective(Table record); 49 50 @SelectProvider(type=TableSqlProvider.class, method="selectByExample") 51 @Results({ 52 @Result(column="id", property="id", jdbcType=JdbcType.INTEGER, id=true), 53 @Result(column="name", property="name", jdbcType=JdbcType.VARCHAR), 54 @Result(column="tel_number", property="telNumber", jdbcType=JdbcType.VARCHAR), 55 @Result(column="degree", property="degree", jdbcType=JdbcType.VARCHAR), 56 @Result(column="sex", property="sex", jdbcType=JdbcType.CHAR), 57 @Result(column="grad_uni", property="gradUni", jdbcType=JdbcType.VARCHAR), 58 @Result(column="mail", property="mail", jdbcType=JdbcType.VARCHAR), 59 @Result(column="password", property="password", jdbcType=JdbcType.VARCHAR) 60 }) 61 List<Table> selectByExample(TableExample example); 62 63 @Select({ 64 "select", 65 "id, name, tel_number, degree, sex, grad_uni, mail, password", 66 "from table", 67 "where id = #{id,jdbcType=INTEGER}" 68 }) 69 @Results({ 70 @Result(column="id", property="id", jdbcType=JdbcType.INTEGER, id=true), 71 @Result(column="name", property="name", jdbcType=JdbcType.VARCHAR), 72 @Result(column="tel_number", property="telNumber", jdbcType=JdbcType.VARCHAR), 73 @Result(column="degree", property="degree", jdbcType=JdbcType.VARCHAR), 74 @Result(column="sex", property="sex", jdbcType=JdbcType.CHAR), 75 @Result(column="grad_uni", property="gradUni", jdbcType=JdbcType.VARCHAR), 76 @Result(column="mail", property="mail", jdbcType=JdbcType.VARCHAR), 77 @Result(column="password", property="password", jdbcType=JdbcType.VARCHAR) 78 }) 79 Table selectByPrimaryKey(Integer id); 80 81 @UpdateProvider(type=TableSqlProvider.class, method="updateByExampleSelective") 82 int updateByExampleSelective(@Param("record") Table record, @Param("example") TableExample example); 83 84 @UpdateProvider(type=TableSqlProvider.class, method="updateByExample") 85 int updateByExample(@Param("record") Table record, @Param("example") TableExample example); 86 87 @UpdateProvider(type=TableSqlProvider.class, method="updateByPrimaryKeySelective") 88 int updateByPrimaryKeySelective(Table record); 89 90 @Update({ 91 "update table", 92 "set name = #{name,jdbcType=VARCHAR},", 93 "tel_number = #{telNumber,jdbcType=VARCHAR},", 94 "degree = #{degree,jdbcType=VARCHAR},", 95 "sex = #{sex,jdbcType=CHAR},", 96 "grad_uni = #{gradUni,jdbcType=VARCHAR},", 97 "mail = #{mail,jdbcType=VARCHAR},", 98 "password = #{password,jdbcType=VARCHAR}", 99 "where id = #{id,jdbcType=INTEGER}" 100 }) 101 int updateByPrimaryKey(Table record); 102 103 104 105 @SelectProvider(type=TableSqlProvider.class, method="getCntsql") 106 int getCnt(String name, String sex); 107 108 @SelectProvider(type=TableSqlProvider.class, method="getListsql") 109 List<Map<String, String>> getList( 110 @Param("name") String name, 111 @Param("sex") String sex, 112 @Param("offset") int offset, 113 @Param("size") int size); 114 115 116 @SelectProvider(type=TableSqlProvider.class, method="getmappersql") 117 int getmapper(Table table); 118 }
還有
1 package com.javen.modules.Test.dao.mapper; 2 3 import static org.apache.ibatis.jdbc.SqlBuilder.BEGIN; 4 import static org.apache.ibatis.jdbc.SqlBuilder.DELETE_FROM; 5 import static org.apache.ibatis.jdbc.SqlBuilder.FROM; 6 import static org.apache.ibatis.jdbc.SqlBuilder.INSERT_INTO; 7 import static org.apache.ibatis.jdbc.SqlBuilder.ORDER_BY; 8 import static org.apache.ibatis.jdbc.SqlBuilder.SELECT; 9 import static org.apache.ibatis.jdbc.SqlBuilder.SELECT_DISTINCT; 10 import static org.apache.ibatis.jdbc.SqlBuilder.SET; 11 import static org.apache.ibatis.jdbc.SqlBuilder.SQL; 12 import static org.apache.ibatis.jdbc.SqlBuilder.UPDATE; 13 import static org.apache.ibatis.jdbc.SqlBuilder.VALUES; 14 import static org.apache.ibatis.jdbc.SqlBuilder.WHERE; 15 16 import com.javen.modules.Test.dao.model.Table; 17 import com.javen.modules.Test.dao.model.TableExample.Criteria; 18 import com.javen.modules.Test.dao.model.TableExample.Criterion; 19 import com.javen.modules.Test.dao.model.TableExample; 20 21 import java.util.List; 22 import java.util.Map; 23 24 import org.springframework.util.StringUtils; 25 26 public class TableSqlProvider { 27 28 public String countByExample(TableExample example) { 29 BEGIN(); 30 SELECT("count(*)"); 31 FROM("table"); 32 applyWhere(example, false); 33 return SQL(); 34 } 35 36 public String deleteByExample(TableExample example) { 37 BEGIN(); 38 DELETE_FROM("table"); 39 applyWhere(example, false); 40 return SQL(); 41 } 42 43 public String insertSelective(Table record) { 44 BEGIN(); 45 INSERT_INTO("table"); 46 47 if (record.getId() != null) { 48 VALUES("id", "#{id,jdbcType=INTEGER}"); 49 } 50 51 if (record.getName() != null) { 52 VALUES("name", "#{name,jdbcType=VARCHAR}"); 53 } 54 55 if (record.getTelNumber() != null) { 56 VALUES("tel_number", "#{telNumber,jdbcType=VARCHAR}"); 57 } 58 59 if (record.getDegree() != null) { 60 VALUES("degree", "#{degree,jdbcType=VARCHAR}"); 61 } 62 63 if (record.getSex() != null) { 64 VALUES("sex", "#{sex,jdbcType=CHAR}"); 65 } 66 67 if (record.getGradUni() != null) { 68 VALUES("grad_uni", "#{gradUni,jdbcType=VARCHAR}"); 69 } 70 71 if (record.getMail() != null) { 72 VALUES("mail", "#{mail,jdbcType=VARCHAR}"); 73 } 74 75 if (record.getPassword() != null) { 76 VALUES("password", "#{password,jdbcType=VARCHAR}"); 77 } 78 79 return SQL(); 80 } 81 82 public String selectByExample(TableExample example) { 83 BEGIN(); 84 if (example != null && example.isDistinct()) { 85 SELECT_DISTINCT("id"); 86 } else { 87 SELECT("id"); 88 } 89 SELECT("name"); 90 SELECT("tel_number"); 91 SELECT("degree"); 92 SELECT("sex"); 93 SELECT("grad_uni"); 94 SELECT("mail"); 95 SELECT("password"); 96 FROM("table"); 97 applyWhere(example, false); 98 99 if (example != null && example.getOrderByClause() != null) { 100 ORDER_BY(example.getOrderByClause()); 101 } 102 103 return SQL(); 104 } 105 106 public String updateByExampleSelective(Map<String, Object> parameter) { 107 Table record = (Table) parameter.get("record"); 108 TableExample example = (TableExample) parameter.get("example"); 109 110 BEGIN(); 111 UPDATE("table"); 112 113 if (record.getId() != null) { 114 SET("id = #{record.id,jdbcType=INTEGER}"); 115 } 116 117 if (record.getName() != null) { 118 SET("name = #{record.name,jdbcType=VARCHAR}"); 119 } 120 121 if (record.getTelNumber() != null) { 122 SET("tel_number = #{record.telNumber,jdbcType=VARCHAR}"); 123 } 124 125 if (record.getDegree() != null) { 126 SET("degree = #{record.degree,jdbcType=VARCHAR}"); 127 } 128 129 if (record.getSex() != null) { 130 SET("sex = #{record.sex,jdbcType=CHAR}"); 131 } 132 133 if (record.getGradUni() != null) { 134 SET("grad_uni = #{record.gradUni,jdbcType=VARCHAR}"); 135 } 136 137 if (record.getMail() != null) { 138 SET("mail = #{record.mail,jdbcType=VARCHAR}"); 139 } 140 141 if (record.getPassword() != null) { 142 SET("password = #{record.password,jdbcType=VARCHAR}"); 143 } 144 145 applyWhere(example, true); 146 return SQL(); 147 } 148 149 public String updateByExample(Map<String, Object> parameter) { 150 BEGIN(); 151 UPDATE("table"); 152 153 SET("id = #{record.id,jdbcType=INTEGER}"); 154 SET("name = #{record.name,jdbcType=VARCHAR}"); 155 SET("tel_number = #{record.telNumber,jdbcType=VARCHAR}"); 156 SET("degree = #{record.degree,jdbcType=VARCHAR}"); 157 SET("sex = #{record.sex,jdbcType=CHAR}"); 158 SET("grad_uni = #{record.gradUni,jdbcType=VARCHAR}"); 159 SET("mail = #{record.mail,jdbcType=VARCHAR}"); 160 SET("password = #{record.password,jdbcType=VARCHAR}"); 161 162 TableExample example = (TableExample) parameter.get("example"); 163 applyWhere(example, true); 164 return SQL(); 165 } 166 167 public String updateByPrimaryKeySelective(Table record) { 168 BEGIN(); 169 UPDATE("table"); 170 171 if (record.getName() != null) { 172 SET("name = #{name,jdbcType=VARCHAR}"); 173 } 174 175 if (record.getTelNumber() != null) { 176 SET("tel_number = #{telNumber,jdbcType=VARCHAR}"); 177 } 178 179 if (record.getDegree() != null) { 180 SET("degree = #{degree,jdbcType=VARCHAR}"); 181 } 182 183 if (record.getSex() != null) { 184 SET("sex = #{sex,jdbcType=CHAR}"); 185 } 186 187 if (record.getGradUni() != null) { 188 SET("grad_uni = #{gradUni,jdbcType=VARCHAR}"); 189 } 190 191 if (record.getMail() != null) { 192 SET("mail = #{mail,jdbcType=VARCHAR}"); 193 } 194 195 if (record.getPassword() != null) { 196 SET("password = #{password,jdbcType=VARCHAR}"); 197 } 198 199 WHERE("id = #{id,jdbcType=INTEGER}"); 200 201 return SQL(); 202 } 203 204 protected void applyWhere(TableExample example, boolean includeExamplePhrase) { 205 if (example == null) { 206 return; 207 } 208 209 String parmPhrase1; 210 String parmPhrase1_th; 211 String parmPhrase2; 212 String parmPhrase2_th; 213 String parmPhrase3; 214 String parmPhrase3_th; 215 if (includeExamplePhrase) { 216 parmPhrase1 = "%s #{example.oredCriteria[%d].allCriteria[%d].value}"; 217 parmPhrase1_th = "%s #{example.oredCriteria[%d].allCriteria[%d].value,typeHandler=%s}"; 218 parmPhrase2 = "%s #{example.oredCriteria[%d].allCriteria[%d].value} and #{example.oredCriteria[%d].criteria[%d].secondValue}"; 219 parmPhrase2_th = "%s #{example.oredCriteria[%d].allCriteria[%d].value,typeHandler=%s} and #{example.oredCriteria[%d].criteria[%d].secondValue,typeHandler=%s}"; 220 parmPhrase3 = "#{example.oredCriteria[%d].allCriteria[%d].value[%d]}"; 221 parmPhrase3_th = "#{example.oredCriteria[%d].allCriteria[%d].value[%d],typeHandler=%s}"; 222 } else { 223 parmPhrase1 = "%s #{oredCriteria[%d].allCriteria[%d].value}"; 224 parmPhrase1_th = "%s #{oredCriteria[%d].allCriteria[%d].value,typeHandler=%s}"; 225 parmPhrase2 = "%s #{oredCriteria[%d].allCriteria[%d].value} and #{oredCriteria[%d].criteria[%d].secondValue}"; 226 parmPhrase2_th = "%s #{oredCriteria[%d].allCriteria[%d].value,typeHandler=%s} and #{oredCriteria[%d].criteria[%d].secondValue,typeHandler=%s}"; 227 parmPhrase3 = "#{oredCriteria[%d].allCriteria[%d].value[%d]}"; 228 parmPhrase3_th = "#{oredCriteria[%d].allCriteria[%d].value[%d],typeHandler=%s}"; 229 } 230 231 StringBuilder sb = new StringBuilder(); 232 List<Criteria> oredCriteria = example.getOredCriteria(); 233 boolean firstCriteria = true; 234 for (int i = 0; i < oredCriteria.size(); i++) { 235 Criteria criteria = oredCriteria.get(i); 236 if (criteria.isValid()) { 237 if (firstCriteria) { 238 firstCriteria = false; 239 } else { 240 sb.append(" or "); 241 } 242 243 sb.append('('); 244 List<Criterion> criterions = criteria.getAllCriteria(); 245 boolean firstCriterion = true; 246 for (int j = 0; j < criterions.size(); j++) { 247 Criterion criterion = criterions.get(j); 248 if (firstCriterion) { 249 firstCriterion = false; 250 } else { 251 sb.append(" and "); 252 } 253 254 if (criterion.isNoValue()) { 255 sb.append(criterion.getCondition()); 256 } else if (criterion.isSingleValue()) { 257 if (criterion.getTypeHandler() == null) { 258 sb.append(String.format(parmPhrase1, criterion.getCondition(), i, j)); 259 } else { 260 sb.append(String.format(parmPhrase1_th, criterion.getCondition(), i, j,criterion.getTypeHandler())); 261 } 262 } else if (criterion.isBetweenValue()) { 263 if (criterion.getTypeHandler() == null) { 264 sb.append(String.format(parmPhrase2, criterion.getCondition(), i, j, i, j)); 265 } else { 266 sb.append(String.format(parmPhrase2_th, criterion.getCondition(), i, j, criterion.getTypeHandler(), i, j, criterion.getTypeHandler())); 267 } 268 } else if (criterion.isListValue()) { 269 sb.append(criterion.getCondition()); 270 sb.append(" ("); 271 List<?> listItems = (List<?>) criterion.getValue(); 272 boolean comma = false; 273 for (int k = 0; k < listItems.size(); k++) { 274 if (comma) { 275 sb.append(", "); 276 } else { 277 comma = true; 278 } 279 if (criterion.getTypeHandler() == null) { 280 sb.append(String.format(parmPhrase3, i, j, k)); 281 } else { 282 sb.append(String.format(parmPhrase3_th, i, j, k, criterion.getTypeHandler())); 283 } 284 } 285 sb.append(')'); 286 } 287 } 288 sb.append(')'); 289 } 290 } 291 292 if (sb.length() > 0) { 293 WHERE(sb.toString()); 294 } 295 } 296 297 public String getCntsql(String name,String sex){ 298 StringBuilder str = new StringBuilder(); 299 str.append("select count(*) from table where name = #{name}"); 300 return str.toString(); 301 } 302 303 public String getListsql(Map<String, String> map){ 304 StringBuilder str = new StringBuilder(); 305 str.append("select name,"); 306 str.append("sex,"); 307 str.append("tel_number,"); 308 str.append("degree,"); 309 str.append("grad_uni,"); 310 str.append("mail from table where 1 = 1"); 311 312 String name = map.get("name"); 313 if(!StringUtils.isEmpty(name)){ 314 str.append(" and name like '%"); 315 str.append(name); 316 str.append("%'"); 317 } 318 319 String sex = map.get("sex"); 320 if(!StringUtils.isEmpty(sex)){ 321 str.append(" and sex = "); 322 str.append(sex); 323 } 324 325 str.append(" limit #{offset},#{size}"); 326 return str.toString(); 327 } 328 329 public String getmappersql(Table table){ 330 StringBuilder str = new StringBuilder(); 331 str.append("select count(*) from table where name = #{name}"); 332 return str.toString(); 333 } 334 }
頁面有兩個,登錄注冊/頁面和顯示頁面,由於是demo,所以沒加任何樣式,大家湊合看吧。
登錄/注冊:
1 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> 2 <%@ include file="/WEB-INF/views/include/global.jsp"%> 3 <%@ page import="com.javen.common.constant.UrlConst" %> 4 <c:set target="${self.content}" property="main"> 5 <form action="${base}/wf/test" method="post"> 6 <table style="width:250px;height:100px" border="1" align="center"> 7 <tbody> 8 <tr> 9 <th width="80px" height="80px" >請輸入用戶名</th> 10 <td width="80px" height="80px" > 11 <input type="text" width="200px" placeholder="用戶名" pattern="^[A-Za-z0-9_\u4e00-\u9fa5\/]+$" title="請輸入字母,數字或中文!"> 12 </td> 13 </tr> 14 <tr> 15 <th width="80px" height="80px" align="center">請輸入密碼</th> 16 <td width="80px" height="80px"> 17 <input type="password" width="200px" placeholder="密碼" pattern="^[A-Za-z0-9]+$" title="請輸入字母,數字!"> 18 </td> 19 </tr> 20 <tr> 21 <th width="80px" height="80px"></th> 22 <td width="80px" height="80px"> 23 <a href="javascript:void(0);" onclick="layer_show('登錄','${base}/wf/test/list','750','600')" class="btn radius btn-secondary size-MINI ml-5">登錄</a> 24 </td> 25 </tr> 26 </tbody> 27 </table> 28 29 30 </form> 31 </c:set> 32 <%@ include file="/WEB-INF/views/include/main.jsp"%>
顯示:
1 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> 2 <%@ include file="/WEB-INF/views/include/global.jsp"%> 3 <%@ page import="com.javen.common.constant.UrlConst" %> 4 <c:set target="${self.content}" property="main"> 5 <form action="${base}/wf/test/list" method="post" > 6 <div class="text-l"> 7 <label>用戶名:</label> 8 <input id="name" name="name" value="${name}" type="tel" class="input-text" style="width:250px; " placeholder="用戶名"> 9 <label>性別:</label> 10 <c:choose> 11 <c:when test="${sex == 0}"> 12 <input id="sex1" name="sex" value="0" type="radio" checked/>男 13 <input id="sex2" name="sex" value="1" type="radio"/>女 14 </c:when> 15 <c:when test="${sex == 1}"> 16 <input id="sex3" name="sex" value="0" type="radio"/>男 17 <input id="sex4" name="sex" value="1" type="radio"checked/>女 18 </c:when> 19 <c:otherwise > 20 <input id="sex5" name="sex" value="0" type="radio"/>男 21 <input id="sex6" name="sex" value="1" type="radio"/>女 22 </c:otherwise> 23 </c:choose> 24 25 <button type="submit" > 查找</button> 26 </div> 27 <div> 28 <span> 29 <a class="btn btn-primary radius" href="javascript:void(0);" onclick="layer_show('添加數據','${base}/','750','600')"><i class="Hui-iconfont"></i> 添加數據</a> 30 </span> 31 <span class="r">共有數據:<strong>${cnt}</strong> 條</span> 32 </div> 33 <table class="table table-border table-bordered table-hover table-bg"> 34 <thead> 35 <tr class="text-c"> 36 <th width="20">序號</th> 37 <th width="200">用戶名</th> 38 <th width="200">密碼</th> 39 <th width="200">電話</th> 40 <th width="200">學位</th> 41 <th width="200">性別</th> 42 <th width="200">畢業院校</th> 43 <th width="200">郵箱</th> 44 </tr> 45 </thead> 46 <tbody> 47 <c:forEach var="data" items="${list}" varStatus="status"> 48 <tr> 49 <td class="text-c">${offset + status.index + 1}</td> 50 <td class="text-c">${data.name}</td> 51 <td class="text-c">${data.password}</td> 52 <td class="text-c">${data.tel_number}</td> 53 <td class="text-c">${data.degree}</td> 54 <td class="text-c">${data.grad_uni}</td> 55 <td class="text-c">${data.mail}</td> 56 <td class="text-c">${data.sex}</td> 57 <%-- <input id="type_id" type="hidden" name="type_id" value="${data.type_id}"> --%> 58 <td class="text-c f-14"> 59 <a href="javascript:void(0);" onclick="layer_show('修改數據','${base}/','750','600')" class="btn radius btn-secondary size-MINI ml-5">修改</a> 60 <a href="javascript:void(0);" onclick="layer_show('刪除數據','${base}/','750','600')" class="btn radius btn-danger size-MINI ml-5">刪除</a> 61 62 </td> 63 </tr> 64 </c:forEach> 65 </tbody> 66 </table> 67 68 <!-- <script type="text/javascript" src="jquery/1.9.1/jquery.min.js"></script> --> 69 70 71 <script> 72 73 $(document).ready(function () { 74 $("#btnClear").click(function () { 75 $("input").val(""); 76 // $("select") .val(""); 77 }); 78 79 }); 80 81 82 83 // $(document).ready(function(){ 84 // alert("第一種方法。"); 85 // }); 86 </script> 87 <%-- <%@ include file="/WEB-INF/views/bussiness/wfActivity/activityPage.jsp"%> --%> 88 <%@ include file="/WEB-INF/views/include/pagination.jsp"%> 89 </form> 90 </c:set> 91 <%@ include file="/WEB-INF/views/include/main.jsp"%>
下面是我總結的增刪改查思想,工作中或是其他場景做各種框架服務基本都是這么個流程(話說問我什么時候能入門架構。。。)
查詢:
獲取結果集合,
判斷是否有數據(模糊查詢)
如果有,
model.addAttribute()傳值
返頁面,
如果沒有,報錯
添加:
先判斷是否有輸入
在判斷輸入的值是否與與已有數據重復
創建日期 修改日期balabala
如果插入了 返回成功
如果沒有,報錯
修改:(刪除中的邏輯刪除也算是一種修改,寫法類似)
判斷是否輸入
在判斷修改的對象是否正確
如果修改返回成功
如果沒有,報錯
以上就是SpringMVC簡單的增刪改查功能的實現,希望對大家有幫助~