當前位置:
首頁 > 知識 > 電商門戶網站商品品類多級聯動SpringBoot+Thymeleaf實現

電商門戶網站商品品類多級聯動SpringBoot+Thymeleaf實現

在淘寶、京東等電商網站,其門戶網站都有一個商品品類的多級聯動,滑鼠移動,就顯示,因為前端不是我做的,所以不說明前端實現,只介紹後端實現。

電商門戶網站商品品類多級聯動SpringBoot+Thymeleaf實現

打開今日頭條,查看更多精彩圖片

實現的效果如圖:可以說是3級聯動

搭建部署SpringBoot環境

配置文件配置:

開啟了對Thymeleaf模塊引擎的支持

server:

port: 8081

#logging:

# config: classpath:logback_spring.xml

# level:

# com.muses.taoshop: debug

# path: /data/logs

spring:

datasource:

# 主數據源

shop:

url: jdbc:mysql://127.0.0.1:3306/taoshop?autoReconnect=true&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&useSSL=false

username: root

password: root

driver-class-name: com.mysql.jdbc.Driver

type: com.alibaba.druid.pool.DruidDataSource

# 連接池設置

druid:

initial-size: 5

min-idle: 5

max-active: 20

# 配置獲取連接等待超時的時間

max-wait: 60000

# 配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒

time-between-eviction-runs-millis: 60000

# 配置一個連接在池中最小生存的時間,單位是毫秒

min-evictable-idle-time-millis: 300000

# Oracle請使用select 1 from dual

validation-query: SELECT "x"

test-while-idle: true

test-on-borrow: false

test-on-return: false

# 打開PSCache,並且指定每個連接上PSCache的大小

pool-prepared-statements: true

max-pool-prepared-statement-per-connection-size: 20

# 配置監控統計攔截的filters,去掉後監控界面sql無法統計,"wall"用於防火牆

filters: stat,wall,slf4j

# 通過connectProperties屬性來打開mergeSql功能;慢SQL記錄

connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

# 合併多個DruidDataSource的監控數據

use-global-data-source-stat: true

# jpa:

# database: mysql

# hibernate:

# show_sql: true

# format_sql: true

# ddl-auto: none

# naming:

# physical-strategy: org.hibernate.boot.entity.naming.PhysicalNamingStrategyStandardImpl

# mvc:

# view:

# prefix: /WEB-INF/jsp/

# suffix: .jsp

#添加Thymeleaf配置

thymeleaf:

cache: false

prefix: classpath:/templates/

suffix: .html

mode: HTML5

encoding: UTF-8

content-type: text/html

#Jedis配置

# jedis :

# pool :

# host : 127.0.0.1

# port : 6379

# password : redispassword

# timeout : 0

# config :

# maxTotal : 100

# maxIdle : 10

# maxWaitMillis : 100000

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

SpringBoot啟動類:

package com.muses.taoshop;

import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration;

import org.springframework.boot.*;

import org.springframework.boot.autoconfigure.*;

import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;

import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;

import org.springframework.boot.web.servlet.ServletComponentScan;

import org.springframework.cache.annotation.EnableCaching;

import org.springframework.scheduling.annotation.EnableAsync;

import org.springframework.scheduling.annotation.EnableScheduling;

import org.springframework.stereotype.*;

import org.springframework.transaction.annotation.EnableTransactionManagement;

import org.springframework.web.bind.annotation.*;

/**

*

* <pre>

* SpringBoot啟動配置類

* </pre>

* @author nicky

* @version 1.00.00

* <pre>

* 修改記錄

* 修改後版本: 修改人: 修改日期: 修改內容:

* </pre>

*/

@Controller

@EnableScheduling//開啟對計劃任務的支持

@EnableTransactionManagement//開啟對事務管理配置的支持

@EnableCaching

@EnableAsync//開啟對非同步方法的支持

@EnableAutoConfiguration

@ServletComponentScan

@SpringBootApplication(exclude={DataSourceAutoConfiguration.class,

MybatisAutoConfiguration.class,

DataSourceTransactionManagerAutoConfiguration.class})

public class PortalApplication {

@RequestMapping("/")

@ResponseBody

String home() {

return "portal web!";

}

@RequestMapping("/doTest")

@ResponseBody

String doTest(){

System.out.println(Thread.currentThread().getName());

String threadName = Thread.currentThread().getName();

return threadName;

}

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

SpringApplication.run(PortalApplication.class, args);

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

寫個Controller類跳轉到門戶網站:

ps:品類多級聯動思路其實就是先構建一個樹,我這裡的做法就是先查詢處理,然後通過工具類,進行遞歸遍歷,待會給出工具類代碼,僅供參考。listCategory方法其實就是獲取所有的品類信息

package com.muses.taoshop.web.controller.portal;

import com.alibaba.fastjson.JSON;

import com.muses.taoshop.item.entity.ItemBrand;

import com.muses.taoshop.item.entity.ItemCategory;

import com.muses.taoshop.item.entity.ItemPortal;

import com.muses.taoshop.item.service.IItemBrankService;

import com.muses.taoshop.item.service.IItemCategoryService;

import com.muses.taoshop.item.service.IItemService;

import com.muses.taoshop.util.CategoryTreeUtils;

import com.muses.taoshop.web.controller.BaseController;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.util.CollectionUtils;

import org.springframework.web.bind.annotation.*;

import org.springframework.web.servlet.ModelAndView;

import java.util.Date;

import java.util.List;

/**

* <pre>

* 門戶網站控制類

* </pre>

*

* @author nicky

* @version 1.00.00

* <pre>

* 修改記錄

* 修改後版本: 修改人: 修改日期: 修改內容:

* </pre>

*/

@Controller

@RequestMapping("/portal")

public class IndexController extends BaseController{

@Autowired

IItemService iItemService;

@Autowired

IItemBrankService iItemBrankService;

@Autowired

IItemCategoryService iItemCategoryService;

/**

* 跳轉到門戶網站

* @return

*/

@GetMapping(value = "/toIndex.do")

public ModelAndView toIndex(){

info("跳轉到門戶網站");

ModelAndView mv = this.getModelAndView();

mv.setViewName("index");

List<ItemPortal> items = iItemService.listItemPortal();

CategoryTreeUtils treeUtil = new CategoryTreeUtils();

List<ItemCategory> list = iItemCategoryService.listCategory();

List<ItemCategory> categories = treeUtil.buildCategoryTree(list);

mv.addObject("items" , items);

mv.addObject("categories" , categories);

return mv;

}

@GetMapping(value = "/doTest")

@ResponseBody

public String doTest(){

List<ItemBrand> itemBrands = iItemBrankService.listItemBrand();

String str = JSON.toJSON(itemBrands).toString();

return str;

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

業務介面類:

package com.muses.taoshop.item.service;

import com.muses.taoshop.item.entity.ItemCategory;

import com.muses.taoshop.item.entity.ItemList;

import java.util.List;

/**

* <pre>

* 商品品類信息介面

* </pre>

*

* @author nicky

* @version 1.00.00

* <pre>

* 修改記錄

* 修改後版本: 修改人: 修改日期: 2018.06.17 10:59 修改內容:

* </pre>

*/

public interface IItemCategoryService {

/**

* 查詢所有商品品類信息

* @return

*/

List<ItemCategory> listCategory();

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

業務服務實現類:

package com.muses.taoshop.item.service;

import com.muses.taoshop.item.entity.ItemCategory;

import com.muses.taoshop.item.entity.ItemList;

import com.muses.taoshop.item.mapper.ItemCategoryMapper;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import java.util.List;

/**

* <pre>

* 商品品類信息服務實現類

* </pre>

*

* @author nicky

* @version 1.00.00

* <pre>

* 修改記錄

* 修改後版本: 修改人: 修改日期: 2018.06.17 11:01 修改內容:

* </pre>

*/

@Service

public class ItemCategoryServiceImpl implements IItemCategoryService{

@Autowired

ItemCategoryMapper itemCategoryMapper;

/**

* 查詢所有的商品品類信息

* @return

*/

@Override

public List<ItemCategory> listCategory() {

return itemCategoryMapper.listCategory();

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

Mybatis相關代碼:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >

<mapper namespace="com.muses.taoshop.item.mapper.ItemCategoryMapper" >

<resultMap id="BaseResultMap" type="com.muses.taoshop.item.entity.ItemCategory" >

<id column="id" property="id" jdbcType="BIGINT" />

<result column="category_name" property="categoryName" jdbcType="VARCHAR" />

<result column="sjid" property="sjid" jdbcType="BIGINT" />

<result column="last_modify_time" property="lastModifyTime" jdbcType="TIMESTAMP" />

<result column="create_time" property="createTime" jdbcType="TIMESTAMP" />

</resultMap>

<sql id="BaseColumnList" >

id,

category_name as categoryName,

sjid,

last_modify_time as lastModifyTime,

create_time as createTime

</sql>

<!-- 獲取所有的商品品類信息-->

<select id="listCategory" resultType="ItemCategory">

SELECT

<include refid="BaseColumnList" />

FROM item_category t

</select>

</mapper>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

Mapper介面類:

package com.muses.taoshop.item.mapper;

import com.muses.taoshop.item.entity.ItemCategory;

import com.muses.taoshop.item.entity.ItemList;

import org.apache.ibatis.annotations.Mapper;

import org.apache.ibatis.annotations.Param;

import java.util.List;

@Mapper

public interface ItemCategoryMapper {

List<ItemCategory> listCategory();

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

實體類:

這裡用了lombok的jar來實現,所有不用set和get方法

package com.muses.taoshop.item.entity;

import com.alibaba.fastjson.annotation.JSONField;

import com.fasterxml.jackson.annotation.JsonFormat;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import lombok.Data;

import org.springframework.format.annotation.DateTimeFormat;

import javax.validation.constraints.NotNull;

import java.util.Date;

import java.util.List;

/**

* <pre>

* 商品品類

* </pre>

* @author nicky

* @version 1.00.00

* <pre>

* 修改記錄

* 修改後版本: 修改人: 修改日期: 2018.06.09 21:49 修改內容:

* </pre>

*/

@Data

public class ItemCategory {

/**

* 商品品類id

*/

private Long id;

/**

* 商品品類名稱

*/

private String categoryName;

/**

* 上級id

*/

private Long sjid;

/**

* 上次修改時間

*/

@JSONField(format ="yyyy-MM-dd HH:mm:ss")

private Date lastModifyTime;

/**

* 創建時間

*/

@JSONField(format ="yyyy-MM-dd HH:mm:ss")

private Date createTime;

/**

* 子菜單

*/

private List<ItemCategory> subCategorys;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

構建品類樹的工具類:

package com.muses.taoshop.util;

import com.muses.taoshop.item.entity.ItemCategory;

import javax.mail.FetchProfile;

import java.util.ArrayList;

import java.util.List;

/**

* <pre>

* 構造一棵品類樹

* </pre>

*

* @author nicky

* @version 1.00.00

* <pre>

* 修改記錄

* 修改後版本: 修改人: 修改日期: 2018.06.24 17:12 修改內容:

* </pre>

*/

public class CategoryTreeUtils {

public List<ItemCategory> commonCategorys;

public List<ItemCategory> list = new ArrayList<ItemCategory>();

public List<ItemCategory> buildCategoryTree(List<ItemCategory> categories ) {

this.commonCategorys = categories;

for (ItemCategory c : categories){

ItemCategory category = new ItemCategory();

if(c.getSjid() == 0){

category.setSjid(c.getSjid());

category.setId(c.getId());

category.setCategoryName(c.getCategoryName());

category.setSubCategorys(treeChild(c.getId()));

list.add(category);

}

}

return list;

}

public List<ItemCategory> treeChild(long id){

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

for(ItemCategory c : commonCategorys){

ItemCategory category = new ItemCategory();

if(c.getSjid() == id){

category.setSjid(c.getSjid());

category.setId(c.getId());

category.setCategoryName(c.getCategoryName());

category.setSubCategorys(treeChild(c.getId()));//遞歸循環

list.add(category);

}

}

return list;

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

前端代碼:

<div class="headerNav" xmlns:th="http://www.thymeleaf.org">

<div class="layout">

<dl class="all-brands">

<dt class="all-brands-head"> <a href="#">全部商品分類</a> </dt>

<dd class="all-brands-list">

<div class="wrap" th:each="c : ${categories}">

<div class="all-sort-list">

<div class="item bo">

<h3>

<a href="" th:text="${c.categoryName}"></a></h3>

<div class="item-list clearfix">

<div class="close">x</div>

<div class="subitem" th:each="s: ${c.subCategorys}">

<dl class="fore1">

<dt th:text="${s.categoryName}"><a th:href="@{"/portal/category/toCategoryList/"+${s.id}}"></a></dt>

<dd>

<em th:each="ss : ${s.subCategorys} "><a th:href="@{"/portal/category/toCategoryList/"+${ss.id}}" th:text="${ss.categoryName}"></a></em>

</dd>

</dl>

</div>

</div>

</div>

</div>

</div>

</dd>

</dl>

</div>

</div>

</div>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

這是在開發中的開源項目的一個小功能,源碼已經開源

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序員小新人學習 的精彩文章:

vue-cli的工程模板與構建工具
MySQL8.0設置遠程訪問許可權

TAG:程序員小新人學習 |