品優購(IDEA版)-第二天

来源:https://www.cnblogs.com/amiaojiang/archive/2019/11/15/11863807.html
-Advertisement-
Play Games

品優購 第2天 "學習目標" 目標1:運用AngularJS前端框架的常用指令 目標2:完成品牌管理的列表功能 目標3:完成品牌管理的分頁列表功能 目標4:完成品牌管理的增加功能 目標5:完成品牌管理的修改功能 目標6:完成品牌管理的刪除功能 目標7:完成品牌管理的條件查詢功能 目標N:通用Mapp ...


品優購-第2天

學習目標

目標1:運用AngularJS前端框架的常用指令
目標2:完成品牌管理的列表功能
目標3:完成品牌管理的分頁列表功能
目標4:完成品牌管理的增加功能
目標5:完成品牌管理的修改功能
目標6:完成品牌管理的刪除功能
目標7:完成品牌管理的條件查詢功能
目標N:通用Mapper

第1章 前端框架AngularJS入門

1.1 AngularJS簡介rJS

AngularJS 誕生於2009年,由Misko Hevery 等人創建,後為Google所收購。是一款優秀的前端JS框架,已經被用於Google的多款產品當中。AngularJS有著諸多特性,最為核心的是:MVC、模塊化、自動化雙向數據綁定、依賴註入等等。
在這裡插入圖片描述

1.2 AngularJS四大特征

1.2.1 MVC模式

Angular遵循軟體工程的MVC模式,並鼓勵展現,數據,和邏輯組件之間的松耦合.通過依賴註入(dependency injection),Angular為客戶端的Web應用帶來了傳統服務端的服務,例如獨立於視圖的控制。 因此,後端減少了許多負擔,產生了更輕的Web應用。
在這裡插入圖片描述
Model:數據,其實就是angular變數($scope.XX);

View: 數據的呈現,Html+Directive(指令);

Controller:操作數據,就是function,數據的增刪改查;

1.2.2 雙向綁定

AngularJS是建立在這樣的信念上的:即聲明式編程應該用於構建用戶界面以及編寫軟體構建,而指令式編程非常適合來表示業務邏輯。框架採用並擴展了傳統HTML,通過雙向的數據綁定來適應動態內容,雙向的數據綁定允許模型和視圖之間的自動同步。因此,AngularJS使得對DOM的操作不再重要並提升了可測試性。
在這裡插入圖片描述

1.2.3 依賴註入

依賴註入(Dependency Injection,簡稱DI)是一種設計模式, 指某個對象依賴的其他對象無需手工創建,只需要“吼一嗓子”,則此對象在創建時,其依賴的對象由框架來自動創建並註入進來,其實就是最少知識法則;模塊中所有的service和provider兩類對象,都可以根據形參名稱實現DI.

1.2.4 模塊化設計

高內聚低耦合法則

1)官方提供的模塊 ng、ngRoute、ngAnimate

2)用戶自定義的模塊 angular.module(‘模塊名’,[ ])

1.3 入門小Demo

1.3.1 表達式
<html>
<head>
    <title>入門小Demo-1</title>
    <script src="angular.min.js"></script>
</head>
<body ng-app>
{{100+100}}
</body>
</html>

執行結果如下:
在這裡插入圖片描述
表達式的寫法是{{表達式 }} 表達式可以是變數或是運算式

ng-app 指令 作用是告訴子元素以下的指令是歸angularJs的,angularJs會識別的
ng-app 指令定義了AngularJS 應用程式的 根元素。
ng-app 指令在網頁載入完畢時會自動引導(自動初始化)應用程式。

1.3.2 雙向綁定
<html>
<head>
    <title>入門小Demo-1  雙向綁定</title>
    <script src="angular.min.js"></script>
</head>
<body ng-app>
請輸入你的姓名:<input ng-model="myname">
<br>
{{myname}},你好
</body>
</html>

運行效果如下:
在這裡插入圖片描述

ng-model 指令用於綁定變數,這樣用戶在文本框輸入的內容會綁定到變數上,而表達式可以實時地輸出變數。

1.3.3 初始化指令

我們如果希望有些變數具有初始值,可以使用ng-init指令來對變數初始化:

<html>
<head>
    <title>入門小Demo-3  初始化</title>
    <script src="angular.min.js"></script>
</head>
<body ng-app   ng-init="myname='陳大海'">
請輸入你的姓名:<input ng-model="myname">
<br>
{{myname}},你好
</body>
</html>
1.3.4 控制器
<html>
<head>
    <title>入門小Demo-3  初始化</title>
    <script src="angular.min.js"></script>
    <script>
        var app=angular.module('myApp',[]); //定義了一個叫myApp的模塊
        //定義控制器
        app.controller('myController',function($scope){
            $scope.add=function(){
                return parseInt($scope.x)+parseInt($scope.y);
            }
        });
    </script>
</head>
<body ng-app="myApp" ng-controller="myController">
x:<input ng-model="x" >
y:<input ng-model="y" >
運算結果:{{add()}}
</body>
</html>

運行結果如下:
在這裡插入圖片描述
ng-controller用於指定所使用的控制器。

理解 $scope:

$scope 的使用貫穿整個 AngularJS App 應用,它與數據模型相關聯,同時也是表達式執行的上下文.有了$scope就在視圖和控制器之間建立了一個通道,基於作用域視圖在修改數據時會立刻更新 $scope,同樣的$scope 發生改變時也會立刻重新渲染視圖.

1.3.5 事件指令
<html>
<head>
    <title>入門小Demo-5  事件指令</title>
    <script src="angular.min.js"></script>  
    <script>
        var app=angular.module('myApp',[]); //定義了一個叫myApp的模塊
        //定義控制器
        app.controller('myController',function($scope){         
            $scope.add=function(){
                $scope.z= parseInt($scope.x)+parseInt($scope.y);
            }           
        }); 
    </script>
</head>
<body ng-app="myApp" ng-controller="myController">
x:<input ng-model="x" >
y:<input ng-model="y" >
<button ng-click="add()">運算</button>
結果:{{z}}
</body>
</html>

運行結果:
在這裡插入圖片描述
ng-click 是最常用的單擊事件指令,再點擊時觸發控制器的某個方法

1.3.6 迴圈數組
<html>
<head>
    <title>入門小Demo-6  迴圈數據</title>
    <script src="angular.min.js"></script>
    <script>
        var app=angular.module('myApp',[]); //定義了一個叫myApp的模塊
        //定義控制器
        app.controller('myController',function($scope){
            $scope.list= [100,192,203,434 ];//定義數組
        });
    </script>
</head>
<body ng-app="myApp" ng-controller="myController">
<table>
<tr ng-repeat="x in list">
    <td>{{x}}</td>
</tr>
</table>
</body>
</html>

這裡的ng-repeat指令用於迴圈數組變數。

運行結果如下:

1.3.7 迴圈對象數組
<html>
<head>
    <title>入門小Demo-7  迴圈對象數組</title>
    <script src="angular.min.js"></script>  
    <script>
        var app=angular.module('myApp',[]); //定義了一個叫myApp的模塊
        //定義控制器
        app.controller('myController',function($scope){     
            $scope.list= [
                {name:'張三',shuxue:100,yuwen:93},
                {name:'李四',shuxue:88,yuwen:87},
                {name:'王五',shuxue:77,yuwen:56}
            ];//定義數組            
        }); 
    </script>   
</head>
<body ng-app="myApp" ng-controller="myController">
<table>
<tr>
    <td>姓名</td>
    <td>數學</td>
    <td>語文</td>
</tr>
<tr ng-repeat="entity in list">
    <td>{{entity.name}}</td>
    <td>{{entity.shuxue}}</td>
    <td>{{entity.yuwen}}</td>
</tr>
</table>
</body>
</html>

運行結果如下:
在這裡插入圖片描述

1.3.8 內置服務

我們的數據一般都是從後端獲取的,那麼如何獲取數據呢?我們一般使用內置服務$http來實現。註意:以下代碼需要在tomcat中運行。

<html>
<head>
    <title>入門小Demo-8  內置服務</title>
    <meta charset="utf-8" />
    <script src="angular.min.js"></script>  
    <script>
        var app=angular.module('myApp',[]); //定義了一個叫myApp的模塊
        //定義控制器
        app.controller('myController',function($scope,$http){       
            $scope.findAll=function(){
                $http.get('data.json').success(
                    function(response){
                        $scope.list=response;
                    }                   
                );              
            }           
        }); 
    </script>   
</head>
<body ng-app="myApp" ng-controller="myController" ng-init="findAll()">
<table>
<tr>
    <td>姓名</td>
    <td>數學</td>
    <td>語文</td>
</tr>
<tr ng-repeat="entity in list">
    <td>{{entity.name}}</td>
    <td>{{entity.shuxue}}</td>
    <td>{{entity.yuwen}}</td>
</tr>
</table>
</body>
</html>

建立文件 data.json

[
    {"name":"張三","shuxue":100,"yuwen":93},
    {"name":"李四","shuxue":88,"yuwen":87},
    {"name":"王五","shuxue":77,"yuwen":56},
    {"name":"趙六","shuxue":67,"yuwen":86}
]

第2章 通用Mapper

2.1 通用Mapper介紹

通用 Mapper 提供了一些通用的方法,這些通用方法是以介面的形式提供的,它主要簡化了我們工作中常做的單表操作問題,讓MyBatis由面向過程轉換成了面向對象的操作方式,當然,MyBatis編寫SQL面向過程操作和通用Mapper面向對象操作可以共存。

為了方便測試,我們在parent工程中引入log日誌包,版本如下:

<slf4j.version>1.6.6</slf4j.version>
<log4j.version>1.2.12</log4j.version>

包引入如下:

<!-- log start -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>${log4j.version}</version>
</dependency>

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>${slf4j.version}</version>
</dependency>

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>${slf4j.version}</version>
</dependency>
<!-- log end -->

log4j.properties

log4j.rootLogger=DEBUG,Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.org.apache=DEBUG

2.2 配置介紹

使用通用通用Mapper首先需要引入依賴包。

<!--通用Mapper-->
<dependency>
    <groupId>tk.mybatis</groupId>
    <artifactId>mapper</artifactId>
</dependency>

替換MyBatis集成Spring的包掃描bean,修改pinyougou-mapper項目中spring-mybatis.xml

替換前:

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"
   p:basePackage="com.pinyougou.mapper"
     p:sqlSessionFactoryBeanName="sqlSessionFactoryBean" />

替換後:

<bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer"
     p:basePackage="com.pinyougou.mapper"
     p:sqlSessionFactoryBeanName="sqlSessionFactoryBean">
   <!--通用介面-->
   <property name="properties">
      <value>
         mappers=tk.mybatis.mapper.common.Mapper
      </value>
   </property>
</bean>

2.3 MyBatis+通用Mapper+Spring集成測試

在pinyougou-sellergoods-service編寫測試類

package com.pinyougou;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MapperTest {
    private ApplicationContext act;
    @Before
    public void init(){
        act = new ClassPathXmlApplicationContext("classpath:spring/spring.xml");
    }
    @Test
    public void testSpring(){
        String[] names = act.getBeanDefinitionNames();

        for (String name : names) {
            System.out.println(name);
        }
    }
}

測試結果

addressMapper
areasMapper
brandMapper
citiesMapper
contentCategoryMapper
contentMapper
freightTemplateMapper
goodsDescMapper
goodsMapper
itemCatMapper
itemMapper
orderItemMapper
orderMapper
payLogMapper
provincesMapper
seckillGoodsMapper
seckillOrderMapper
sellerMapper
specificationMapper
specificationOptionMapper
typeTemplateMapper
userMapper

這裡可以看到每個介面都產生了一個代理對象,並且註入到Spring容器中,而每個介面都繼承了Mapper 介面,所以初步可以斷定,繼承通用Mapper成功,接著我們來使用通用Mapper實現增刪改查。

2.4通用Mapper的使用

2.4.1 增加操作
2.4.1.1 不忽略空值-insert
/***
 * 增加數據
 * 不忽略空值
 */
@Test
public void testInsert(){
    Brand brand = new Brand();
    brand.setName("深圳黑馬訓練營");
    //brand.setFirstChar("C");
    int acount = brandMapper.insert(brand);
    System.out.println(acount);
}

日誌:

當Brand的id、firstChar為空的時候,SQL語句仍然執行了插入操作。

==>  Preparing: INSERT INTO tb_brand ( id,name,first_char ) VALUES( ?,?,? ) 
==> Parameters: null, 深圳黑馬訓練營(String), null
1.4.1.2. 忽略空值-insertSelective
/***
 * 增加數據
 * 忽略空值
 */
@Test
public void testInsertSelective(){
    Brand brand = new Brand();
    brand.setName("傳智播客-黑馬訓練營");
    //brand.setFirstChar("C");
    int acount = brandMapper.insertSelective(brand);
    System.out.println(acount);
}

日誌:

當Brand的id、firstChar為空的時候,SQL語句沒有執行了插入操作。

==>  Preparing: INSERT INTO tb_brand ( name ) VALUES( ? ) 
==> Parameters: 傳智播客-黑馬訓練營(String)
2.4.2修改操作
2.4.2.1 根據主鍵修改數據-不忽略空值
/**
 * 需改操作
 * 不忽略空值
 */
@Test
public void testUpdateByPrimaryKey(){
    Brand brand = new Brand();
    brand.setId(25L);
    //brand.setName("深圳黑馬訓練營");
    brand.setFirstChar("S");
    //根據主鍵修改數據
    int mcount = brandMapper.updateByPrimaryKey(brand);
    System.out.println(mcount);
}

日誌:

當name為空的時候,SQL語句仍然執行修改。

==>  Preparing: UPDATE tb_brand SET name = ?,first_char = ? WHERE id = ? 
==> Parameters: null, S(String), 25(Long)
2.4.2.2. 根據主鍵修改數據-忽略空值
/**
 * 需改操作
 * 忽略空值
 */
@Test
public void testUpdateByPrimaryKeySelective(){
    Brand brand = new Brand();
    brand.setId(25L);
    brand.setName("深圳黑馬訓練營");
    //brand.setFirstChar("S");
    //根據主鍵修改數據
    int mcount = brandMapper.updateByPrimaryKeySelective(brand);
    System.out.println(mcount);
}

日誌:

當name為空的時候,SQL語句不執行修改。

1
2
3
sql
==>  Preparing: UPDATE tb_brand SET name = ? WHERE id = ? 
==> Parameters: 深圳黑馬訓練營(String), 25(Long)
2.4.2.3構造條件修改數據-不忽略空值
/**
 * 構造條件執行修改
 * 不忽略空值
 */
@Test
public void testUpdateByExample(){
    //firstChar=S
    Brand brand = new Brand();
    brand.setName("深圳市黑馬訓練營");

    //創建Example對象
    Example example = new Example(Brand.class);

    //Criteria 用來構造約束條件
    Example.Criteria criteria = example.createCriteria();

    //第一個參數是Brand對應的屬性,第二個參數是屬性約束值   相當於 where firstChar=S
    criteria.andEqualTo("firstChar","S");

    //條件修改數據
    int mcount = brandMapper.updateByExample(brand,example);
    System.out.println(mcount);
}

日誌:

criteria.andEqualTo(“firstChar”,“S”); 轉換成了這裡的SQL語句 where(first_char=?),這裡firstChart為空,但SQL語句仍然執行了修改。

1
2
==>  Preparing: UPDATE tb_brand SET name = ?,first_char = ? WHERE ( first_char = ? ) 
==> Parameters: 深圳市黑馬訓練營(String), null, S(String)
2.4.2.4 構造條件修改數據-忽略空值
/**
 * 構造條件執行修改
 * 忽略空值
 */
@Test
public void testUpdateByExampleSelective(){
    //firstChar=S
    Brand brand = new Brand();
    brand.setFirstChar("S");
    //創建Example對象
    Example example = new Example(Brand.class);
    //Criteria 用來構造約束條件
    Example.Criteria criteria = example.createCriteria();

    //第一個參數是Brand對應的屬性,第二個參數是屬性約束值   相當於 where name='深圳市黑馬訓練營'
    criteria.andEqualTo("name","深圳市黑馬訓練營");

    //條件修改數據
    int mcount = brandMapper.updateByExampleSelective(brand,example);
    System.out.println(mcount);
}

日誌:

這裡name為空,SQL語句並沒有做出修改操作。

==>  Preparing: UPDATE tb_brand SET first_char = ? WHERE ( name = ? ) 
==> Parameters: S(String), 深圳市黑馬訓練營(String)
2.4.3查詢操作
1.4.3.1. 根據主鍵查詢
/***
 * 根據主鍵查詢
 */
@Test
public void testSelectByPrimaryKey(){
    long id = 25L;
    Brand brand = brandMapper.selectByPrimaryKey(id);
    System.out.println(brand);
}

日誌:

==>  Preparing: SELECT id,name,first_char FROM tb_brand WHERE id = ? 
==> Parameters: 25(Long)
Brand{id=25, name='深圳市黑馬訓練營', firstChar='S'}
2.4.3.1查詢單條記錄
/***
 * 查詢單個記錄
 */
@Test
public void testSelectOne(){
    Brand brand = new Brand();
    brand.setId(25L);
    brand.setName("深圳市黑馬訓練營");
    Brand brand1 = brandMapper.selectOne(brand);
    System.out.println(brand1);
}

日誌:

==>  Preparing: SELECT id,name,first_char FROM tb_brand WHERE id = ? AND name = ? 
==> Parameters: 25(Long), 深圳市黑馬訓練營(String)
Brand{id=25, name='深圳市黑馬訓練營', firstChar='S'}

註意:

這裡需要註意一下,複合該條件的數據,資料庫里必須<=1條,如果大於了1條數據,則會報錯

TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 3
2.4.3.2 根據條件查詢-Example
/***
 * 根據條件執行查詢
 */
@Test
public void testExample(){
    Example example = new Example(Brand.class);
    Example.Criteria criteria = example.createCriteria();
    //id IN(1,2,5,6)
    List<Long> ids = new ArrayList<Long>();
    ids.add(1L);
    ids.add(2L);
    ids.add(5L);
    ids.add(6L);

    //第二個參數是個集合對象即可,註意集合對象這裡對應的類型雖然是Object,不過要和你資料庫對應的類型保持一致
    criteria.andIn("id",ids);

    //執行查詢
    List<Brand> brands = brandMapper.selectByExample(example);

    for (Brand brand : brands) {
        System.out.println(brand);
    }
}

日誌:

==>  Preparing: SELECT id,name,first_char FROM tb_brand WHERE ( id in ( ? , ? , ? , ? ) ) 
==> Parameters: 1(Long), 2(Long), 5(Long), 6(Long)
Brand{id=1, name='聯想', firstChar='L'}
Brand{id=2, name='華為', firstChar='H'}
Brand{id=5, name='OPPO', firstChar='O'}
Brand{id=6, name='深圳市黑馬訓練營', firstChar='S'}
2.4.3.3 根據條件查詢-JavaBean
/***
 * 根據條件查詢
 * 入參:JavaBean
 */
@Test
public void testSelect(){
    Brand brand = new Brand();
    brand.setId(25L);
    brand.setName("深圳市黑馬訓練營");
    //把brand作為查詢條件,這裡會忽略空值
    List<Brand> brands = brandMapper.select(brand);
    for (Brand bd : brands) {
        System.out.println(bd);
    }
}

日誌:

==>  Preparing: SELECT id,name,first_char FROM tb_brand WHERE id = ? AND name = ? 
==> Parameters: 25(Long), 深圳市黑馬訓練營(String)
Brand{id=25, name='深圳市黑馬訓練營', firstChar='S'}
2.4.3.4 查詢所有
/***
 * 查詢所有
 */
@Test
public void testSelectAll(){
    //執行查詢
    List<Brand> brands = brandMapper.selectAll();

    for (Brand brand : brands) {
        System.out.println(brand);
    }
}

日誌:

==>  Preparing: SELECT id,name,first_char FROM tb_brand 
==> Parameters: 
Brand{id=1, name='聯想', firstChar='L'}
Brand{id=2, name='華為', firstChar='H'}
Brand{id=3, name='深圳市黑馬訓練營', firstChar='S'}
...........................................
2.4.3.5 統計查詢
/***
 * 統計查詢-總記錄數
 */
@Test
public void testSelectCount(){
    //查詢總記錄數
    int count = brandMapper.selectCount(null);
    System.out.println(count);
}

日誌:

==>  Preparing: SELECT COUNT(id) FROM tb_brand 
==> Parameters: 
25
2.4.4 刪除操作
2.4.4.1 根據主鍵刪除
/***
 * 根據ID刪除
 */
@Test
public void testDeleteByPrimaryKey(){
    long id = 25;
    int dcount = brandMapper.deleteByPrimaryKey(id);
    System.out.println(dcount);
}

日誌:

==>  Preparing: DELETE FROM tb_brand WHERE id = ? 
==> Parameters: 25(Long)
2.4.4.2 條件刪除-Example
/***
 * 條件刪除
 */
@Test
public void testDeleteByExample(){
    Example example = new Example(Brand.class);
    Example.Criteria criteria = example.createCriteria();
    //where id between 23 and 28
    criteria.andBetween("id",23L,28L);
    //根據條件刪除
    int dcount = brandMapper.deleteByExample(example);
    System.out.println(dcount);
}

日誌:

==>  Preparing: DELETE FROM tb_brand WHERE ( id between ? and ? ) 
==> Parameters: 23(Long), 28(Long)
2.4.4.3 條件刪除-JavaBean
/***
 * 條件刪除
 * 入參:javaBean
 */
@Test
public void testDelete(){
    Brand brand = new Brand();
    brand.setName("阿凡達");
    //根據條件刪除
    int dcount = brandMapper.delete(brand);
    System.out.println(dcount);
}

日誌:

==>  Preparing: DELETE FROM tb_brand WHERE name = ? 
==> Parameters: 阿凡達(String)

第3章 分頁工具

在做項目的時候,分頁屬於很常見的,但通常都有繁瑣的封裝。這裡提供了一個通用分頁插件pagehelper,能滿足我們工作中的基本需求。

3.1 配置介紹

首先需要引入對應的依賴

<!--分頁工具包-->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
</dependency>

然後需要配置一個mybatis攔截器,在pinyougou-mapper項目的mybatis.xml中加入如下插件代碼

<plugins>
    <!-- com.github.pagehelper為PageInterceptor類所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <property name="reasonable" value="true"/>
    </plugin>
</plugins>

上述配置也可以不配置在mybatis.xml中,也可以配置在spring-mybatis.xml的SqlSessionFactoryBean中,代碼如下:

<!-- SqlSessionFactoryBean -->
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="configLocation" value="classpath:mybatis/mybatis.xml" />
    <property name="typeAliasesPackage" value="com.pinyougou.model" />
    <property name="mapperLocations">
        <list>
            <value>classpath:com/pinyougou/mapper/*Mapper.xml</value>
        </list>
    </property>
    <property name="dataSource" ref="dataSource" />

    <!--分頁插件配置-->
    <property name="plugins">
        <array>
            <bean class="com.github.pagehelper.PageInterceptor">
                <!--配置分頁屬性-->
                <property name="properties">
                    <props>
                        <!--指定資料庫方言-->
                        <prop key="helperDialect">mysql</prop>
                        <!--合理化分頁操作-->
                        <prop key="reasonable">true</prop>
                    </props>
                </property>
            </bean>
        </array>
    </property>
</bean>

3.2 分頁類介紹

PageInfo類既包含我們工作中的分頁信息,也包含分頁查詢的集合對象,所以很實用,如下代碼:

public class PageInfo<T> implements Serializable {
    private static final long serialVersionUID = 1L;
    //當前頁
    private int pageNum;
    //每頁的數量
    private int pageSize;
    //當前頁的數量
    private int size;
    //當前頁面第一個元素在資料庫中的行號
    private int startRow;
    //當前頁面最後一個元素在資料庫中的行號
    private int endRow;
    //總記錄數
    private long total;
    //總頁數
    private int pages;
    //結果集
    private List<T> list;
    //前一頁
    private int prePage;
    //下一頁
    private int nextPage;
    //是否為第一頁
    private boolean isFirstPage = false;
    //是否為最後一頁
    private boolean isLastPage = false;
    //是否有前一頁
    private boolean hasPreviousPage = false;
    //是否有下一頁
    private boolean hasNextPage = false;
    //導航頁碼數
    private int navigatePages;
    //所有導航頁號
    private int[] navigatepageNums;
    //導航條上的第一頁
    private int navigateFirstPage;
    //導航條上的最後一頁
    private int navigateLastPage;
     //........略
}

3.3 分頁插件的使用

分頁插件的使用很簡單,配置好了後,直接調用PageHelper的靜態方法startPage即可實現分頁,其他查詢正常寫就行了,註意一點,調用startPage的方法必須寫在執行查詢selectAll()前面,否則分頁無效。

/**
 * 分頁測試
 */
@Test
public void testPage(){
    //page 當前頁    size 每頁顯示多少條
    int page = 1,size=10;
    //分頁處理,只需要調用PageHelper.startPage靜態方法即可。S
    PageHelper.startPage(page,size);

    //查詢
    List<Brand> brands = brandMapper.selectAll();

    //獲取分頁信息,註意這裡傳入了brands集合對象
    PageInfo<Brand> pageInfo = new PageInfo<Brand>(brands);
    System.out.println(pageInfo);
}

日誌:

==>  Preparing: SELECT count(0) FROM tb_brand 
==> Parameters: 
------------------------------------------------------------------------------------------------------------------------------------------------
==>  Preparing: SELECT id,name,first_char FROM tb_brand LIMIT ? 
==> Parameters: 10(Integer)
------------------------------------------------------------------------------------------------------------------------------------------------
PageInfo{pageNum=1, pageSize=10, size=10, startRow=1, endRow=10, total=22, pages=3, list=Page{count=true, pageNum=1, pageSize=10, startRow=0, endRow=10, total=22, pages=3, reasonable=true, pageSizeZero=false}, prePage=0, nextPage=2, isFirstPage=true, isLastPage=false, hasPreviousPage=false, hasNextPage=true, navigatePages=8, navigateFirstPage=1, navigateLastPage=3, navigatepageNums=[1, 2, 3]}

第4章 品牌列表的實現

品牌分頁實現,記得再pinyougou-sellergoods-interface中引入分頁包

<!--分頁工具包-->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
</dependency>

4.1 需求分析

實現品牌列表的查詢(不用分頁和條件查詢)效果如下:

在這裡插入圖片描述

4.2 前端代碼

4.2.1 拷貝資源

將“資源/靜態原型/運營商管理後臺”下的頁面資源拷貝到pinyougou-manager-web下

在這裡插入圖片描述

其中plugins文件夾中包括了angularJS 、bootstrap、JQuery等常用前端庫,我們將在項目中用到

4.2.2 引入JS

修改brand.html ,引入JS

<script src="/plugins/angularjs/angular.min.js"></script>

指定模塊和控制器

<body ng-app="pinyougou" ng-controller="brandController" class="hold-transition skin-red sidebar-mini">

ng-app 指令中定義的就是模塊的名稱

ng-controller 指令用於為你的應用添加控制器。

在控制器中,你可以編寫代碼,製作函數和變數,並使用 scope 對象來訪問。

4.2.3 編寫JS代碼
<script>
   /******
   * 1、引入angularjs
   * 2、發送請求
   * 3、顯示數據
   *****/

   //定義一個模塊
   var app = angular.module("pinyougou",[]);

   /*****
    * 定義一個controller
    * 發送HTTP請求從後臺獲取數據
    ****/
   app.controller("brandController",function($scope,$http){
      //創建一個方法
      //獲取所有的品牌信息
      $scope.getPage=function(page,size){
         //發送請求獲取數據
         $http.post("/brand/list.shtml?page="+page+"&size="+size).success(function(response){
            //集合數據
            $scope.list = response.list;
         });
      }
   });
</script>
4.3.4 迴圈顯示表格數據
<tbody>
<tr ng-repeat="entity in list">
   <td><input  type="checkbox" ng-model="id" ></td>
   <td>{{entity.id}}</td>
   <td>{{entity.name}}</td>
   <td>{{entity.firstChar}}</td>
   <td class="text-center">
      <button type="button" class="btn bg-olive btn-xs" data-toggle="modal" data-target="#editModal"  >修改</button>
   </td>
</tr>
</tbody>

4.3.5 初始化調用

<body ng-app="pinyougou" ng-controller="brandController" ng-init="getPage(1,10)" class="hold-transition skin-red sidebar-mini">

第5章 品牌列表分頁的實現

5.1 需求分析

在品牌管理下方放置分頁欄,實現分頁功能

在這裡插入圖片描述

5.2 後端代碼

5.2.1 服務介面層

在pinyougou-sellergoods-interface的BrandService.java 增加方法定義

/***
 * 分頁返回列表
 * @param pageNum
 * @param pageSize
 * @return
 */
public PageInfo<Brand> getAll(int pageNum, int pageSize);
5.2.2 服務實現層

在pinyougou-sellergoods-service的BrandServiceImpl.java中實現該方法y:

public PageInfo<Brand> getAll(int pageNum, int pageSize) {
    //執行分頁
    PageHelper.startPage(pageNum,pageSize);
    //List<Brand> all = brandMapper.getAllBrand();
    List<Brand> all = brandMapper.selectAll();

    PageInfo<Brand> pageInfo = new PageInfo<Brand>(all);
    return pageInfo;
}

PageHelper為MyBatis分頁插件

5.2.3 控制層

在pinyougou-manager-web工程的BrandController.java新增方法

/***
 * 分頁查詢數據
 * 獲取JSON數據
 * @return
 */
@RequestMapping(value = "/list")
public PageInfo<Brand> list(@RequestParam(value = "page", required = false, defaultValue = "1") int page,
                            @RequestParam(value = "size", required = false, defaultValue = "10") int size) {
    return brandService.getAll(page, size);
}

5.3 前端代碼控制層

5.3.1 HTML

在brand.html引入分頁組件

<!--分頁相關引入-->
<link rel="stylesheet" href="/plugins/angularjs/pagination.css">
<script src="/plugins/angularjs/pagination.js"></script>

構建app模塊時引入pagination模塊

//定義一個模塊
var app = angular.module("pinyougou",["pagination"]); //引入分頁模塊

頁面的表格下放置分頁組件

<!--分頁-->
<tm-pagination conf="paginationConf"></tm-pagination>
5.3.2 JS代碼

在brandController中添加如下代碼

/***
 * 分頁控制項配置
 * currentPage:當前頁
 * totalItems:共有多少條記錄
 * itemsPerPage:每頁顯示多少條
 * perPageOptions:每頁多少條選項條
 * onChange:參數發生變化時執行
 * */
$scope.paginationConf = {
   currentPage: 1,
   totalItems: 10,
   itemsPerPage: 10,
   perPageOptions: [10, 20, 30, 40, 50],
   onChange: function(){
      $scope.reloadList();//重新載入
   }
};
//重新載入
$scope.reloadList=function(){
   $scope.getPage($scope.paginationConf.currentPage,$scope.paginationConf.itemsPerPage);
}

在頁面的body元素上去掉ng-init指令的調用

<body ng-app="pinyougou" ng-controller="brandController" class="hold-transition skin-red sidebar-mini">
5.3.3 完整代碼
<script>
   /******
    * 步驟分析:
    * 1、引入angularjs
    * 2、發送請求
    * 3、顯示數據
    *****/
    //定義一個模塊
   var app = angular.module("pinyougou",["pagination"]);

   /*****
    * 定義一個controller
    * 發送HTTP請求從後臺獲取數據
    ****/
   app.controller("brandController",function($scope,$http){
      /***
       * 分頁控制項配置
       * currentPage:當前頁
       * totalItems:共有多少條記錄
       * itemsPerPage:每頁顯示多少條
       * perPageOptions:每頁多少條選項條
       * onChange:參數發生變化時執行
       * */
      $scope.paginationConf = {
         currentPage: 1,
         totalItems: 10,
         itemsPerPage: 10,
         perPageOptions: [10, 20, 30, 40, 50],
         onChange: function(){
            $scope.reloadList();//重新載入
         }
      };

      //創建一個方法
      //獲取所有的品牌信息
      $scope.getPage=function(page,size){
         //發送請求獲取數據
         $http.post("/brand/list.shtml?page="+page+"&size="+size).success(function(response){
            //集合數據
            $scope.list = response.list;

            //分頁數據
            $scope.paginationConf.totalItems=response.total;
         });
      }
      
      //重新載入
      $scope.reloadList=function(){
         $scope.getPage($scope.paginationConf.currentPage,$scope.paginationConf.itemsPerPage);
      }
   });
</script>
5.3.4 效果

在這裡插入圖片描述

第6章 增加品牌

6.1 需求分析

實現品牌增加功能

在這裡插入圖片描述

6.2 後端代碼

6.2.1 控制層

在pinyougou-manager-web的BrandController中增加add方法,同時相應JSON數據。

/***
 * 增加品牌數據
 * @param brand
 * 響應數據:success
 *                  true:成功  false:失敗
 *           message
 *                  響應的消息
 *
 */
@RequestMapping(value = "/add",method = RequestMethod.POST)
public Map<String,Object> add(@RequestBody Brand brand){
    //存放響應消息
    Map<String,Object> dataMap = new HashMap<String,Object>();
    
    try {
        //執行增加
        int acount = brandService.add(brand);

        if(acount>0){
            //增加成功
            dataMap.put("success",true);
            dataMap.put("message","增加品牌成功");
        }
    } catch (Exception e) {
        e.printStackTrace();
        dataMap.put("success",false);
        dataMap.put("message","增加品牌失敗");
    }
    return dataMap;
}
6.2.2 服務介面層

在pinyougou-sellergoods-interface的BrandService.java新增方法定義

/***
 * 增加品牌信息
 * @param brand
 * @return
 */
int add(Brand brand);
6.2.3 服務實現層

在com.pinyougou.sellergoods.service.impl的BrandServiceImpl.java實現該方法

@Override
public int add(Brand brand) {
    return brandMapper.insertSelective(brand);
}

6.3 前端代碼

6.3.1 js代碼
//添加品牌方法
$scope.save = function(){
   //發送Http請求,執行增加
   $http.post("/brand/add.shtml",$scope.entity).success(function(response){
      //判斷執行狀態
      if(response.success){
         //重新載入新的數據
         $scope.reloadList();
      }else{
         //列印錯誤消息
         alert(response.message);
      }
   });
}
6.3.2 html代碼

綁定表單元素,我們用ng-model指令,綁定按鈕的單擊事件我們用ng-click

<!-- 編輯視窗 -->
<div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
   <div class="modal-dialog" >
      <div class="modal-content">
         <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
            <h3 id="myModalLabel">品牌編輯</h3>
         </div>
         <div class="modal-body">
            <table class="table table-bordered table-striped"  width="800px">
               <tr>
                  <td>品牌名稱</td>
                  <td><input ng-model="entity.name" class="form-control" placeholder="品牌名稱" >  </td>
               </tr>
               <tr>
                  <td>首字母</td>
                  <td><input ng-model="entity.firstChar"  class="form-control" placeholder="首字母">  </td>
               </tr>
            </table>
         </div>
         <div class="modal-footer">
            <button ng-click="save()" class="btn btn-success" data-dismiss="modal" aria-hidden="true">保存</button>
            <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">關閉</button>
         </div>
      </div>
   </div>
</div>
6.3.3 效果

在這裡插入圖片描述

6.4 增加緩存解決

為了每次打開視窗沒有遺留上次的數據,我們可以修改新建按鈕,對entity變數進行清空操作

<button ng-click="entity={}" type="button" class="btn btn-default" title="新建" data-toggle="modal" data-target="#editModal" ><i class="fa fa-file-o"></i> 新建</button>

效果

在這裡插入圖片描述

6.5 封裝響應消息體

6.5.1 封裝介紹

響應消息體我們寫的是一個Map,每次需要用到的時候,都要重覆創建這個Map對象,並重覆給指定的key賦值,存在大量重覆代碼,而且每次key容易書寫錯,所以我們可以考慮封裝成一個實體Bean,名字叫Result,每次直接new Result()即可。

6.5.2 創建Result

由於Result可能會在很多項目中都會用到,所以我們可以考慮把它放到pinyougou-common項目中,在pinyougou-common中創建Result類

package com.pinyougou.http;
import java.io.Serializable;
public class Result implements Serializable {

    private boolean success;

    private String message;

    public Result(boolean success, String message) {
        this.success = success;
        this.message = message;
    }

    public Result(boolean success) {
        this.success = success;
    }

    public Result(String message) {
        this.message = message;
    }

    public Result() {
    }

    //get.. set.. toString..
}
6.5.3 依賴關係分析

無論是哪個項目都直接或者間接依賴了pinyougou-pojo,所以可以讓pojo依賴pinyougou-common,maven有依賴的傳遞性,則所有項目都會依賴pinyougou-common,而pinyougou-common主要用來寫一些常用的工具包,所以任何項目依賴他都合情合理。

在pinyougou-pojo的pom.xml中加入依賴

<!--依賴pinyougou-common-->
<dependency>
    <artifactId>pinyougou-common</artifactId>
    <groupId>com.pinyougou</groupId>
    <version>1.0-SNAPSHOT</version>
</dependency>
6.5.4 修改Controllerl

修改pinyougou-manager-web中的BrandController的add方法:

/***
 * 增加品牌數據
 * @param brand
 * 響應數據:success
 *                  true:成功  false:失敗
 *           message
 *                  響應的消息
 *
 */
@RequestMapping(value = "/add",method = RequestMethod.POST)
public Result add(@RequestBody Brand brand){
    try {
        //執行增加
        int acount = brandService.add(brand);

        if(acount>0){
            //增加成功
           return new Result(true,"增加品牌成功");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return new Result(false,"增加品牌失敗");
}

第7章 修改品牌

7.1 需求分析

點擊列表的修改按鈕,彈出視窗,修改數據後點“保存”執行保存操作,大概分為2個步驟。

第一:根據ID查詢出品牌數據,展示出來。

第二:根據用戶修改保存數據。

在這裡插入圖片描述

7.2 後端代碼

7.2.1 控制層

在pinyougou-manager-web的BrandController中分別加入根據id查詢和修改品牌的方法

/***
 * 修改品牌信息
 * @param brand
 * @return
 */
@RequestMapping(value = "/update",method = RequestMethod.POST)
public Result modify(@RequestBody Brand brand){
    try {
        //根據ID修改品牌信息
        int mcount = brandService.updateBrandById(brand);
        if(mcount>0){
            return new Result(true,"品牌修改成功");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return new Result(false,"品牌修改失敗");
}

/***
 * 根據ID查詢品牌信息
 * @param id
 * @return
 */
@RequestMapping(value = "/{id}",method = RequestMethod.GET)
public Brand getById(@PathVariable(value = "id")long id){
    //根據ID查詢品牌信息
    Brand brand = brandService.getOneById(id);
    return brand;
}
7.2.2 服務介面層

在pinyougou-sellergoods-interface的BrandService.java新增方法定義

/***
 * 根據ID查詢品牌信息
 * @param id
 * @return
 */
Brand getOneById(long id);

/***
 * 根據ID修改品牌信息
 * @param brand
 * @return
 */
int updateBrandById(Brand brand);
7.2.3 服務實現層

在pinyougou-sellergoods-service的BrandServiceImpl.java新增方法實現

@Override
public Brand getOneById(long id) {
    return brandMapper.selectByPrimaryKey(id);
}

@Override
public int updateBrandById(Brand brand) {
    return brandMapper.updateByPrimaryKeySelective(brand);
}

7.3 前端代碼

7.3.1 實現數據查詢

增加JS代碼;

//根據ID查詢品牌信息
$scope.getById=function(id){
   $http.get("/brand/"+id+".shtml").success(function(response){
      //將後臺的數據綁定到前臺
      $scope.entity=response;
   });
}

修改列表中的“修改”按鈕,調用此方法執行查詢實體的操作

<button ng-click="getById(entity.id)" type="button" class="btn bg-olive btn-xs" data-toggle="modal" data-target="#editModal">修改</button>
7.3.2 保存數據

修改JS的save方法

//添加或者修改品牌方法
$scope.save = function(){
   //發送Http請求,執行增加
   var url="/brand/add.shtml";
   if($scope.entity.id!=null){
      //執行修改數據
      url="/brand/update.shtml";
   }
   //執行操作
   $http.post(url,$scope.entity).success(function(response){
      //判斷執行狀態
      if(response.success){
         //重新載入新的數據
         $scope.reloadList();
      }else{
         //列印錯誤消息
         alert(response.message);
      }
   });
}

第8章 刪除品牌

8.1 需求分析

點擊列表前的覆選框,點擊刪除按鈕,刪除選中的品牌。

在這裡插入圖片描述

8.2 後端代碼

8.2.1 控制層

在BrandController中加入刪除方法

/***
 * 根據ID批量刪除
 * @param ids
 * @return
 */
@RequestMapping(value = "/delete")
public Result delete(@RequestBody List<Long> ids){
    try {
        //根據ID刪除數據
        int dcount = brandService.deleteByIds(ids);

        if(dcount>0){
            return new Result(true,"品牌刪除成功");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return new Result(false,"品牌刪除失敗");
}
8.2.2 服務介面層

在pinyougou-sellergoods-interface的BrandService.java介面定義方法

/***
 * 根據ID批量刪除品牌信息
 * @param ids
 * @return
 */
int deleteByIds(List<Long> ids);
8.2.3 服務實現層

在pinyougou-sellergoods-service的BrandServiceImpl.java實現該方法

@Override
public int deleteByIds(List<Long> ids) {
    //創建Example,來構建根據ID刪除數據
    Example example = new Example(Brand.class);
    Example.Criteria criteria = example.createCriteria();

    //所需的SQL語句類似 delete from tb_brand where id in(1,2,5,6)
    criteria.andIn("id",ids);
    return brandMapper.deleteByExample(example);
}

8.3 前端代碼

8.3.1 js

主要思路:我們需要定義一個用於存儲選中ID的數組,當我們點擊覆選框後判斷是選擇還是取消選擇,如果是選擇就加到數組中,如果是取消選擇就從數組中移除。在點擊刪除按鈕時需要用到這個存儲了ID的數組。

這裡我們補充一下JS的關於數組操作的知識

數組的push方法:向數組中添加元素

數組的splice方法:從數組的指定位置移除指定個數的元素 ,參數1為位置 ,參數2位移除的個數

覆選框的checked屬性:用於判斷是否被選中:

//定義一個變數,用於存儲要刪除的品牌ID
$scope.selectids=[];

//判斷當前點擊是否要刪除對應品牌
$scope.updateSelection=function($event,id){
   //判斷當前操作是否是選中覆選框
   if($event.target.checked){
      //如果選中覆選框,則將該id增加到數組中去
      $scope.selectids.push(id);
   }else{
      //取消刪除,則從數組中移除該id
      var idx = $scope.selectids.indexOf(id);   //獲取id對應的下標
      $scope.selectids.splice(idx, 1);//刪除對應下標的數據,1表示刪除的數量
   }
}


//批量刪除
$scope.delete=function(){
   $http.post("/brand/delete.shtml",$scope.selectids).success(function(response){
      //判斷刪除狀態
      if(response.success){
         $scope.reloadList();
      }else{
         alert(response.message);
      }
   });
}
8.3.2 HTML

修改列表的覆選框

<input  type="checkbox" ng-click="updateSelection($event,entity.id)" >

修改刪除按鈕

<button ng-click="delete()" type="button" class="btn btn-default" title="刪除" ><i class="fa fa-trash-o"></i> 刪除</button>

第9章 品牌條件查詢

9.1 需求分析

實現品牌條件查詢功能,輸入品牌名稱、首字母後查詢,並分頁。

9.2 後端代碼

9.2.1 控制層

修改BrandController裡面的list方法

/***
 * 分頁查詢數據
 * 獲取JSON數據
 * @return
 */
@RequestMapping(value = "/list")
public PageInfo<Brand> list(@RequestBody Brand brand,@RequestParam(value = "page", required = false, defaultValue = "1") int page,
                            @RequestParam(value = "size", required = false, defaultValue = "10") int size) {
    return brandService.getAll(brand,page, size);
}
9.2.2 服務介面層

在pinyougou-sellergoods-interface工程的BrandService.java方法增加方法定義

/***
 * 分頁返回列表
 * @param pageNum
 * @param pageSize
 * @return
 */
public PageInfo<Brand> getAll(Brand brand,int pageNum, int pageSize);
9.2.3 服務實現層

在pinyougou-sellergoods-service工程BrandServiceImpl.java實現該方法

public PageInfo<Brand> getAll(Brand brand,int pageNum, int pageSize) {
    //執行分頁
    PageHelper.startPage(pageNum,pageSize);

    //條件查詢
    Example example = new Example(Brand.class);
    Example.Criteria criteria = example.createCriteria();

    if(brand!=null){
        //名字模糊搜索
        if(StringUtils.isNotBlank(brand.getName())){
            criteria.andLike("name","%"+brand.getName()+"%");
        }

        //首字母搜索
        if(StringUtils.isNotBlank(brand.getFirstChar())){
            criteria.andEqualTo("firstChar",brand.getFirstChar());
        }
    }
    //執行查詢
    List<Brand> all = brandMapper.selectByExample(example);
    PageInfo<Brand> pageInfo = new PageInfo<Brand>(all);


    //======================================================================
    //List<Brand> all = brandMapper.getAllBrand();
    /*List<Brand> all = brandMapper.selectAll();

    PageInfo<Brand> pageInfo = new PageInfo<Brand>(all);*/
    return pageInfo;
}

9.3 前端代碼

修改pinyougou-manager-web的brand.html

9.3.1 增加搜索塊

增加搜索代碼塊,並綁定一個搜索對象。同時增加點擊事件,調用搜索方法。

<div class="has-feedback">
   品牌名稱:<input ng-model="searchEntity.name">
   品牌首字母:<input ng-model="searchEntity.firstChar">
   <button ng-click="getPage(1,10)" class="btn btn-default">查詢</button>
</div>
9.3.2 js

定義一個搜索對象,和搜索條件那裡保持一致,並修改原來搜索方法。

//條件查詢對象定義
$scope.searchEntity={};

//獲取所有的品牌信息
$scope.getPage=function(page,size){
   //發送請求獲取數據
   $http.post("/brand/list.shtml?page="+page+"&size="+size,$scope.searchEntity).success(function(response){
      //集合數據
      $scope.list = response.list;

      //分頁數據
      $scope.paginationConf.totalItems=response.total;
   });
}
9.3.3 效果

在這裡插入圖片描述
第二天需要的資料文件


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 2d x y 3d x y z 左手坐標系 伸出左手,讓拇指和食指成“L”形,大拇指向右,食指向上,中指指向前方。這樣我們就建立了一個左手坐標系,拇指、食指和中指分別代表X、Y、Z軸的正方向。如下圖 CSS3中的3D坐標系與上述的3D坐標系是有一定區別的,相當於其繞著X軸旋轉了180度,如下圖 簡單 ...
  • 現在很多網站會用到進入網站特效,到網頁沒有載入完成的時候,會有一個loding特效,載入完了之後才能看到頁面,今天就帶著做一個js進度條效果,今天要做的效果是純js進度條載入,沒有用到框架,方便大家進行深入理解: 首先我們要進行js進度條的佈局 js進度條佈局如下: 1234567891011121 ...
  • 網路請求編碼表示會從你是否關註Request head的哪些內容入手,一般關註點放在statusCode和method上就夠用,重點200,304。同時掌握了基礎後希望註意的點為文件上傳的內容(百度問過斷點續傳的實現) 200: ‘伺服器成功返回請求的數據。’,201: ‘新建或修改數據成功。’,2 ...
  • 一.起因 我在做爬蟲的時候發現很多網站上都在url上加一個 一開始我以為是啥加密後面發現其實他在後臺解析的時候也不需要 ,那他加個隨機數是做啥子 二.查看文獻得到總結 常用修改url方式 ...
  • transform是CSS3中具有顛覆性的特征之一,可以實現元素的位移、旋轉、傾斜、縮放,甚至支持矩陣方式,配合過渡和即將學習的動畫知識,可以取代大量之前只能靠Flash才可以實現的效果。 變形轉換 transform transform 變換 變形的意思 《 transformers 變形金剛》 ...
  • 對於DevOps的理解大家眾說紛紜,就連維基百科(Wikipedia)都沒有給出一個統一的定義。一般的解釋都是從字面上來理解,就是把開發(Development)和運維(Operations)整合到一起,來加速產品從啟動到上線的過程,並使之自動化。這個是對DevOps的廣義解釋,而且大多數人都是認可 ...
  • 例6 數字反轉 題目描述 給定一個整數,請將該數各個位上數字反轉得到一個新數。新數也應滿足整數的常見形式,即除非給定的原數為零,否則反轉後得到的新數的最高位數字不應為零(參見樣例2)。 輸入格式 一個整數 N 輸出格式 一個整數,表示反轉後的新數。 輸入樣例 #1 123 輸出樣例 #1 321 輸 ...
  • 例5 分解質因數 題目描述 將一個正整數分解質因數。例如:輸入90,輸出 90=2*3*3*5。 輸入 輸入數據包含多行,每行是一個正整數n (1<n <100000) 。 輸出 對於每個整數n將其分解質因數。 輸入樣例 90 256 199 輸出樣例 90=2*3*3*5 256=2*2*2*2* ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...