科技美学

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

1. Spring Initializr

Spring-boot脚手架

 

2. 项目结构

<package>java.com.kenny.ai desciption
config  配置类
controller  控制器
entity  实体类
intercept  拦截器
mapper  MyBatis映射类
service  服务类
utils  工具类

 

 

 

 

 

 

 

 

 

 

 

<package> resources desciption
mapper  MyBatis XML映射类
static  js, css, images
templates  thymeleaf模板
application.properties  springboot xml配置
jdbc.properties  mysql 配置
schema.sql  sql 初始化

 

 

 

 

 

 

 

 

 

 

3. Starter

    <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
</dependencies>
<pom.xml> starter desciption
spring-boot-starter-web  Spring框架
spring-boot-starter-test  /
spring-boot-starter-thymeleaf  渲染模板
mysql-connector-java  mysql
mybatis-spring-boot-starter  mybatis持久层

 

 

 

 

 

 

 

 

 

4. xml配置

 AiApplication.java

package com.kenny.ai;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;

@SpringBootApplication
@ComponentScan(basePackages = {"com.kenny.ai.*"})
@MapperScan(basePackages = {"com.kenny.ai.mapper"})
@PropertySource(value={"classpath:jdbc.properties"}, ignoreResourceNotFound=true)
public class AiApplication {
    public static void main(String[] args) {
        SpringApplication.run(AiApplication.class, args);
    }
}
Label Description
@SpringBootApplication Spring框架
@ComponentScan 扫描根目录
@MapperScan Mybatis映射层
@PropertySource 数据库xml配置

 

 

 

 

 

 

 

application.properties

server.port=8080
mybatis.mapper-locations=classpath:mapper/*.xml

jdbc.properties

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/spring_boot?useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=user002
spring.datasource.password=123456
spring.datasource.sql-script-encoding=utf-8
spring.datasource.initialization-mode=always
  1. 项目端囗配置
  2. mybatis映射xml
  3. mysql配置

重点:mysql必须有useUnicode=true&characterEncoding=UTF-8,否则会编码错误

 

 

5. mybatis持久层

spring.datasource.initialization-mode=always,这句会自动扫描resources/schema.sql。

5.1 schema.sql

DROP TABLE IF EXISTS `stock`;
CREATE TABLE stock
(
  id        INT PRIMARY KEY auto_increment,
  ucode     VARCHAR(256) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  uname_tc  VARCHAR(512) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  uname_en  VARCHAR(512) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 DEFAULT COLLATE utf8_general_ci;
INSERT INTO `stock`(`id`,`ucode`,`uname_tc`,`uname_en`) values
(1,'0700','騰訊控股','Tencent Holdings Ltd.'),
(2,'1810','小米集團','Xiaomi Singapore Pte. Ltd.'),
(3,'3690','美團','Meituan Corp'),
(4,'9988','阿里巴巴','Alibaba Group'),
(5,'2800','盈富基金','Tracker Fund of Hong Kong'),
(6,'3033','南方東英恒生科技指數ETF','CSOP Hang Seng TECH Index ETF HKD');

5.2 java.com.kenny.ai.entity.Stock.java 实体类

package com.kenny.ai.entity;

import org.springframework.stereotype.Component;

@Component("stock")
public class Stock {
    private Long id;
    private String ucode;
    private String uname_tc;
    private String uname_en;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUcode() {
        return ucode;
    }

    public void setUcode(String ucode) {
        this.ucode = ucode;
    }

    public String getUname_tc() {
        return uname_tc;
    }

    public void setUname_tc(String uname_tc) {
        this.uname_tc = uname_tc;
    }

    public String getUname_en() {
        return uname_en;
    }

    public void setUname_en(String uname_en) {
        this.uname_en = uname_en;
    }

    @Override
    public String toString() {
        return "Stock{" +
                "id=" + id +
                ", ucode='" + ucode + '\'' +
                ", uname_tc='" + uname_tc + '\'' +
                ", uname_en='" + uname_en + '\'' +
                '}';
    }
}

5.3 java.com.kenny.ai.mapper.StockMapper.java

mapper映射层,注入Stock实体类。实现增删改查。

package com.kenny.ai.mapper;

import com.kenny.ai.entity.Stock;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Component;

import java.util.List;

@Mapper
@Component
public interface StockMapper {

    /***
     * 查詢所有正股
     * @return 正股列表
     */
    @Select({"select id, ucode, uname_tc, uname_en from stock"})
    List<Stock> listAll();

    /***
     * 根據ucode查詢正股
     * @param ucode 正股編號
     * @return 当前ucode的正股,不存在则是 {@code null}
     */
    @Select({"SELECT id, ucode, uname_tc, uname_en from stock WHERE ucode = #{ucode}"})
    Stock findByUcode(@Param("ucode") String ucode);

    /***
     * 保存正股
     * @param stock 正股
     * @return 成功 - {@code 1} 失败 - {@code 0}
     */
    int saveStock(@Param("stock") Stock stock);

    /***
     * 更新正股
     * @param stock 正股
     * @return 成功 - {@code 1} 失败 - {@code 0}
     */
    int updateStock(@Param("stock") Stock stock);

    /***
     * 删除正股
     * @param ucode 正股編號
     * @return 成功 - {@code 1} 失败 - {@code 0}
     */
    int deleteByUcode(@Param("ucode") String ucode);
}

5.4 resources.mapper.StockMapper.xml 

mapper映射层的xml配置。配置了较复杂的sql stmt。

重点:路径在application.properties配置。

<?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.kenny.ai.mapper.StockMapper">

    <insert id="saveStock">
        INSERT INTO `stock` (`ucode`, `uname_tc`, `uname_en`)
        VALUES (#{stock.ucode}, #{stock.uname_tc}, #{stock.uname_en})
    </insert>

    <update id="updateStock">
        UPDATE `stock` SET uname_tc=#{stock.uname_tc}, uname_en=#{stock.uname_en} WHERE ucode=#{stock.ucode}
    </update>

    <delete id="deleteByUcode">
        DELETE
        FROM `stock`
        WHERE `ucode` = #{ucode}
    </delete>

</mapper>

 

 

6. Controller控制器

注入Stock实体类 和 StockMapper映射类。因业务简单,所以暂时地不用Service层。

默认使用thymeleaf模板渲染。

6.1 com.kenny.ai.controller.StockController.java

package com.kenny.ai.controller;

import com.kenny.ai.entity.Stock;
import com.kenny.ai.mapper.StockMapper;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class StockController {
    @Autowired
    private final StockMapper stockMapper;

    public StockController(StockMapper stockMapper) {
        this.stockMapper = stockMapper;
    }

    @RequestMapping(value={"/", "/index", "/home", "/uat/v2/home"})
    public String index(Model model) {
        model.addAttribute("stocks", this.stockMapper.listAll());
        return "stock/stock";
    }

    @RequestMapping({"stock/delete/{ucode}", "uat/v2/stock/delete/{ucode}"})
    public String deleteStock(@PathVariable String ucode) {
        stockMapper.deleteByUcode(ucode);
        return "redirect:/home";
    }

    @RequestMapping({"stock/save", "uat/v2/stock/save"})
    public String stockSave(Stock stock) {
       stockMapper.saveStock(stock);
       return "redirect:/home";
    }

    @RequestMapping({"stock/update", "uat/v2/stock/update"})
    public String stockUpdate(Stock stock) {
        stockMapper.updateStock(stock);
        return "redirect:/home";
    }
}

 

 

7. Thymeleaf模板

7.1 webapp结构

 spring-boot强烈推荐thymeleaf完全取代jsp,那就试用thymeleaf吧。

 

7.2 最终效果

 

7.3 resources/templates/fragments/header.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="common_header(title)">
    <title th:replace="${title}"></title>
    <meta charset="utf-8"></meta>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"></meta>
    <script th:src="@{/js/jquery.min.js}" type="text/javascript"></script>
    <script th:src="@{/js/bootstrap.min.js}" type="text/javascript"></script>
    <link th:href="@{/css/bootstrap.min.css}" rel="stylesheet" />
    <link th:href="@{/css/kuang-style.css}" rel="stylesheet" />
    <link th:href="@{/css/style.css}" rel="stylesheet" />
</head>

th:fragment="common_header(title)"

fragment名称:common_header

注入叁数:title

重点:@{/} 指向根目录。

<head th:replace="fragments/header :: common_header(~{::title})">

 

7.4 resources/templates/stock/stock.html

7.4.1 渲染表格

<tr th:if="${stocks==null or stocks.isEmpty()}">
    <td colspan="4"> 沒有合適的正股 </td>
</tr>
<tr th:each="stock : ${stocks}">
    <form th:action="@{/stock/update}" method="post">
        <td><span th:text="${stock.ucode}"> </span></td>
        <td><input type="text" class="form-control" name="uname_tc" th:value="${stock.uname_tc}"> </input></td>
        <td><input type="text" class="form-control" name="uname_en" th:value="${stock.uname_en}"> </input></td>
        <td>
            <button type="submit" class="btn btn-sm btn-primary btn-update">更新</button>
            <input type="hidden" class="form-control" name="ucode" th:value="${stock.ucode}"> </input>
            <button type="button" th:href="@{'/stock/delete/'+${stock.ucode}}"  class="btn btn-sm btn-danger btn-delete">刪除</button>
        </td>
    </form>
</tr>

7.4.2 新增数据

name=ucode
name=uname_tc
name=uname_en

会自动映射至Stock实体,并经StockMapper映射,进行数据库事务。

<form th:action="@{/stock/save}" method="post">
    <div class="form-row">
        <div class="form-group col-12 col-md-4">
            <label for="ucode">正股</label>
            <input type="text" class="form-control" id="ucode" name="ucode" placeholder="0700" required />
        </div>
        <div class="form-group col-12 col-md-4">
            <label for="uname_tc">中文</label>
            <input type="text" class="form-control" id="uname_tc" name="uname_tc" placeholder="騰訊控股" required />
        </div>
        <div class="form-group col-12 col-md-4">
            <label for="uname_en">英文</label>
            <input type="text" class="form-control" id="uname_en" name="uname_en" placeholder="Tencent Holdings Ltd." required />
        </div>
        <button type="submit" class="btn btn-sm btn-primary" id="submit">Submit</button>
    </div>
</form>

 

posted on 2021-01-25 22:09  chankuang  阅读(573)  评论(1编辑  收藏  举报