1. 程式人生 > >項目一:第四天

項目一:第四天

rip 單元格 提交表單 path orderby get 復制 batch 解析excel

1、 快遞員的條件分頁查詢-noSession,條件查詢

2、 快遞員刪除(邏輯刪除)

3、 基於Apache POI實現批量導入區域數據

a) Jquery OCUpload上傳文件插件使用

b) Apache POI讀取excel文件數據

1.1 快遞員的條件分頁查詢 --關鍵 需要將查詢條件 和分頁條件都綁定到一次請求中

1、 提供工具方法:將表單序列化為json對象

//工具方法:將表單中輸入項格式化為json對象 {"input的name":"input的value",}

$.fn.serializeJson=function(){

var serializeObj={};

var array=this.serializeArray();

var str=this.serialize();

$(array).each(function(){

if(serializeObj[this.name]){

if($.isArray(serializeObj[this.name])){

serializeObj[this.name].push(this.value);

}else{

serializeObj[this.name]=[serializeObj[this.name],this.value];

}

}else{

serializeObj[this.name]=this.value;

}

});

return serializeObj;

};

1、 給彈出查詢窗口,查詢按鈕綁定單擊事件

技術分享圖片

技術分享圖片

1.1.1 服務端完成查詢

1、 將頁面提交參數獲取到,查詢數據中符合條件數據

2、 現在Dao繼承接口JpaRepository接口,沒有根據條件查詢,返回分頁數據方法。故需要讓dao接口繼承另外接口

技術分享圖片

技術分享圖片

1、 改造action中分頁方法

/**

* @Description: 快遞員分頁查詢

*/

@Action("courierAction_pageQuery")

public String pageQuery() throws Exception {

Pageable pageable = new PageRequest(page-1, rows);

//通過模型驅動model將查詢條件獲取到

Page<Courier> page = courierService.pageQuery(model, pageable);

Map<String, Object> map = new HashMap<>();

map.put("total", page.getTotalElements());

map.put("rows", page.getContent());

//需要將一些不要轉json屬性排除掉

JsonConfig jsonConfig = new JsonConfig();

jsonConfig.setExcludes(new String[]{"fixedAreas"});

String json = JSONObject.fromObject(map, jsonConfig).toString();

System.out.println(json);

//通過response對象向瀏覽器響應json

ServletActionContext.getResponse().setContentType("text/json;charset=utf-8");

ServletActionContext.getResponse().getWriter().write(json);

return NONE;

}

2、 Service層中進行條件封裝

/**

* @Description: 條件查詢(單表查詢,多表關聯查詢)

* @param model :查詢條件

* @param pageable :分頁需要參數

ORM框架查詢:通過查詢實體 設置查詢條件 最終發出sql: select * from tableName where c1 = ? and|or c2 = ? or c3 like ‘%‘?‘%‘

*/

public Page<Courier> pageQuery(Courier model, Pageable pageable) {

final String courierNum = model.getCourierNum();

final String company = model.getCompany();

final String type = model.getType();

final Standard standard = model.getStandard();

//Specification對象封裝查詢條件

Specification<Courier> spec = new Specification<Courier>() {

//predicate查詢條件: 等同於 where c1 = ?

//Root:代表Criteria查詢的根對象, 相當於sql : from talbeName

//CriteriaQuery接口:代表一個specific的頂層查詢對象,它包含著查詢的各個部分,比如:select 、from、where、group by、order by等

//CriteriaBuilder接口:用來構建CritiaQuery的構建器對象: 工廠對象:創建Predicate工廠實例

public Predicate toPredicate(Root<Courier> root, CriteriaQuery<?> query, CriteriaBuilder cb) {

List<Predicate> list = new ArrayList<>();

//cb.equal 運算符 使用等於=

//p1:查詢根實體中屬性 p2:查詢條件值

if(StringUtils.isNotBlank(courierNum)){

Predicate p1 = cb.equal(root.get("courierNum").as(String.class), courierNum);

list.add(p1);

}

if(StringUtils.isNotBlank(company)){

Predicate p2 = cb.like(root.get("company").as(String.class), "%"+company+"%");

list.add(p2);

}

if(StringUtils.isNotBlank(type)){

Predicate p3 = cb.equal(root.get("type").as(String.class), type);

list.add(p3);

}

//快遞員表跟收派標準表關聯查詢

if(standard!=null && StringUtils.isNotBlank(standard.getName())){

//創建收派標準關聯對象 默認內連接

Join<Object, Object> join = root.join("standard", JoinType.INNER);

Predicate p4 = cb.equal(join.get("name").as(String.class), standard.getName());

list.add(p4);

}

if(list!=null && list.size()==0){

return null;

}

Predicate[] restrictions = new Predicate[list.size()];

//將list集合轉為數組

restrictions = list.toArray(restrictions);

//cb.and 相對多個條件 並且 cb.or--或者

return cb.and(restrictions);

}

};

return courierDao.findAll(spec , pageable);

技術分享圖片

1.1.1 JpaSpecificationExecutor查詢接口說明

參數:Criteria查詢基本概念

Criteria 查詢是以元模型的概念為基礎的,元模型是為具體持久化單元的受管實體定義的,這些實體可以是實體類,嵌入類或者映射的父類。

CriteriaQuery接口:代表一個specific的頂層查詢對象,它包含著查詢的各個部分,比如:select 、from、where、group by、order by等

註意:CriteriaQuery對象只對實體類型或嵌入式類型的Criteria查詢起作用

參數:Root接口:代表Criteria查詢的根對象,Criteria查詢的查詢根定義了實體類型,能為將來導航獲得想要的結果,它與SQL查詢中的FROM子句類似

1:Root實例是類型化的,且定義了查詢的FROM子句中能夠出現的類型。

2:查詢根實例能通過傳入一個實體類型給 AbstractQuery.from方法獲得。

3:Criteria查詢,可以有多個查詢根。

4:AbstractQuery是CriteriaQuery 接口的父類,它提供得到查詢根的方法。

參數:CriteriaBuilder接口:用來構建CritiaQuery的構建器對象

返回值:Predicate:一個簡單或復雜的謂詞類型,其實就相當於條件或者是條件組合。

Criteria查詢

基本對象的構建

1:通過EntityManager的getCriteriaBuilder或EntityManagerFactory的getCriteriaBuilder方法可以得到CriteriaBuilder對象

2:通過調用CriteriaBuilder的createQuery或createTupleQuery方法可以獲得CriteriaQuery的實例

3:通過調用CriteriaQuery的from方法可以獲得Root實例

過濾條件

1:過濾條件會被應用到SQL語句的FROM子句中。在criteria 查詢中,查詢條件通過Predicate或Expression實例應用到CriteriaQuery對象上。

2:這些條件使用 CriteriaQuery .where 方法應用到CriteriaQuery 對象上

3:CriteriaBuilder也作為Predicate實例的工廠,通過調用CriteriaBuilder 的條件方法( equal,notEqual, gt, ge,lt, le,between,like等)創建Predicate對象。

4:復合的Predicate 語句可以使用CriteriaBuilder的and, or andnot 方法構建。

構建簡單的Predicate示例:

Predicate p1=cb.like(root.get(“name”).as(String.class), “%”+uqm.getName()+“%”);

Predicate p2=cb.equal(root.get("uuid").as(Integer.class), uqm.getUuid());

Predicate p3=cb.gt(root.get("age").as(Integer.class), uqm.getAge());

構建組合的Predicate示例:

Predicate p = cb.and(p3,cb.or(p1,p2));

當然也可以形如前面動態拼接查詢語句的方式,比如:

java代碼:

查看復制到剪貼板打印

Specification<UserModel> spec = new Specification<UserModel>() {

public Predicate toPredicate(Root<UserModel> root, CriteriaQuery<?> query, CriteriaBuilder cb) {

List<Predicate> list = new ArrayList<Predicate>();

if(um.getName()!=null && um.getName().trim().length()>0){

list.add(cb.like(root.get("name").as(String.class), "%"+um.getName()+"%"));

}

if(um.getUuid()>0){

list.add(cb.equal(root.get("uuid").as(Integer.class), um.getUuid()));

}

Predicate[] p = new Predicate[list.size()];

return cb.and(list.toArray(p));

}

};


也可以使用CriteriaQuery來得到最後的Predicate,示例如下:

java代碼:

查看復制到剪貼板打印

Specification<UserModel> spec = new Specification<UserModel>() {

public Predicate toPredicate(Root<UserModel> root, CriteriaQuery<?> query, CriteriaBuilder cb) {

Predicate p1 = cb.like(root.get("name").as(String.class), "%"+um.getName()+"%");

Predicate p2 = cb.equal(root.get("uuid").as(Integer.class), um.getUuid());

Predicate p3 = cb.gt(root.get("age").as(Integer.class), um.getAge());

//把Predicate應用到CriteriaQuery中去,因為還可以給CriteriaQuery添加其他的功能,比如排序、分組啥的

query.where(cb.and(p3,cb.or(p1,p2)));

//添加排序的功能

query.orderBy(cb.desc(root.get("uuid").as(Integer.class)));

return query.getRestriction();

}

邏輯刪除

、頁面:調整

function doDelete(){

//判斷選中記錄數

var rows = $("#grid").datagrid("getSelections");

if(rows.length==0){

$.messager.alert(‘系統信息‘,"請至少選中一條記錄操作!","warning");

}else{

console.info(rows);

//創建js數組對象

var array = new Array();

//將選中快遞員json數組中id獲取出來

for(var i=0;i<rows.length;i++){

var id = rows[i].id;

//push() 方法可向數組的末尾添加一個或多個元素

array.push(id);

}

//元素是通過指定的分隔符進行分隔的。

var ids = array.join(",");

//發送請求,將快遞員id提交

window.location.href="${pageContext.request.contextPath}/courierAction_delete.action?ids="+ids;

//或者發送ajax請求

}

}

};

技術分享圖片

1.1 方式二:ajax請求提交

function doDelete(){

//判斷選中記錄數

var rows = $("#grid").datagrid("getSelections");

if(rows.length>0){

$.messager.confirm(‘提示信息‘,‘是否進行刪除!‘,function(r){

if(r){

// 將刪除快遞員id獲取到

//創建數組

var array = new Array();

for(var i=0;i<rows.length;i++){

var id = rows[i].id;

//向數組中添加數據

array.push(id);

}

//設置數組內容拼接符 默認使用逗號分隔

var ids = array.join(",");

//發送請求:提交快遞員的id 刪除數據

//方式一:location.href="xxx.action?ids="+ids; 會刷新頁面,需要在服務端配置結果視圖

//方式二:發送ajax請求,不需要結果視圖

$.post("${pageContext.request.contextPath}/courierAction_deleteBatch.action",{“ids”:ids},function(data){

//讓datagrid重新加載數據

$("#grid").datagrid("reload");

})

}

})

}else{

$.messager.alert(‘提示信息‘,‘請至少選中一條記錄操作!‘,‘warning‘);

}

}

技術分享圖片

技術分享圖片

1、 ocUpload使用:

a) 引入js文件

<script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery-1.8.3.js"></script>

<script type="text/javascript" src="${pageContext.request.contextPath }/js/ocupload/jquery.ocupload-1.1.2.js"></script>

b) 在頁面提供任意的元素 給出id

c) 在頁面加載完成後調用uplaod方法:動態修改html元素

技術分享圖片

技術分享圖片

public static void main(String[] args) throws Exception {

//解析本地磁盤exel文件 後綴名:xls

//文件目錄

String pathname = "H:\\北京Java271期_速運快遞\\速運快遞項目-day04\\資料\\03_區域測試數據\\區域導入測試數據.xls";

//使用POI提供API讀取文件

//:excel文件對象

//07版本 XSSFWorkbook

HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(new File(pathname)));

//解析文件中數據

//從文件對象中獲取標簽頁

HSSFSheet sheet = workbook.getSheetAt(0);

//遍歷標簽頁中行

for (Row row : sheet) {

//遍歷每一行中單元格中數據

System.out.println();

for (Cell cell : row) {

System.out.print(cell.getStringCellValue()+" ");

}

}

}

1.1.1 在項目中使用POI

//定義變量接收上傳文件

private File upload;

//接收文件MIME類型,文件名稱

private String uploadContentType;

private String uploadFileName;

public void setUpload(File upload) {

this.upload = upload;

}

public void setUploadContentType(String uploadContentType) {

this.uploadContentType = uploadContentType;

}

public void setUploadFileName(String uploadFileName) {

this.uploadFileName = uploadFileName;

}

/**

* @Description: 通過POI解析excel文件中數據

*/

@Action("areaAction_importXls")

public String importXls() throws Exception {

List<Area> list = new ArrayList<>();

//創建excel文件對象

HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(upload));

//獲取標簽頁

HSSFSheet sheet = workbook.getSheetAt(0);

//遍歷標簽頁獲取行

for (Row row : sheet) {

//忽略標題行

if(row.getRowNum()==0){

continue;

}

String id = row.getCell(0).getStringCellValue();

String province = row.getCell(1).getStringCellValue();

String city = row.getCell(2).getStringCellValue();

String district = row.getCell(3).getStringCellValue();

String postcode = row.getCell(4).getStringCellValue();

//創建區域對象

Area area = new Area(id, province, city, district, postcode, null, null);

list.add(area);

}

areaService.save(list);

//釋放資源

workbook.close();

//由於提交表單到Iframe中,故配置結果視圖也看不到

return NONE;

}

1.1 Pinyin4j

漢字跟拼音轉換。

1.1.1 Demo

技術分享圖片

項目一:第四天