1 通用Mapper介紹
1.1 通用Mapper入門案例
1.1.1 通用的findCount()
- 編輯介面
/** * 需求:自己實現一個通用Mapper的方法 * 要求:查詢任意表的記錄總數??? * sql: select count(*) from 表名 */ @SelectProvider(type = SysMapperProvider.class, method = "dynamicSQL") int findCount(); 2.編輯測試方法 /** * 目的:獲取表的名稱 * 1.獲取方法的執行的路徑 * 2.獲取Mapper的介面路徑 * 3.通過反射的機制獲取Mapper的型別 * 4.通過Mapper的型別獲取父級介面型別 * 1.判斷父級介面是否為泛型 * 5.獲取泛型中的型別 Item * 6.獲取item型別的註解 * 7.獲取表的名稱 * @param ms * @return */ public SqlNode findCount(MappedStatement ms){ //1.獲取當前正在執行的Mapper的方法路徑 //com.jt.manage.mapper.itemMapper.findCount() try { //1.獲取客戶端呼叫的方法 //com.jt.manage.mapper.ItemMapper.findCount() String methodPath = ms.getId(); //2.獲取ItemMapper的字串 com.jt.manage.mapper.ItemMapper String targetPath = methodPath.substring(0, methodPath.lastIndexOf(".")); //3.獲取ItemMapper物件 ItemMapper.Class Class<?> targetClass = Class.forName(targetPath); //4.獲取ItemMapper的父級介面 由於介面是可以多繼承的 Type[] types = targetClass.getGenericInterfaces(); //5.獲取SysMapper Type targetType = types[0]; //判斷該型別是否為泛型 SysMapper<Item> if(targetType instanceof ParameterizedType){ //表示當前介面是一個泛型,並且獲取泛型引數 SysMapper<Item> ParameterizedType parameterizedType = (ParameterizedType) targetType; //SysMapper<T,V,K> 獲取泛型的全部引數 Item Type Type[] supers = parameterizedType.getActualTypeArguments(); //表示成功獲取第一個引數 Item.class Class<?> targetMethodClass = (Class<?>) supers[0]; //判斷Class不能為空 if(targetMethodClass !=null){ //判斷該類中是否含有註解 if(targetMethodClass.isAnnotationPresent(Table.class)){ //獲取目標物件的註解 Table table = targetMethodClass.getAnnotation(Table.class); //獲取表名 String tableName = table.name(); //定義查詢sql語句 String sql = "select count(*) from "+tableName; //定義sqlNode物件 SqlNode sqlNode = new StaticTextSqlNode(sql); return sqlNode; } } } } catch (ClassNotFoundException e) { e.printStackTrace(); } return null; }
2 富文字編輯器
2.1 入門案例
2.1.1 引入js
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <link href="/js/kindeditor-4.1.10/themes/default/default.css" type="text/css" rel="stylesheet"> <script type="text/javascript" charset="utf-8" src="/js/kindeditor-4.1.10/kindeditor-all-min.js"></script> <script type="text/javascript" charset="utf-8" src="/js/kindeditor-4.1.10/lang/zh_CN.js"></script> <script type="text/javascript" charset="utf-8" src="/js/jquery-easyui-1.4.1/jquery.min.js"></script>
2.1.2 初始化文字編輯器
<script type="text/javascript"> $(function(){ KindEditor.ready(function(){ KindEditor.create("#editor") }) }) </script>
2.2 商品描述新增
2.2.1 表設計
2.2.2 編輯pojo物件
2.2.3 頁面分析
說明:根據頁面中的name屬性進行資料傳輸
<td>商品描述:</td> <td> <textarea style="width:800px;height:300px;visibility:hidden;" name="desc"></textarea> </td>
2.2.4 編輯Controller
2.2.5 編輯Service
/** * 說明: * Item物件的主鍵是自增的,所以item中的id現在為null * ItemDesc物件入庫操作時,必須含有主鍵Id資訊. * 困難:如果獲取已經入庫的id?? * 解決: * 利用通用Mapper的機制.當執行插入操作時,會先查詢當前最大的id. * 之後回顯. * SELECT LAST_INSERT_ID() * @param item * @param desc */ @Override public void saveItem(Item item,String desc) { //補齊Item資料 item.setStatus(1); //啟用 item.setCreated(new Date()); item.setUpdated(item.getCreated()); //利用通用Mapper實現入庫操作 itemMapper.insert(item); //為ItemDesc補齊資料 ItemDesc itemDesc = new ItemDesc(); itemDesc.setItemDesc(desc); itemDesc.setItemId(item.getId()); itemDesc.setCreated(item.getCreated()); itemDesc.setUpdated(item.getCreated()); itemDescMapper.insert(itemDesc); }
2.3 商品描述的回顯
2.3.1 頁面分析
2.3.2 編輯Controller
2.3.3 編輯Service
說明:通過通用Mapper的根據主鍵查詢ItemDesc資訊
2.4 商品描述資訊修改
2.4.1 頁面分析
說明:根據修改頁面的語句.接收name=desc提交的資料
<tr> <td>商品描述:</td> <td> <textarea style="width:800px;height:300px;visibility:hidden;" name="desc"></textarea> </td> </tr>
2.4.2 編輯Controller
說明:接收Desc資料
2.4.3 編輯Service
2.4.4 效果展現
說明:資料已經修改
2.5 商品關聯刪除
2.5.1 商品描述刪除
2.6 圖片的上傳
2.6.1 頁面分析
說明:如果測試圖片上傳,需要使用谷歌瀏覽器.
2.6.2 新增檔案上傳解析器
<!--配置檔案上傳解析器 要求: 1.id的名稱必須固定 multipartResolver 2.規範檔案上傳的引數 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!--最大的上傳量10M --> <property name="maxUploadSize" value="10485760"/> <property name="defaultEncoding" value="UTF-8"/> </bean>
2.7 Spring屬性賦值
說明:將本地的磁碟路徑和url直接寫死在程式碼中,不是特別的好,最好使用配置檔案的方式進行動態的注入.
2.7.1 編輯配置檔案
2.7.2 Spring容器管理配置檔案
2.7.3 動態的取值
2.8 檔案上傳
2.8.1 編輯Controller
2.8.2 編輯Service
/** * 檔案上傳的步驟 * 1.判斷是否為圖片 png|jpg|gif * 2.判斷是否非法程式 通過BufferedImage物件 * 3.為了讓圖片檢索快速,使用分資料夾儲存 * 4.應該儘可能讓圖片名稱不一致 * 5.將檔案進行寫盤操作 * 6.url和本地的檔案路徑的關係? * url的作用: * 通過使用者訪問虛擬路徑,獲取圖片的資源 * https://img11.360buyimg.com/n1/s150x150_jfs/t4918/211/45049371/104197/15abee23/58d9d1deN542b664b.jpg * * 結論: * 1.本地的磁碟路徑是儲存圖片的實體地址 * 2.url是使用者訪問圖片的虛擬地址 * * 實體地址: E:\jt-upload/2018/10/1/10/abc.jpg * 虛擬地址: http://image.jt.com/2018/10/1/10/abc.jpg * * */ @Override public PicUploadResult uploadFile(MultipartFile uploadFile) { PicUploadResult result = new PicUploadResult(); //1.獲取檔案的名稱 abc.jpg String fileName = uploadFile.getOriginalFilename(); //2.判斷是否為圖片型別 .代表任意一個不為空格的字元 if(!fileName.matches("^.*(jpg|png|gif)$")){ result.setError(1); //表示不是一個圖片 return result; } try { //3.判斷是否為惡意程式 BufferedImage bufferedImage = ImageIO.read(uploadFile.getInputStream()); //4.獲取圖片的高度和寬度 int height = bufferedImage.getHeight();//獲取高度 int width = bufferedImage.getWidth(); //獲取寬度 if(height == 0 || width == 0){ //表示不是圖片 result.setError(1); return result; } //如果程式執行到這裡表示圖片正常 //5.定義本地磁碟的路徑 //String LPath = "E:/jt-upload/"; //6.採用時間格式分檔案儲存 yyyy/MM/dd/HH String datePath = new SimpleDateFormat("yyyy/MM/dd/HH") .format(new Date()); //7.拼接儲存資料夾 E:/jt-upload/yyyy/MM/dd/HH String filePath = LPath + datePath; //8.判斷資料夾是否存在 File file = new File(filePath); if(!file.exists()){ //表示檔案不存在 file.mkdirs(); //建立資料夾 } //9.重構檔名,讓檔名稱儘可能不一致 //獲取檔案的型別 abc.jpg===>.jpg String fileType = fileName.substring(fileName.lastIndexOf(".")); //使用UUID生成檔名稱 sdfsdfsdf-sdfsdfa-sadfasdf-asdfasd String uuid = UUID.randomUUID().toString() .replace("-", ""); /** * 形成檔案的完成路徑 E:/jt-upload/yyyy/MM/dd/HH/asdfasdfasdf.jpg */ String realPath = filePath + "/" + uuid + fileType; //10.寫盤操作 uploadFile.transferTo(new File(realPath)); //11.封裝虛擬路徑,使用者圖片的展現 //String uPath = "http://image.jt.com/"; //拼接虛擬路徑 //http://image.jt.com/2018/03/02/16/ String realUrlPath = uPath + datePath + "/" + uuid + fileType; result.setUrl(realUrlPath); //賦值url路徑 result.setHeight(height+""); result.setWidth(width+""); return result; } catch (Exception e) { result.setError(1); //表示非法圖片 return result; } }
3 檔案上傳的圖片回顯
3.1 url分析
3.1.1 檔案回顯的url
說明:檔案上傳後.根據自定義的虛擬路徑獲取圖片的資訊
問題:
檔案在本地磁碟下儲存
E:\jt-upload\2018\03\02\16\1.jpg
URL的路徑
http://image.jt.com/2018/03/02/17/54d2410e4d6646a4882377d0aa0510f3.jpg
問題:本地的磁碟路徑與url的路徑是不匹配的
解決方法:nginx反向代理技術
3.1.2 反向代理
說明:使用者根據虛擬路徑請求靜態資源,經過Nginx中,將請求轉發真實的磁碟路徑下.獲取靜態資原始檔.再次由Nginx將結果回傳給客戶端.這樣的方式叫做反向代理
3.2 Nginx介紹
3.2.1 Nginx說明
3.2.2 Nginx下載
3.3 Nginx本地磁碟部署
3.3.1 匯入本地
說明:路徑不要安裝到C盤/不要有空格和中文
3.3.2 Nginx命令
- 以管理員身份執行
2.命令
1.start nginx
2.nginx -s stop
3.nginx -s reload
重啟(該命令會提示報錯資訊)
3.3.3 Nginx配置
#定義圖片伺服器 root表示轉向資料夾 server { listen 80; server_name image.jt.com; location / { root E:\jt-upload; } }
3.3.4 修改hosts檔案
說明:修改了host檔案後,可以將指定的路徑發往本機.
路徑:
C:\Windows\System32\drivers\etc/hosts
編輯HOST檔案
3.3.5 圖片回顯呼叫過程
說明:
- 當根據虛擬路徑請求圖片時,首先經過Hosts中的配置轉向到本地的伺服器.否則會去外網中查詢image.jt.com的伺服器.
- 通過Hosts檔案轉向本地後,請求會被Nginx攔截實現反向代理.將請求轉發到指定的資料夾下 E:/jt-upload下.請求圖片資訊
- 當獲取到圖片資訊後,返回結果給Nginx.之後再由Nginx回傳給客戶端.
3.3.6 效果: