Springboot小例子

文章目录

1 SpringBoot小例子练习

1.1 新建项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.2 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>testspringboot</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>testspringboot</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.0</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

1.3 application.yml

若项目无数据库,不必加次配置
将application.properties改名为application.yml,添加spring配置项:

spring:
  datasource:
    name: lzhtest
    url: jdbc:mysql://localhost:3306/lzhtest?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver

若使用连接池

spring:
  datasource:  #127.0.0.1:3306
    url: jdbc:mysql://127.0.0.1:3306/wyf?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
    username: root
    password: ys_20220826
    driver-class-name: com.mysql.cj.jdbc.Driver
  type: com.zaxxer.hikari.HikariDataSource
  hikari:
    ## 最小空闲连接数量
    minimum-idle: 5
    ## 空闲连接存活最大时间,默认600000(10分钟)
    idle-timeout: 180000
    ## 连接池最大连接数,默认是10
    maximum-pool-size: 500
    ## 此属性控制从池返回的连接的默认自动提交行为,默认值:true
    auto-commit: true
    ## 连接池母子
    pool-name: MyHikariCP
    ## 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟
    max-lifetime: 1800000
    ## 数据库连接超时时间,默认30秒,即30000
    connection-timeout: 30000
    connection-test-query: SELECT 1

1.4 index.html

在resources下新建templates文件夹,创建index.html页面

1.5 testController.java

新建controller文件夹,创建testController

@Controller
public class testController {

    @RequestMapping("/testSpringBoot")
    public String testSpringBoot(){
       return "index";
    }
}

运行地址:http://localhost:8080/testSpringBoot

2 SpringBoot带数据库例子—select

2.1 配置database

在这里插入图片描述

2.2 配置application.yml

若不使用mybatis,不必加此配置

mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.example.testspringboot.bean

2.3 创建PersonBean类

新建bean文件夹,创建PersonBean,生成Getter、Setter、toString函数

2.4 创建PersonMapper接口

新建mapper文件夹,创建PersonMapper接口,定义函数接口

@Mapper
public interface PersonMapper {
    List personList();
}

注意:添加@Mapper注解,接口中的函数名与映射文件中id保持一致

2.5 创建PersonMapper映射文件

在resources下新建mapper文件夹,创建PersonMapper.xml

<?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.example.testspringboot.mapper.PersonMapper">

    <select id="personList"  resultType="com.example.testspringboot.bean.PersonBean">
        SELECT * FROM person
    </select>

</mapper>

2.6 创建PersonService接口

新建service文件夹,创建PersonService接口,定义函数接口

public interface PersonService {
    List getPersons();
}

2.7 创建PersonService接口实现类

在service文件夹下创建impl文件夹,创建PersonServiceImpl类,实现接口函数

@Service
public class PersonServiceImpl implements PersonService {

    @Autowired
    private PersonMapper personMapper;

    @Override
    public List getPersons() {
        return personMapper.personList();
    }
}

注意:添加@Service、@Autowired注解

2.8 创建PersonController类

新建controller文件夹,创建PersonController类

@Controller
public class PersonController {

    @Autowired
    PersonService personService;

    @RequestMapping("/testSpringBoot")
    public String testSpringBoot(){
        System.out.println("hhh....");
        List ps = personService.getPersons();
        for(int i = 0; i < ps.size(); i++){
            PersonBean p = (PersonBean) ps.get(i);
            System.out.println(p.toString());
        }
        return "index";
    }
}

注意:添加@Controller、@RequestMapping(“/testSpringBoot”)注解

3 controller和html交互例子—select

resources.templates文件夹下:index.html和showPersonsHtml.html
controller文件下:testSpringBoot和PersonController

testSpringBoot:

@Controller
public class testSpringBoot {

    @RequestMapping("/test")
    public String test(){
        System.out.println("lzh test controller");
        return "index";
    }
}

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Hello LZH</title>
</head>
<body>
    <h1>Hello LZH, Welcome to SpringBoot!!!</h1>
    <form role="formhtml" action = "/testHtml" method="post">
        id:<input type="text" id="idperson" name = "idperson"> <br>
        name:<input type="text" id = "name" name = "name"> <br>
        <input type="submit" id = "login" value = "测试登录html">
    </form>

</body>
</html>

from表单中input的name必须与controller中函数的形参名一致

PersonController:

@Controller
public class PersonController {

    @Autowired
    PersonService personService;

    @RequestMapping(value = "/testHtml", method = RequestMethod.POST)
    public String testSpringBootHtml(int idperson, String name, Model model){
        System.out.println(idperson + name + "...in html");
        List ps = personService.getPersons();
        for(int i = 0; i < ps.size(); i++){
            PersonBean p = (PersonBean) ps.get(i);
            System.out.println(p.toString());
        }
        model.addAttribute("persons", ps);
        return "showPersonsHtml";
    }
}

showPersonsHtml.html:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Show Persons</title>
</head>
<body>
    <h1>Show PERSONS In Html</h1>
    <tr th:each="p : ${persons}">
        <td>
            <p th:text="'name: ' + ${p.getName()}" >...</p>
        </td>
    </tr>
</body>
</html>

浏览器地址:http://localhost:8080/test

4 增删改查

4.1 insert

form表单action的值与cntroller中RequestMapping中的value值一致
form表单中input的name值与controller中函数形参名一致
Mapper接口中函数名与mapper映射文件中id值一致

form表单:

<h1>增删改查输入</h1>
<form role="formInsert" action="/testInsert" method="post">
    id:<input type="number" id="insert_id0" name = "insert_id"> <br>
    name:<input type="text" id = "insert_name0" name = "insert_name"> <br>
    sex:<input type="text" id="insert_sex0" name = "insert_sex"> <br>
    age:<input type="number" id = "insert_age0" name = "insert_age"> <br>
    <input type="submit" id = "insert_login" value = "insert测试">
</form>

PersonMapper.java:

@Mapper
public interface PersonMapper {
    void insertPerson(int id, String name, String sex, int age);
}

mapper映射文件:

<insert id="insertPerson" parameterType="com.example.testspringboot.bean.PersonBean">
    insert into person(idperson,name,sex,age) values(#{id},#{name},#{sex},#{age})
</insert>

PersonService接口:

public interface PersonService {
    void insertPerson(int id, String name, String sex, int age);
}

接口实现类:

@Service
public class PersonServiceImpl implements PersonService {

    @Autowired
    private PersonMapper personMapper;


    @Override
    public void insertPerson(int id, String name, String sex, int age) {
        personMapper.insertPerson(id, name, sex, age);
    }
}

PersonController中的反应函数:

@RequestMapping(value = "/testInsert", method = RequestMethod.POST)
public String insertCon(int insert_id, String insert_name, String insert_sex, int insert_age){
    System.out.println(insert_id + insert_name + insert_sex + insert_age);
    personService.insertPerson(insert_id,insert_name,insert_sex,insert_age);
    return "index";
}

4.2 delete

form表单:

<form role="formDelete" action="/testDelete" method="post">
    id:<input type="number" id="delete_id0" name = "delete_id"> <br>
    <input type="submit" id = "delete_login" value = "delete测试">
</form>

PersonMapper接口中对应的函数:

void deletePerson(int id);

映射文件:

<delete id="deletePerson" parameterType="java.lang.Integer">
    delete from person where idperson = #{id}
</delete>

ServicePerson接口中对应的函数:

void delPerson(int id);

ServicePerson接口实现类中的函数实现:

@Override
public void delPerson(int id) {
    personMapper.deletePerson(id);
}

PersonController

@RequestMapping(value = "/testDelete", method = RequestMethod.POST)
public String deleteCon(int delete_id){
    System.out.println("delete sql: " + delete_id);
    personService.delPerson(delete_id);
    return "index";

4.3 update

form表单

<form role="formUpdate" action="/testUpdate" method="post">
    id:<input type="number" id="update_id0" name = "update_id"> <br>
    name:<input type="text" id = "update_name0" name = "update_name"> <br>
    sex:<input type="text" id="update_sex0" name = "update_sex"> <br>
    age:<input type="number" id = "update_age0" name = "update_age"> <br>
    <input type="submit" id = "update_login" value = "update测试">
</form>

PersonMapper接口中对应的函数:

void updatePerson(int id, String name, String sex, int age);

映射文件:

<update id="updatePerson" parameterType="com.example.testspringboot.bean.PersonBean">
    update person set name = #{name}, sex = #{sex}, age = #{age} where idperson = #{id}
</update>

ServicePerson接口中对应的函数:

void updPerson(int id, String name, String sex, int age);

ServicePerson接口实现类中的函数实现:

@Override
public void updPerson(int id, String name, String sex, int age) {
    personMapper.updatePerson(id, name, sex, age);
}

PersonController

@RequestMapping(value = "/testUpdate", method = RequestMethod.POST)
public String updateCon(int update_id, String update_name, String update_sex, int update_age){
    System.out.println("update sql: " + update_id + update_name);
    personService.updPerson(update_id, update_name, update_sex, update_age);
    return "index";
}

4.4 模糊查询

SELECT * FROM student WHERE name like '%${name}%'; 最终被解析为 SELECT * FROM student WHERE name like '%zhangsan%'; (√)

SELECT * FROM student WHERE name like '%#{name}%'; 最终被解析为SELECT * FROM student WHERE name like '%'zhangsan'%'; (×)

4.5 动态SQL

(1)if

<!-- if示例 当满足test条件时,才会将<if>标签内的SQL语句拼接上去 -->
<select id="find" resultType="student" parameterType="student">
        SELECT * FROM student WHERE age >= 18
        <if test="name != null and name != ''">
            AND name like '%${name}%'
        </if>
</select>

(2)choose when otherwise

<!-- choose标签是按顺序判断其内部when标签中的test条件出否成立,如果有一个成立,则 choose 结束。当 choose 中所有 when 的条件都不满则时,则执行 otherwise 中的sql。类似于Java 的 switch 语句,choose 为 switch,when 为 case,otherwise 则为 default。-->
<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>

(3)where

<!-- <where>标签只会在至少有一个子元素返回了SQL语句时,才会向SQL语句中添加WHERE,并且如果WHERE之后是以AND或OR开头,会自动将其删掉-->
<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG
  <where>
    <if test="state != null">
         state = #{state}
    </if>
    <if test="title != null">
        AND title like #{title}
    </if>
    <if test="author != null and author.name != null">
        AND author_name like #{author.name}
    </if>
  </where>
</select>

(4)foreach

<!--foreach:用来做迭代拼接的,通常会与SQL语句中的IN查询条件结合使用,注意,当parameterType为List(链表)或者Array(数组),后面在引用时,参数名必须为list或者array。如在foreach标签中,collection属性则为需要迭代的集合,由于入参是个List,所以参数名必须为list-->
<select id="batchFind" resultType="student" parameterType="list">
        SELECT * FROM student WHERE id in
        <foreach collection="list" item="item" open="(" separator="," close=")">
          #{item}
        </foreach>
</select>

(5)sql

<!--sql:可将重复的SQL片段提取出来,然后在需要的地方,使用<include>标签进行引用-->
<select id="findUser" parameterType="user" resultType="user">
	SELECT * FROM user
	<include refid="whereClause"/>
</select>

<sql id="whereClause">
     <where>
         <if test user != null>
         	AND username like '%${user.name}%'
         </if>
     </where>
</sql>

5 访问静态资源

application.yml配置语句:

spring:
  mvc:
    static-path-pattern: /static/**
  web:
    resources:
      static-locations: classpath:/static,classpath:/public,classpath:/resources,classpath:/META-INF/resources

5.1 访问CSS

在这里插入图片描述

html中引用CSS文件语句:

<link rel="stylesheet" type="text/css" href="../static/css/testCSS.css">

5.2 访问JS

<script src="../static/js/testJS.js"></script>

<button type="button" class="btn btn-primary" onclick="testclick()">返回index页面</button>

5.3 修改html、js后不显示效果

(1)浏览器缓存问题
F12调出控制台 -》NetWork -》Disable cache勾选上 -》Ctrl+F5刷新

(2)idea未实际build,需rebuild

5.4 html页面跳转

templates下的html不能直接跳转,需新建一个专门用于页面跳转的controller,使用a标签调用controller
在这里插入图片描述
在这里插入图片描述

5.5 修改项目默认启动页面

页面跳转Controller

@GetMapping(value = "/login")
public String loginPage() {
    return "html/LoginPage";
}

默认启动页面配置类:

@Configuration
public class WebConfigurer implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //默认地址(可以是页面或后台请求接口)
        registry.addViewController("/").setViewName("forward:/login");
        //设置过滤优先级最高
        registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
    }
}

js登陆函数:

function login() {
    console.log(username.value + "---" + password.value);
    if (username.value == 'admin' && password.value == '123456'){
        location.href = '/index';
    }else{
        alert_con.innerText = "用户名或密码错误";
        alert_btn_modal.click();
    }
}

5.6 登陆拦截

(1)实现HandlerInterceptor接口

public class LoginInterceptor implements HandlerInterceptor {
    /**
     * 在请求处理之前调用(Controller中方法调用之前)
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //查询当前session中是否存在user
        if(request.getSession().getAttribute("user") == null){
            response.sendRedirect("/login");
            //返回false则拦截器执行到此处不会继续操作
            return false;
        }
        System.out.println("request login user: " + request.getSession().getAttribute("user"));
        return true;
    }
    /**
     * 请求处理之后调用,但是在视图被渲染之前(Controller方法调用之后)
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }
    /**
     * 在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

(2)实现WebMvcConfigurer接口

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/index") //要拦截的路径
                .addPathPatterns("/car-track") //要拦截的路径
                .addPathPatterns("/device-manager")    //要拦截的路径
                .addPathPatterns("/device-statistics") //要拦截的路径
                .excludePathPatterns("/login");    //不拦截的路径
    }
}

(3)登陆判断Controller

@PostMapping("/loginController")
public String loginCon(HttpServletRequest request,
                                @RequestParam("username") String username,
                                @RequestParam("password") String password) {
    System.out.println("登陆 username:" + username + "---password:" + password);
    JSONObject data = new JSONObject();
    if (username.equals("admin") && password.equals("123456")){
        data.put("code", 1);
        request.getSession().setAttribute("user", "admin");
    }else{
        data.put("code", 0);
    }
    return data.toJSONString();
}

(4)js:

function login() {
    console.log(username.value + "---" + password.value);
    $.ajax({
        type: "post",
        url: "/api/loginController",   //控制器路径
        data: {
            username: username.value,
            password: password.value
        },
        cache: false,
        success: function (msg) {
            var data = eval('(' + msg + ')');
            var code = data.code;
            if(code == 1){
                location.href = '/index';
            }else{
                alert_con.innerText = "用户名或密码错误";
                alert_btn_modal.click();
            }
        }
    });
}

6 小例子

6.1 JS + controller实现页面间跳转

controller:

@Controller
public class testSpringBoot {

    @RequestMapping("/test")
    public String test(){
        System.out.println("lzh test controller");
        return "index";
    }

}

js:

function testclick()
{
    location.href = "/test";
}

html:

<script src="../static/js/testJS.js"></script>

    <button type="button" class="btn btn-primary" onclick="testclick()">返回index页面</button>

6.2 session实现登陆显示(“请登录”和“lzh”互相转换)

controller:

@Autowired
HttpSession session;
@RequestMapping(value = "/testLogin", method = RequestMethod.POST)
public String isLogin(String user_id) {
    if (user_id.equals("lzh")) {
        session.setAttribute("username", user_id);
    }
    return "index";
}
@RequestMapping(value = "/fallback")
public String unLogin() {
    session.removeAttribute("username");
    return "index";
}

index.html

<h1 th:text="${session.username}!=null?${session.username}:'请登录...'"></h1>
<form action="/testLogin" method="post">
    id:<input type="text" id="user_id" name = "user_id"> <br>
    <input type="submit" id = "test_login" value = "login测试">
</form>

<a href="/fallback">退出登录...</a>

6.3 购物车,根据选中项动态更新价格

controller:

@RequestMapping("/car")
public String goCar(Model model){
    model.addAttribute("persons", personService.getPersons());
    return "shopping";
}

index.html:

<a href="/car">shopping...</a>

shopping.html:

<h3 id="value">0</h3>
<table class="table table-bordered">
    <tr>
        <td>select</td>
        <td>id</td>
        <td>name</td>
        <td>age</td>
        <td>sex</td>
    </tr>
    <tr th:each="p : ${persons}">
        <td>
            <input type="checkbox" th:id="'checkbox' + ${pStat.index}" onclick="testShop(id)"/>
        </td>
        <td>
            <p th:text=" ${p.getIdPerson()}" th:id="'id' + ${pStat.index}" th:value=" ${p.getIdPerson()}">...</p>
        </td>
        <td>
            <p th:text=" ${p.getName()}" th:id="'name' + ${pStat.index}" th:value=" ${p.getName()}">...</p>
        </td>
        <td>
            <p th:text=" ${p.getAge()}" th:id="'age' + ${pStat.index}" th:value=" ${p.getAge()}">...</p>
        </td>
        <td>
            <p th:text=" ${p.getSex()}" th:id="'sex' + ${pStat.index}" th:value=" ${p.getSex()}">...</p>
        </td>
    </tr>
</table>

js:

function testShop(id) {
    //展示的总数
    var value = document.getElementById("value");
    var checkbox = document.getElementById(id);
    var num = id.replace("checkbox", "");
    var age = document.getElementById("age" + num);
    if(checkbox.checked){
        value.innerHTML = Number(value.innerText) + Number(age.innerText);
    }else{
        value.innerHTML = Number(value.innerText) - Number(age.innerText);
    }
}

6.4 js调用model中的属性参数

controller,在model中添加参数

@RequestMapping(value = "/manager")
public String mangerAddress(Model model){
    model.addAttribute("successLogin", false);
    return "index";
}

index.html,在js中使用model中参数

<html lang="en" xmlns:th="http://www.thymeleaf.org">

<script type="text/javascript" th:inline="javascript">
    window.onload = function () {
        var succ = [[${successLogin}]]
        console.log(succ);
    }
</script>

6.5 ajax使用

html,button调用函数

<button name="buquan-lzhnum" id='buquan-lzhnum' onclick='buquanF(id)'>补全</button>

<script>
    function buquanF(id) {
        var filename = id.replace("buquan-","");
        $.ajax({
            type: "post",
            url:"/buquanCon",   //控制器路径
            data: {
                address: filename
            },
            cache: false,
            success: function (msg) {
                console.log("补全---" + msg.result);
            }
        });
    }
</script>

controller

//补全
@RequestMapping("/buquanCon")
@ResponseBody
public Map bqCon(String filename){
    Map map = new HashMap();
    map.put("result", "1");
    return map;
}

6.6 iframe父子页面间数据控制

子控制父:

var modalContent = window.parent.document.getElementById("myModalContent");
modalContent.innerHTML = "<h3>补全成功</h3>";
var modalb = window.parent.document.getElementById("modalBtn");
modalb.click();

父用子:

var radios = document.getElementById('iframeData').contentDocument.getElementsByName('trRadio');

iframe若引用其他项目页面:

// 发送方:
window.parent.postMessage("hello", "http://localhost:8081"); // 要写top.postMessage或者是parent.message

// 接收方:
window.addEventListener( "message",
(e)=>{console.log(e.data)}	
false);

6.7 js修改div的css、属性、文字、增删子div

获取div:
var user = document.getElementById("usernameDiv");
修改css:
user.style.display = "block";
设置属性:
user.setAttribute("class", "form-group");
修改文字内容:
user.innerText = "<h3>补全成功</h3>";
增加节点:

var newTr = "\n" +
    "            <td>\n" +
    "                <input type=\"radio\" name='trRadio' id='num'>\n" +
    "            </td>\n";//待增加的节点的子节点
var tr = document.createElement("tr");//创建待增加的节点
tr.setAttribute("id", "tr-" + filename);//为待增加的节点设置属性
tr.setAttribute("name", "sons");
tr.innerHTML = newTr;//设置tr节点的子元素(含子节点)
lastTr.parentNode.insertBefore(tr, lastTr.nextSibling);//在lastTr节点后增加tr节点

//删除节点:remove方法
var sonOfuser = document.getElementById("sonOfuserDiv");
sonOfuser.remove();

6.8 js字符串替换

newTr = newTr.replace(/lzhnum/g, filename);
将newTr中的全部lzhnum替换为filename

6.9 form上传文件

index.html

<html lang="en" xmlns:th="http://www.thymeleaf.org">

<form th:action="@{/upload}" method="post" enctype="multipart/form-data" onsubmit="uploadBF()">
        <!-- 切记,这里的name="multipartFile"必须和控制层的参数一致性MultipartFile multipartFile -->
        <input type="file" id="file" name="multipartFile" /><br/>
        <input type="submit" value="上传"/><br/>
</form>
<button onclick="uploadF()">upload</button>
    <script type="text/javascript" th:inline="javascript">
        function uploadBF() { //form提交前调用
            console.log(document.getElementById("file").value);
        }
        function uploadF() {
            console.log([[${filepath}]]);
        }
    </script>

controller

   @RequestMapping(value = "/upload", method = RequestMethod.POST)
   public String upload(@RequestParam(value = "multipartFile") MultipartFile multipartFile, Model model) throws IllegalStateException, IOException, IOException {
   System.out.println(multipartFile.getOriginalFilename());
   //创建文件名称
   String fileName = multipartFile.getContentType().substring(multipartFile.getContentType().lastIndexOf("/") + 1);
   // 获取到文件的路径信息
   RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
   ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
   String filePath = servletRequestAttributes.getRequest().getServletContext().getRealPath("/") + fileName;
   // 打印保存路径
   System.out.println(filePath);
   model.addAttribute("filepath",filePath);
   // 创建文件
   File saveFile = new File(filePath);
   // 文件保存
   multipartFile.transferTo(saveFile);
   // 返回信息
   return "index";
}

6.10 form ajax上传文件

html:

<form class="form-inline col-md-2" id="fileForm" enctype="multipart/form-data" method="post">
        <input type="file" class="form-control" id="file" name="multipartFile" >
</form>
    <button class="btn btn-default" onclick="uploadF()">文件上传</button>
    <div hidden id="isbuquan" value=""></div>
    
<script>
var buquandiv = document.getElementById("isbuquan");
buquandiv.setAttribute("value", true);

function uploadF(){
    var selectedFile = document.getElementById("file").files[0];
    if (selectedFile === undefined){
        return ;
    }
    var filename = selectedFile.name;
    var formdata = new FormData(document.getElementById("fileForm"));
    formdata.append("filename", filename);
    $.ajax({
        type: "post",
        url:"/uploadCon",   //控制器路径
        data: formdata,
        async: false,
        cached: false,
        contentType: false,
        processData: false,
        beforeSend: function(){
            console.log("上传---ajax---" + filename);
        },
        success: function (msg) {
            console.log("上传---ajax---" + msg.filepath);
        }
    });
	}
	</script>

controller:

@RequestMapping(value = "/uploadCon", method = RequestMethod.POST)
@ResponseBody
public Map pd(@RequestParam(value = "multipartFile") MultipartFile multipartFile, HttpServletRequest request) throws IOException {
    String filename =  request.getParameter("filename");
    Map map = new HashMap();
    System.out.println(multipartFile.getOriginalFilename() + "---" + filename);
    //创建文件名称
    String createfileName = multipartFile.getContentType().substring(multipartFile.getContentType().lastIndexOf("/") + 1);
    // 获取到文件的路径信息
    RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
    ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
    String filePath = servletRequestAttributes.getRequest().getServletContext().getRealPath("/") + filename;
    // 打印保存路径
    System.out.println(filePath);
    map.put("filepath", filePath);
    // 创建文件
    File saveFile = new File(filePath);
    // 文件保存
    multipartFile.transferTo(saveFile);

    return map;
}

6.11 计时器使用,修改div width无效果

<div class="progress" id="process" style="background: red;height: 50px;width: 100px">
</div>

<script>
    var timer = null;
    function jdt() {
        var j = document.getElementById("process");
        var width = 1;
        clearInterval(timer);
        timer = setInterval(function () {
            j.style.width = width++ + "px";
        },100);
</script>

进度条:

<div class="progress" >
    <div id="process" class="progress-bar progress-bar-striped active" role="progressbar"
         aria-valuenow="5" aria-valuemin="0" aria-valuemax="100" style="width: 5%">
        <span class="sr-only">45% Complete</span>
    </div>
</div>
<button onclick="jdt()">进度条</button>
<script>
    var timer = null;
    function jdt() {
        var j = document.getElementById("process");
        var width = 1;
        clearInterval(timer);
        timer = setInterval(function () {
            if(width == 100)
                width = 100
            j.style.width = width++ + "%";
        },100);
    }
</script>

6.12 controller返回List,html页面如何接收

在这里插入图片描述
在这里插入图片描述

6.13 controller返回JSONObject,html页面如何接收

在这里插入图片描述
在这里插入图片描述

保证put顺序
JSONObject jsonObject = new JSONObject(new LinkedHashMap());

6.14 组织架构树

方法一:

<link rel="stylesheet" type="text/css" href="../../static/css/zTreeStyle.css"> 
<script src="../../static/js/jquery.ztree.all.js"></script>

<ul id="ZTree" class="ztree" style="background: #fff;"></ul>

<script>
var liChengTongJi_setting={
    view:{
        showIcon: true
    },
    check: {
        enable: true,
        chkStyle: "checkbox",  //显示 checkbox 选择框,默认checkbox可选择值radio
        chkboxType:{ "Y": "", "N": "s" }
        /*
            chkboxType: { “Y”: “ps”, “N”: “ps” }
            Y 属性定义 checkbox 被勾选后的情况;
            N 属性定义 checkbox 取消勾选后的情况;
            “p” 表示操作会影响父级节点;
            “s” 表示操作会影响子级节点。
         */
    },
    callback:{
        onCheck: zTreeOnCheck, //选中或取消时的方法
        onAsyncSuccess: zTreeOnExpand //异步请求获取子节点
        //onClick: zTreeOnExpand //onExpand
    },
    async: {
        enable: true,//要开启async功能必须设置为true,其他地方同理
        //dataType: "json",
        type: "post",
        url: "/api/unitTreeLevel",
        autoParam: ["id"] //设置传参为当前节点id,后台接口入参必须为id
    },
    data: {
        simpleData: {
            enable: true,
            idKey: "id",//节点id名
            pIdKey: "pid",//父节点id名
            rootPId: 0//默认根节点为0
        }
    }
};

var liChengTongJi_zTreeNodes;//组织架构树节点
var liChengTongJi_zTreeObj;//组织架构树对象
function zTreeOnCheck(event, treeId, treeNode) {
    cancleParenetAndSonsNode(treeNode);
    danweis_names = new Array();//保存根节点下所有选中的节点
//console.log(treeNode.getPath()[0]);//获取根节点
//获取树
var treeObj = $.fn.zTree.getZTreeObj("ZTree");
//获取某节点下的全部子节点
    var childNodes = treeObj.transformToArray(treeNode.getPath()[0]);
    for(var i = 0; i < childNodes.length; i++){
        if(childNodes[i].checked){
            danweis_names.push(childNodes[i].name);
        }
    } 
treeObj.refresh();//刷新树
}
function zTreeOnExpand(event, treeId, treeNode, clickFlag) {
    
}
//选中节点时,取消上级节点和全部子节点
function cancleParenetAndSonsNode(node){
    if(node.checked){
        var parentNode = node.getParentNode();
        while(parentNode != null){
            if(parentNode.checked){
                parentNode.checked = false;
            }
            parentNode = parentNode.getParentNode();
        }
        var treeObj = $.fn.zTree.getZTreeObj("ZTree");
        var childNodes = treeObj.transformToArray(node);
        for(var i = 1; i < childNodes.length; i++){
            if(childNodes[i].checked){
                childNodes[i].checked = false;
            }
        }
        treeObj.refresh();//刷新树
    }
}

var liChengTongJi_zTreeNodes=[
    {"name":"湖州","open":true,"id":1,"pid":0,"icon":"../../static/images/control/shebei.png","isDevice":0,"data":{"name":123}},
    {"name":"东城区","id":11,"pid":1,"isDevice":1},
    {"name":"朝阳区","id":12,"pid":1,"isDevice":1},
    {"name":"重庆","open":true,"id":2,"pid":0,"isDevice":0},
    {"name":"巴南区","id":21,"pid":2,"isDevice":0},
    {"name":"渝中区","id":22,"pid":2,"isDevice":1}
];
var liChengTongJi_zTreeNodes0=[
    {"name":"南泉","id":211,"pid":21,"isDevice":1},
    {"name":"界石","id":212,"pid":21,"isDevice":1}
];
//第一个参数为zTree的DOM容器,第二个为zTree设置详情可见官网api,第三个为zTree的节点数据
var liChengTongJi_zTreeObj = $.fn.zTree.init($("#ZTree"), liChengTongJi_setting, liChengTongJi_zTreeNodes);
</script>

方法二:

<style type="text/css"> <!--组织架构树css-->
    ul>li{
        list-style: none;
    }
    /* 可展开*/
    .switch-open
    {
        margin-left:-12px;
        border:6px solid transparent;
        display:inline-block;
        width:0px;
        height:0px;
        border-top-color: black;

    }
    /* 展开完毕*/
    .switch-close
    {
        margin-left:-12px;
        border:6px solid transparent;
        display:inline-block;
        width:0px;
        height:0px;
        border-left-color: black;
        margin-bottom: 2px;

    }
    /* 改变CheckBox样式*/
    input[type='checkbox']{
        width: 20px;
        height: 20px;

        -webkit-appearance:none;
        -moz-appearance: none;
        border: 1px solid #c9c9c9;
        border-radius: 3px;
        outline: none;
        color:white;
        text-align: center;
    }
    input[type='checkbox']:before
    {
        content: '√ ';
        color:transparent;
    }
    input[type=checkbox]:checked{
        background-color: rgba(24, 74, 255, 0.6);
    }
    input[type=checkbox]:checked:before{
        content: '√';
        color:white;
        font-weight: bold;
    }
</style>

<div class="warp">
    <ul id="zuzhijiagou_container" class="list-group">
    </ul>
</div>

<script>
    $.ajax({
        type: "post",
        url:"/test",   //控制器路径
        data: {
        },
        cache: false,
        success: function (msg) {
            var dataJson = JSON.parse(msg.data);
            console.log("parse" + dataJson);
            generate(dataJson,document.getElementById('zuzhijiagou_container'));
        }
    });


    //结构
    var json={
        "0-0":{
            '0-0-1':{
                '0-0-1-0':null,
                '0-0-1-1':null,
                '0-0-1-2':null
            }
        }
    };

    //这里生成DOM
    function generate(json,par){
        for(var attr in json){
            var ele = document.createElement('li');
            ele.setAttribute("class", "list-group-item");
            ele.setAttribute("style", "border-width:0;");
            if(!json[attr]) {
                ele.innerHTML = ' <input type="checkbox" id="'+ attr +'" οnclick="getData()" />' + attr;
            }else{
                ele.innerHTML='<span>' +
                    '<span class="switch-open" οnclick="toggle(this)"></span>' +
                    // '<input type="checkbox" οnclick="checkChange(this)" />'+
                    attr+'</span>';
                var nextpar = document.createElement('ul');
                nextpar.setAttribute("class", "list-group");
                nextpar.setAttribute("style", "margin:0;");
                ele.appendChild(nextpar);
                generate(json[attr],nextpar);
            }
            par.appendChild(ele);
        }
    }
    //generate(json,document.getElementById('zuzhijiagou_container'));

    //处理展开和收起
    function toggle(eve){
        var par=eve.parentNode.nextElementSibling;
        if(par.style.display=='none'){
            par.style.display='block';
            eve.className='switch-open';
        }else{
            par.style.display='none';
            eve.className='switch-close';
        }
    }

    //处理全部勾选和全部不选
    function checkChange(eve){
        var oul=eve.parentNode.nextElementSibling;
        if(eve.checked){
            for(var i=0;i<oul.querySelectorAll('input').length;i++){
                oul.querySelectorAll('input')[i].checked=true;
            }
        }else{
            for(var i=0;i<oul.querySelectorAll('input').length;i++){
                oul.querySelectorAll('input')[i].checked=false;
            }
        }
    }

    function getData() {
        var inputs = document.getElementsByTagName("input");//获取所有的input标签对象
        for(var i = 0; i < inputs.length; i++){
            var obj = inputs[i];
            if(obj.type=='checkbox' && obj.checked){
                console.log(obj.parentNode.innerText);
            }
        }
    }
    </script>

6.15 导出excel

<script src="../../static/js/tableExport.min.js"></script>

<table id="liChengTongJi_table_table" class="table table-hover">
    <tbody id="liChengTongJi_table_tbody">
        <tr id="liChengTongJi_table_title">
            <th class="col-sm-1">序号</th>
            <th class="col-sm-1">所属车队</th>
            <th class="col-sm-1">车辆名称</th>
            <th class="col-sm-1">车牌号码</th>
            <th class="col-sm-1">统计时间</th>
            <th class="col-sm-1">里程计算</th>
            <th class="col-sm-1">行驶里程(km)</th>
        </tr>
    </tbody>
</table>

<script src="../../static/js/jquery.min.js"></script>
<script src="../../static/js/tableExport.min.js"></script>
<script>
function liChengTongJi_daoChuBtn() {
    $("#liChengTongJi_table_table").tableExport({
        type:"excel",
        fileName:"liChengTongJi_table_table"
    });
    console.log("里程统级--导出文件");
}
</script>

7 数据库操作

(1)将table中主键id改为自增:
alter table table_name modify id int auto_increment

(2)insert中包含空字段
insert into hz_jstxdb.t_message( src) values ( '123');

(3)mysql中字段为datatime,对应java中应为:
Date sendTime = new Date();
new Timestamp(sendTime.getTime())

(4)字符串转Date
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time = (String) data.get("sendTime");
Date sendTime = dateFormat.parse(time);

(5)根据receiveTime逆序从第0条开始,选择15条数据
select * from hz_jstxdb.t_message where (src = '1' and dst = '2') or (src = '2' and dst = '1') order by receiveTime desc limit 0, 15;

8 项目迁移

若有网,则不需要第一步
(1) 配置本地仓库
在这里插入图片描述
setting.xml:

<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <localRepository>D:\repositoryMaven\repository</localRepository>
  <pluginGroups>
  </pluginGroups>
  <proxies>
  </proxies>
  <servers>
  </servers>
<!--  <mirrors>-->
<!--    <mirror>-->
<!--        <id>nexus-aliyun</id>  -->
<!--        <mirrorOf>central</mirrorOf>    -->
<!--        <name>Nexus aliyun</name>  -->
<!--        <url>http://maven.aliyun.com/nexus/content/groups/public</url> -->
<!--    </mirror>-->
<!--  </mirrors>-->
  <profiles>
  </profiles>
 </settings>

(2) 不识别仓库,将.iml文件、.idea文件夹删除,关闭项目再导入
(3) 已无错误,即可直接在main函数处运行项目

9 JS

9.1 点击button,执行完毕后自动刷新页面

添加type="button"

9.2 获取当前时间

function timer_label(){
    var now = new Date();
    var year = now.getFullYear();
    var month = now.getMonth() + 1;
    if(month < 10){
        month = "0" + month;
    }
    var day = now.getDate();
    if(day < 10){
        day = "0" + day;
    }
    var hour = now.getHours();
    if(hour < 10){
        hour = "0" + hour;
    }
    var minute = now.getMinutes();
    if(minute < 10){
        minute = "0" + minute;
    }
    var second = now.getSeconds();
    if(second < 10){
        second = "0" + second;
    }
    return year + "-" + month + "-" + day + " " + hour+ ":" + minute + ":" + second;
}

9.3 选择时间控件

<input id="start_time" type="datetime-local" class="form-control" placeholder="开始时间">
type有多种,可以只有时间、也可以只有日期

9.4 获取兄弟父亲节点

(1)js

var parent = test.parentNode; // 父节点
var chils = test.childNodes; // 全部子节点
var first = test.firstChild; // 第一个子节点
var last = test.lastChile; // 最后一个子节点 
var previous = test.previousSibling; // 上一个兄弟节点
var next = test.nextSibling; // 下一个兄弟节点

var parent = test.parentElement; // 父节点元素
var first = test.firstElementChild; // 第一个子节点元素
var last = test.lastElementChile; // 最后一个子节点 元素
var previous = test.previousElementSibling; // 上一个兄弟节点元素
var next = test.nextElementSibling; // 下一个兄弟节点元素

(2)jq

$("#test1").parent(); // 父节点
$("#test1").parents(); // 全部父节点
$("#test1").parents(".mui-content");
$("#test").children(); // 全部子节点
$("#test").children("#test1");
$("#test").contents(); // 返回#test里面的所有内容,包括节点和文本
$("#test").contents("#test1");
$("#test1").prev();  // 上一个兄弟节点
$("#test1").prevAll(); // 之前所有兄弟节点
$("#test1").next(); // 下一个兄弟节点
$("#test1").nextAll(); // 之后所有兄弟节点
$("#test1").siblings(); // 所有兄弟节点
$("#test1").siblings("#test2");
$("#test").find("#test1");

#元素筛选
// 以下方法都返回一个新的jQuery对象,他们包含筛选到的元素
$("ul li").eq(1); // 选取ul li中匹配的索引顺序为1的元素(也就是第2个li元素)
$("ul li").first(); // 选取ul li中匹配的第一个元素
$("ul li").last(); // 选取ul li中匹配的最后一个元素
$("ul li").slice(1, 4); // 选取第2 ~ 4个元素
$("ul li").filter(":even"); // 选取ul li中所有奇数顺序的元素

9.5 删除全部兄弟节点

var table_title = document.getElementById("table_title");
function clearBtn() {
    while(table_title.nextSibling != null){
        table_title.nextSibling.remove();
    }
}

9.6 html跳转+传参

<li><a href="/gotoCarWayShow?name=123&pas=lzh">页面跳转</a></li>
function getParams(key) {
    var reg = new RegExp("(^|&)" + key + "=([^&]*)(&|$)");
    var r = window.location.search.substr(1).match(reg);
    if (r != null) {
        return unescape(r[2]);
    }
    return null;
};
console.log(getParams("pas"));

9.7 字符串转Date,计算间隔天数

//2022-01-28 08:32:12
var subTime = new Date(end_time_str)new Date(start_time_str);
if(subTime < 0){
    alert("请注意,结束时间不能早于开始时间");
    return ;
}
if(subTime > 90 * 1000 * 60 * 60 * 24){
    alert("请注意,最大查询90天数据");
    return ;
}

9.8 前端ajax向controller传数组

var danweis = new Array();
danweis.push(str);
$.ajax({
    type: "post",
    url:"/api/deviceInfoByDanwei",   //控制器路径
    data: {
        danweis : danweis
    },
    cache: false,
    success: function (msg) {
        console.log("单位下设备信息-msg: " + msg);
    }
});
@RestController
@RequestMapping("/api")
public class DepartmentController {

    @PostMapping("/deviceInfoByDanwei")
    public DeviceInfoDto getDeviceInfoByDanwei(@RequestParam("danweis[]") String[] danweis) {
        System.out.println("根据单位信息获取设备详细信息入参-danweis[]: " + Arrays.toString(danweis));
        return null;
    }
}

9.10 多级联动

<div id="duojiliandong_container" > </div>
<script>
//结构
var datajson={
    "0-0":{
        '0-0-1':{
            '0-0-1-0':null,
            '0-0-1-1':null,
            '0-0-1-2':null
        },
        '0-0-2':null,
        '0-0-3':{
            '0-0-3-0': {
                '0-0-3-0-1':null,
                '0-0-3-0-2':null,
                '0-0-3-0-3':null
            },
            '0-0-3-1':null,
            '0-0-3-2':null
        },
        '0-0-4':null,
    },
    "0-1":null
};
</script>
<script language="javascript">
    //---------------------添加select选项start-----------------
    var duojiliandong_container = document.getElementById("duojiliandong_container");
    var duojiliandong_select_num = 4; //select的个数
    var duojiliandong_select = "";
    var duojiliandong_select_i = 0;
    for(duojiliandong_select_i; duojiliandong_select_i < duojiliandong_select_num; duojiliandong_select_i++) {
        duojiliandong_select += "<SELECT ID=\"duojiliandong_select_x" + duojiliandong_select_i + "\" " +
                "style='width:100%; height: 30px;'" +
            "NAME=\"duojiliandong_select_x" + duojiliandong_select_i + "\" >\n" +
            "                                <OPTION selected></OPTION>\n" +
            "                            </SELECT><br/>";

    }
    duojiliandong_container.innerHTML = duojiliandong_select;
    //---------------------添加select选项end-----------------

    //---------------------配置数据源格式start-----------------
    var duojiliandong_array = new Array();
    function formatDuojiliandongData(json, parNode){
        for(var attr in json){
            if(!json[attr]){
                //console.log("叶子节点: " + parNode + "**" + attr);
                duojiliandong_array.push(new Array(attr,parNode,attr))
            }else{
                //console.log("非叶子节点: " + parNode + "**" + attr);
                duojiliandong_array.push(new Array(attr,parNode,attr))
                formatDuojiliandongData(json[attr], attr);
            }
        }
    }
    //---------------------配置数据源格式end-----------------

    //---------------------设置数据源格式start-----------------
    function setDuojiliandongData() {
        var liandong2=new CLASS_LIANDONG_YAO(duojiliandong_array);
        liandong2.firstSelectChange("根目录","duojiliandong_select_x0");
        var duojiliandong_select_i = 0;
        for(duojiliandong_select_i; duojiliandong_select_i < duojiliandong_select_num - 1; duojiliandong_select_i++) {
            liandong2.subSelectChange("duojiliandong_select_x" + duojiliandong_select_i,"duojiliandong_select_x" + (duojiliandong_select_i+1) );
        }
    }
    //---------------------设置数据源格式end-----------------

    function CLASS_LIANDONG_YAO(array){
        //数组,联动的数据源
        this.array=array;
        this.indexName='';
        this.obj='';
        //设置子SELECT
        // 参数:当前onchange的SELECT ID,要设置的SELECT ID
        this.subSelectChange=function(selectName1,selectName2){
            var obj1=document.all[selectName1];
            var obj2=document.all[selectName2];
            var objName=this.toString();
            var me=this;
            obj1.onchange=function(){
                me.optionChange(this.options[this.selectedIndex].value, obj2.id)
            }
        }
        //设置第一个SELECT
        // 参数:indexName指选中项,selectName指select的ID
        this.firstSelectChange=function(indexName,selectName){
            this.obj=document.all[selectName];
            this.indexName=indexName;
            this.optionChange(this.indexName,this.obj.id)
        }
        // indexName指选中项,selectName指select的ID
        this.optionChange=function (indexName,selectName){
            var obj1=document.all[selectName];
            var me=this;
            obj1.length=0;
            obj1.options[0]=new Option("请选择",'');
            for(var i=0;i<this.array.length;i++){
                if(this.array[i][1]==indexName){
                    obj1.options[obj1.length]=new Option(this.array[i][2],this.array[i][0]);
                }
            }
        }
    }

//函数调用:先将json数据改为数组格式,然后设置联动数据
formatDuojiliandongData(dataJson, "根目录");
setDuojiliandongData();

</script>

jq获取select的值:

var v1 = $('#duojiliandong_select_x0 option:selected').text();
if(v1 == '请选择') v1 = '';
console.log(v1);

9.11 屏幕左侧弹出modal

<div class="pane" style="position: absolute;top:60px;right: 30px;">
    <a href="javascript:;"  data-backdrop="static" data-toggle="modal" data-target="#myModal1"><span>轨迹展示</span></a>
</div>
<!--css样式-->
<style type="text/css">
    .modal.left .modal-dialog,.modal.right .modal-dialog{position:fixed;margin:auto;width:320px;height:100%;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}
    .modal.left .modal-content,.modal.right .modal-content{height:100%;overflow-y:auto}
    .modal.left .modal-body,.modal.right .modal-body{padding:15px 15px 80px}
    .modal.left.fade .modal-dialog{left:-320px;-webkit-transition:opacity .3s linear,left .3s ease-out;-moz-transition:opacity .3s linear,left .3s ease-out;-o-transition:opacity .3s linear,left .3s ease-out;transition:opacity .3s linear,left .3s ease-out}
    .modal.left.fade.in .modal-dialog{left:0}
    .modal.right.fade .modal-dialog{right:-320px;-webkit-transition:opacity .3s linear,right .3s ease-out;-moz-transition:opacity .3s linear,right .3s ease-out;-o-transition:opacity .3s linear,right .3s ease-out;transition:opacity .3s linear,right .3s ease-out}
    .modal.right.fade.in .modal-dialog{right:0}
    .modal-content{border-radius:0;border:none}
    .modal-header{border-bottom-color:#eee;background-color:#fafafa}
    .modal-backdrop {/*背景颜色不变深*/
        opacity: 0 !important;
        filter: alpha(opacity=0) !important;/*解决背景颜色加深问题*/
    }
</style>
<!--点击右侧弹出-->
<!-- 左边 弹出层 modal -->
<div class="modal right fade" id="myModal1" 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">&times;</button>
                <h4 class="modal-title" id="myModalLabel">弹窗标题</h4>
            </div>
            <div class="modal-body">
                弹窗内容
            </div>
        </div>
    </div>
</div>
<!-- end 弹出层 moda -->

9.12 controller返回Json

JSONObject obj = new JSONObject();
obj.put("湖州市局", deviceStatisticService.deviceTree(parentId));
return obj.toJSONString();

success: function (msg) {
    console.log("组织架构树-msg: " + msg);
    var dataJson = eval("("+msg+")");
    console.log("设备组织架构树-dataJson: " + dataJson);
}

9.13 获取某个div下的全部input

var oul = document.getElementById("liChengTongJi_zuzhijiagou_container");//获取所有的input标签对象
for(var i=0;i<oul.querySelectorAll('input').length;i++){
   oul.querySelectorAll('input')[i].checked=false;
}

9.14 阻止冒泡事件,点击子元素不触发父级事件

function jianKongFun(id) {
   var e=window.event || arguments.callee.caller.arguments[0];
    e.preventDefault();
    e.stopPropagation();
}

9.15 数组是否包含某一元素

if(selectedTaskId.indexOf(id) > -1){  //包含
     selectedTaskId.splice($.inArray( id ,selectedTaskId),1);;  //剔除该元素
 }else{  //不包含
     selectedTaskId.push(id);  //加入该元素
 }
//移除指定元素:数组.splice($.inArray(元素,数组),数量);

10 html

10.1 时间控件

注意要引进font

在这里插入图片描述

<link rel="stylesheet" type="text/css" href="../../static/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="../../static/css/bootstrap-datetimepicker.min.css">

<script src="../../static/js/jquery.min.js"></script>
<script src="../../static/js/bootstrap.min.js"></script>
<script src="../../static/js/moment-with-locales.js"></script>
<script src="../../static/js/bootstrap-datetimepicker.min.js"></script>

<div class='input-group date' id='start_time_datePicker'>
    <input id='start_time' type='text' class="form-control" placeholder="开始时间"/>
    <span class="input-group-addon">
            <span class="glyphicon glyphicon-calendar"></span>
    </span>
</div>

<script>
$('#start_time_datePicker').datetimepicker({
        format: 'YYYY-MM-DD HH:mm',
        locale: moment.locale('zh-cn')
        // defaultDate: "2019-01-01 23:59"
    });

var start_time = document.getElementById("start_time");
function submitBtn() {
	var start_time_str = start_time.value;
}
</script>

10.2 maptalks

10.2.1 根据经纬度坐标获取方位角

function getMarkerRotation(lng_a, lat_a, lng_b, lat_b){
    var a = (90 - lat_b) * Math.PI / 180;
    var b = (90 - lat_a) * Math.PI / 180;
    var AOC_BOC = (lng_b - lng_a) * Math.PI / 180;
    var cosc = Math.cos(a) * Math.cos(b) + Math.sin(a) * Math.sin(b) * Math.cos(AOC_BOC);
    var sinc = Math.sqrt(1 - cosc * cosc);
    var sinA = Math.sin(a) * Math.sin(AOC_BOC) / sinc;
    var A = Math.asin(sinA) * 180 / Math.PI;
    var res = 0;
    if (lng_b > lng_a && lat_b > lat_a) res = A;
    else if (lng_b > lng_a && lat_b < lat_a) res = 180 - A;
    else if (lng_b < lng_a && lat_b < lat_a) res = 180 - A;
    else if (lng_b < lng_a && lat_b > lat_a) res = 360 + A;
    else if (lng_b > lng_a && lat_b == lat_a) res = 90;
    else if (lng_b < lng_a && lat_b == lat_a) res = 270;
    else if (lng_b == lng_a && lat_b > lat_a) res = 0;
    else if (lng_b == lng_a && lat_b < lat_a) res = 180;
    return -res;
}

10.2.2 点击marker出现弹窗,再点消失

function showMarker(x, y) {
    var marker = new maptalks.Marker(
        [x, y],{
            'symbol' : {
                'markerFile' : '../static/images/jwt.png',//'http://50.56.40.102/lbs/images/openlibrary/gugong.jpg',
                'markerWidth' : 50,
                'markerHeight': 50,
                'markerOpcity': 1,
                'markerRotation' : 60//marker逆时针旋转角度
            }
        })
    layer.addGeometry(marker)

    // ================信息窗体start==================
    var infoWindow = {
        'title' : '设备信息',
        'content': '设备名: ' + '我们都有一个家名字叫中国,兄弟姐妹都很多精神色士大夫士大夫阿斯蒂芬阿斯蒂芬撒地方阿斯蒂芬阿斯蒂芬阿斯蒂芬阿斯蒂芬撒旦发生的发士大夫发阿斯蒂芬阿斯蒂芬<a href="http://47.49.21.236:8080">234</a>'
    };
    var isOpenmarker = true;
    marker.on('click',function(){
        if(isOpenmarker){
            marker.setInfoWindow(infoWindow)
            marker.openInfoWindow();
            isOpenmarker = false;
        }else{
            marker.removeInfoWindow();
            isOpenmarker = true;
        }
    })
    // ================信息窗体end==================
    return marker;
}

10.2.3 点击线段,出现弹窗

function showCarWay(layer, dataJson){//layer:图层,dataJson:线段坐标
    layer.clear();
    var i = 1;
    for(i; i < dataJson.length; i++){
        var start = [dataJson[i-1].x, dataJson[i-1].y];
        var end = [dataJson[i].x, dataJson[i].y];
        var arrow = new maptalks.LineString(
            [start, end],
            {
                'id' : 'arrow' + i,
                'arrowStyle' : 'classic',//箭头
                'arrowPlacement' : 'vertex-last',//箭头方向
                symbol: {
                    'lineColor' : '#0071ce',//线段颜色
                    'lineWidth' : 1
                }
            }
        );
        arrowInfoWindows(arrow, start, end, dataJson[i-1].timeIn, dataJson[i].timeIn);
        arrow.addTo(layer);
    }
}
function arrowInfoWindows(arrow, start, end, t1, t2) {
    arrow.on('click', function() {
        arrow.setInfoWindow({
            title    : '轨迹信息',
            content  : '<div style="color:#0071ce">起点坐标: ' + start + '</div>' +
                '<div style="color:#0071ce">起点时间: ' + t1 + '</div>' +
                '<div style="height: 10px;"></div>' +
                '<div style="color:#0071ce">终点坐标: ' + end + '</div>' +
                '<div style="color:#0071ce">终点时间: ' + t2 + '</div>'
        });
        arrow.openInfoWindow();
    });
}

10.2.4 修改marker旋转角度

marker.updateSymbol({
    markerRotation : markerRotation
});

10.2.5 marker在线段移动

//start、end:线段起点、终点经纬度坐标
var start = [120.11324, 34.567];
function getOffset(start, end, marker) {
    var startOffset = new maptalks.Coordinate(start);
    var endtOffset = new maptalks.Coordinate(end);
    marker.setCoordinates(startOffset);
    return endtOffset.sub(startOffset);//.multi(1 / 2);
}
var player = null;
function replay(start, offset, marker) {
    marker.setCoordinates(start);
    player = marker.bringToFront().animate({
        //animation translate distance
        translate: [offset['x'], offset['y']]
    }, {
        duration: 1000,
        focus : true //屏幕是否跟随移动
    });
}

//移动:player.play();
//暂停:player.pause();

10.3 左侧弹窗

<div id="left_nav" class="col-md-2" style="height: 200px;background: palevioletred;"></div>
<button onclick="leftNavControl()" id="left_nav_control" style="z-index:1;border:0;width: 24px;
    height: 58px;position: fixed;top: 136px;left: 337px;background: #0071ce;">
    <span id="left_nav_control_span" class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
</button>
<div id="right_box" class="col-md-10" style="height: 200px;background: powderblue;"></div>

<script>
//----------控制左侧菜单是否弹出--------start
var left_nav = document.getElementById("left_nav");
var right_box = document.getElementById("right_box");
var left_nav_control = document.getElementById("left_nav_control");
var left_nav_control_span = document.getElementById("left_nav_control_span");
var isShowLeft_nav = true;
function leftNavControl() {
    if(isShowLeft_nav){
        left_nav.style.display = "none";
        right_box.setAttribute("class", "col-md-12");
        left_nav_control_span.setAttribute("class", "glyphicon glyphicon-chevron-right");
        left_nav_control.style.left = "0";
        isShowLeft_nav = false;
    }else{
        left_nav.style.display = "block";
        left_nav.setAttribute("class", "col-md-2");
        right_box.setAttribute("class", "col-md-10");
        left_nav_control_span.setAttribute("class", "glyphicon glyphicon-chevron-left");
        left_nav_control.style.left = "337px";
        isShowLeft_nav = true;
    }
}
//----------控制左侧菜单是否弹出--------end
</script>

10.4 div高度自适应屏幕

html,body的height都设置为100%
div的height也设置为100%即可

<nav style="height: 95px; ">
<div style="height: calc( 100% - 95px );">

10.5 table中文字超出显示…

table{
    table-layout:fixed;
}
table td{
    overflow: hidden;
    text-overflow:ellipsis;
    white-space: nowrap;
}

<table id="liChengTongJi_table_table" class="table table-hover">
    <tr id="liChengTongJi_table_title">
        <th class="col-sm-1">序号</th>
        <th class="col-sm-1">所属车队</th>
    </tr>
    <tr >
        <td class="col-sm-1" title="序号">序号</td>
        <td class="col-sm-1" title="所属车队">所属车队</td>
    </tr>
</table>

10.6 自定义表格内容,生成excel

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>tableExport</title>
    <link href="http://www.jq22.com/jquery/bootstrap-3.3.4.css" rel="stylesheet" type="text/css">
    <!--引用以下js文件-->
    <script src="js/jquery.min.js"></script>
    <!--要将生成的导出文件保存在客户端,请将其包含在html代码中:-->
    <script src="libs/FileSaver/FileSaver.min.js"></script>
    <!--要以XLSX (Excel 2007+ XML格式)格式导出表格,您需要额外包括SheetJS/js-xlsx:-->
    <script src="libs/js-xlsx/xlsx.core.min.js"></script>
    <!--不管期望的格式是什么,最后包括:-->
    <script src="libs/tableExport.min.js"></script>

    <script>
        $(function () {
            MakeTb();//初始化表格
        });
        //AJAX动态生成TABLE
        function MakeTb() {
            $("#tbody").empty();
            for (var i = 0; i < 9999; i++) {
                var html = "";
                html += "<tr>";
                html += "<td><span>" + (i + 1) + "</span></td>";
                html += "<td><span>张三" + (i + 1) + "</span></td>";
                html += "<td><span>男" + (i + 1) + "</span></td>";
                html += "<td><span>江苏省" + (i + 1) + "</span></td>";
                html += "<td><span>南京市" + (i + 1) + "</span></td>";
                html += "<td><span>秦淮区" + (i + 1) + "</span></td>";
                html += "</tr>";
                $("#tbody").append(html);//差不多意思意思得了
            }
        }
        //导出excel
        $(function () {
            $("#generate-excel").click(function () {
                $('#test_table').tableExport({ type: 'excel' });
            });
        });
    </script>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-3" style="padding:2em 0; ">
            <button type="button" class="btn btn-success btn-block" id="generate-excel">
                将表格转换为Excel
            </button>
        </div>
        <div class="col-md-12" style="padding:2em 0;">
            <div class="table-responsive">
                <table class="table table-bordered" id="test_table">
                    <thead>
                    <tr style='background-color:lightskyblue; color:white; text-align:center;'>
                        <th>编号</th>
                        <th>姓名</th>
                        <th>性别</th>
                        <th></th>
                        <th></th>
                        <th></th>
                    </tr>
                    </thead>
                    <tbody id="tbody"></tbody>
                </table>
            </div>
        </div>
    </div>
</div>
</body>
</html>

10.7 table表头固定

<style>
    /*table固定表头*/
    .diyTable{
        height: 100%;
    }
    .diyTable_tbody{
        height: 100%;
        display:block;
        overflow-y:auto;
    }
    .diyTable_thead{
        width: calc( 100% - 1em );
    }
    .diyTable_tr{
        display:table;
        width:100%;
        table-layout:fixed;
    }
</style>

<div style="height:100%;overflow-y:hidden;" >
    <table id="liChengTongJi_table_table" class="table table-hover table-striped diyTable" >
        <thead class="diyTable_thead">
            <tr id="liChengTongJi_table_title" class="diyTable_tr">
                <th class="col-sm-1">序号</th>
                <th class="col-sm-1">所属车队</th>
                <th class="col-sm-1">车辆名称</th>
                <th class="col-sm-1">车牌号码</th>
                <th class="col-sm-1">统计时间</th>
                <th class="col-sm-1">行驶里程(km)</th>
            </tr>
        </thead>
        <tbody id="liChengTongJi_table_tbody" class="diyTable_tbody">
            <tr class="diyTable_tr">
                <th class="col-sm-1">序号</th>
                <th class="col-sm-1">所属车队</th>
                <th class="col-sm-1">车辆名称</th>
                <th class="col-sm-1">车牌号码</th>
                <th class="col-sm-1">统计时间</th>
                <th class="col-sm-1">行驶里程(km)</th>
            </tr>
        </tbody>
    </table>
</div>

10.8 modal展示时,背景不变深

.modal-backdrop {
    opacity: 0 !important;
    filter: alpha(opacity=0) !important;//解决背景颜色加深问题
}

<button id="liChengTongJi_tree_btn_modal" type="button" class="btn btn-primary btn-lg"  data-toggle="modal" data-target="#liChengTongJi_tree_Modal" style="display:none;"></button>

<div class="modal fade" tabindex="-1" role="dialog" id="liChengTongJi_tree_Modal">
            <div id="liChengTongJi_warp" class="warp" style="position: absolute;margin-top:45px;top:0px;left:calc(17% + 0.5em);padding-left: 6px;
z-index: 1;border: 2px #0071ce solid;width:20%;height: auto;max-height: 90%;overflow-y: scroll;">
                <ul id="liChengTongJi_zuzhijiagou_container" class="list-group">
                </ul>
            </div>
</div><!-- /.modal -->

10.9 设置背景图片和屏幕一样大

body{
    width: 100%;
    height: 100%;
    background: url('../../static/images/bg.png') no-repeat;
    background-size: cover;
}

11 逆向工程EasyCodeMybatisHelper插件

专业版idea自带database,可以使用plugins安装easycode

11.1 安装

(1)File -> Settings -> Plugins安装easycode插件
(2)安装完成后,在File -> Settings -> EasyCode修改模板
(3)在pom中引入fastjson

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.76</version>
</dependency>

(4) 添加mapper扫描注解

@SpringBootApplication
@MapperScan("com.example.tmall.dao")
public class TmallApplication {

    public static void main(String[] args) {
        SpringApplication.run(TmallApplication.class, args);
        System.out.println("main");
    }
}

(5)yml文件中设置mapper路径,数据库信息配置也是必须的

server:
  port: 8090

spring:
  datasource:
    name: lzhtest
    url: jdbc:mysql://127.0.0.1:3306/tmalldemodb?serverTimezone=UTC&charactorEncoding=utf-8
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver

mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.example.tmall.entity

(6)IDEA配置数据库
(7)在表的位置右键,即可生成代码
在这里插入图片描述

11.2 Default Template

(1) entity:

##引入宏定义
$!define

##使用宏定义设置回调(保存位置与文件后缀)
#save("/entity", ".java")

##使用宏定义设置包后缀
#setPackageSuffix("entity")

##使用全局变量实现默认包导入
$!autoImport
import java.io.Serializable;

##使用宏定义实现类注释信息
#tableComment("实体类")
public class $!{tableInfo.name} implements Serializable {
    private static final long serialVersionUID = $!tool.serial();
#foreach($column in $tableInfo.fullColumn)
    #if(${column.comment})/**
    * ${column.comment}
    */#end

    private $!{tool.getClsNameByFullName($column.type)} $!{column.name};
#end

#foreach($column in $tableInfo.fullColumn)
##使用宏定义实现get,set方法
#getSetMethod($column)
#end

}

(2)dao:

##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "Dao"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/dao"))

##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0))
#end

#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}dao;

import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};
import org.apache.ibatis.annotations.Param;
import java.util.List;

/**
 * $!{tableInfo.comment}($!{tableInfo.name})表数据库访问层
 *
 * @author $!author
 * @since $!time.currTime()
 */
public interface $!{tableName} {

    /**
     * 通过ID查询单条数据
     *
     * @param $!pk.name 主键
     * @return 实例对象
     */
    $!{tableInfo.name} queryById($!pk.shortType $!pk.name);
    
    /**
     * 查询全部行数据
     *
     * @return 对象列表
     */
    List<$!{tableInfo.name}> queryAll();

    /**
     * 查询指定行数据
     *
     * @param offset 查询起始位置
     * @param limit 查询条数
     * @return 对象列表
     */
    List<$!{tableInfo.name}> queryAllByLimit(@Param("offset") int offset, @Param("limit") int limit);


    /**
     * 通过实体作为筛选条件查询
     *
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象
     * @return 对象列表
     */
    List<$!{tableInfo.name}> queryByBean($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));

    /**
     * 新增数据
     *
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象
     * @return 影响行数
     */
    int insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));

    /**
     * 修改数据
     *
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象
     * @return 影响行数
     */
    int update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));

    /**
     * 通过主键删除数据
     *
     * @param $!pk.name 主键
     * @return 影响行数
     */
    int deleteById($!pk.shortType $!pk.name);

}

(3)service:

##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "Service"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/service"))

##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0))
#end

#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service;

import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};
import java.util.List;

/**
 * $!{tableInfo.comment}($!{tableInfo.name})表服务接口
 *
 * @author $!author
 * @since $!time.currTime()
 */
public interface $!{tableName} {

    /**
     * 通过ID查询单条数据
     *
     * @param $!pk.name 主键
     * @return 实例对象
     */
    $!{tableInfo.name} queryById($!pk.shortType $!pk.name);
    
    /**
     * 查询全部行数据
     *
     * @return 对象列表
     */
    List<$!{tableInfo.name}> queryAll();

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit 查询条数
     * @return 对象列表
     */
    List<$!{tableInfo.name}> queryAllByLimit(int offset, int limit);
    
    /**
     * 通过实体作为筛选条件查询
     *
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象
     * @return 对象列表
     */
    List<$!{tableInfo.name}> queryByBean($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));

    /**
     * 新增数据
     *
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象
     * @return 实例对象
     */
    $!{tableInfo.name} insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));

    /**
     * 修改数据
     *
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象
     * @return 实例对象
     */
    $!{tableInfo.name} update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));

    /**
     * 通过主键删除数据
     *
     * @param $!pk.name 主键
     * @return 是否成功
     */
    boolean deleteById($!pk.shortType $!pk.name);

}

(4)serviceImpl:

##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "ServiceImpl"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/service/impl"))

##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0))
#end

#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service.impl;

import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};
import $!{tableInfo.savePackageName}.dao.$!{tableInfo.name}Dao;
import $!{tableInfo.savePackageName}.service.$!{tableInfo.name}Service;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * $!{tableInfo.comment}($!{tableInfo.name})表服务实现类
 *
 * @author $!author
 * @since $!time.currTime()
 */
@Service("$!tool.firstLowerCase($!{tableInfo.name})Service")
public class $!{tableName} implements $!{tableInfo.name}Service {
    @Resource
    private $!{tableInfo.name}Dao $!tool.firstLowerCase($!{tableInfo.name})Dao;

    /**
     * 通过ID查询单条数据
     *
     * @param $!pk.name 主键
     * @return 实例对象
     */
    @Override
    public $!{tableInfo.name} queryById($!pk.shortType $!pk.name) {
        return this.$!{tool.firstLowerCase($!{tableInfo.name})}Dao.queryById($!pk.name);
    }
    
    /**
     * 查询全部行数据
     *
     * @return 对象列表
     */
    public List<$!{tableInfo.name}> queryAll(){
        return this.$!{tool.firstLowerCase($!{tableInfo.name})}Dao.queryAll();
    }   

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit 查询条数
     * @return 对象列表
     */
    @Override
    public List<$!{tableInfo.name}> queryAllByLimit(int offset, int limit) {
        return this.$!{tool.firstLowerCase($!{tableInfo.name})}Dao.queryAllByLimit(offset, limit);
    }    
    
    /**
     * 通过实体作为筛选条件查询
     *
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象
     * @return 对象列表
     */
    @Override
    public List<$!{tableInfo.name}> queryByBean($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})){
        return this.$!{tool.firstLowerCase($!{tableInfo.name})}Dao.queryByBean($!tool.firstLowerCase($!{tableInfo.name}));    
    }

    /**
     * 新增数据
     *
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象
     * @return 实例对象
     */
    @Override
    public $!{tableInfo.name} insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) {
        this.$!{tool.firstLowerCase($!{tableInfo.name})}Dao.insert($!tool.firstLowerCase($!{tableInfo.name}));
        return $!tool.firstLowerCase($!{tableInfo.name});
    }

    /**
     * 修改数据
     *
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象
     * @return 实例对象
     */
    @Override
    public $!{tableInfo.name} update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) {
        this.$!{tool.firstLowerCase($!{tableInfo.name})}Dao.update($!tool.firstLowerCase($!{tableInfo.name}));
        return this.queryById($!{tool.firstLowerCase($!{tableInfo.name})}.get$!tool.firstUpperCase($pk.name)());
    }

    /**
     * 通过主键删除数据
     *
     * @param $!pk.name 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById($!pk.shortType $!pk.name) {
        return this.$!{tool.firstLowerCase($!{tableInfo.name})}Dao.deleteById($!pk.name) > 0;
    }
}

(5)Controller:

##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "Controller"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/controller"))
##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0))
#end

#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}controller;

import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};
import $!{tableInfo.savePackageName}.service.$!{tableInfo.name}Service;
import org.springframework.web.bind.annotation.*;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import javax.annotation.Resource;
import java.util.List;

/**
 * $!{tableInfo.comment}($!{tableInfo.name})表控制层
 *
 * @author $!author
 * @since $!time.currTime()
 */
@RestController
@RequestMapping("$!tool.firstLowerCase($tableInfo.name)")
public class $!{tableName} {
    /**
     * 服务对象
     */
    @Resource
    private $!{tableInfo.name}Service $!tool.firstLowerCase($tableInfo.name)Service;

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("selectOne")
    public String selectOne($!pk.shortType id) {
        $!{tableInfo.name} res = this.$!{tool.firstLowerCase($tableInfo.name)}Service.queryById(id);
        JSONObject obj = new JSONObject();
        obj.put("code", 200);
        obj.put("msg", "success");
        obj.put("data", res);
        return obj.toJSONString();
    }
    
    /**
     * 查询全部行数据
     *
     * @return 对象列表
     */
    @GetMapping("selectAll")
    public String selectAll(){
        List<$!{tableInfo.name}> res = this.$!{tool.firstLowerCase($!{tableInfo.name})}Service.queryAll();
        JSONObject obj = new JSONObject();
        obj.put("code", 200);
        obj.put("msg", "success");
        obj.put("data", res);
        return obj.toJSONString();
    }   
    
    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit 查询条数
     * @return 对象列表
     */
    @GetMapping("selectAllForPage")
    public String selectAllForPage(int offset, int limit) {
        List<$!{tableInfo.name}> res = this.$!{tool.firstLowerCase($!{tableInfo.name})}Service.queryAllByLimit(offset, limit);
        JSONObject obj = new JSONObject();
        obj.put("code", 200);
        obj.put("msg", "success");
        obj.put("data", res);
        return obj.toJSONString();
    }
    
    /**
     * 通过实体作为筛选条件查询
     *
     * @param  json 实例对象的JSON字符串
     * @return 对象列表
     */
    @PostMapping("selectByBean")
    public String queryByBean(@RequestBody String json){
        JSONObject jsonObject = JSON.parseObject(json);
        $!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}) = JSON.parseObject(jsonObject.toJSONString(), $!{tableInfo.name}.class);
        List<$!{tableInfo.name}> res = this.$!{tool.firstLowerCase($!{tableInfo.name})}Service.queryByBean($!tool.firstLowerCase($!{tableInfo.name}));
        JSONObject obj = new JSONObject();
        if (res.size() > 0){
            obj.put("code", 200);
            obj.put("msg", "success");
            obj.put("data", res);
        }else{
            obj.put("code", 201);
            obj.put("msg", "查无信息");
            obj.put("data", res);
        }
        return obj.toJSONString();
    }
    
    /**
     * 新增数据
     *
     * @param  json 实例对象的JSON字符串
     * @return 实例对象
     */
    @PostMapping("insert")
    public String insert(@RequestBody String json){
        JSONObject jsonObject = JSON.parseObject(json);
        $!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}) = JSON.parseObject(jsonObject.toJSONString(), $!{tableInfo.name}.class);
        this.$!{tool.firstLowerCase($!{tableInfo.name})}Service.insert($!tool.firstLowerCase($!{tableInfo.name}));
        JSONObject obj = new JSONObject();
        obj.put("code", 200);
        obj.put("msg", "success");
        obj.put("data", $!tool.firstLowerCase($!{tableInfo.name}));
        return obj.toJSONString();
    }
    
    /**
     * 修改数据
     *
     * @param json 实例对象的JSON字符串
     * @return 实例对象
     */
    @PostMapping("update")
    public String update(@RequestBody String json){
        JSONObject jsonObject = JSON.parseObject(json);
        $!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}) = JSON.parseObject(jsonObject.toJSONString(), $!{tableInfo.name}.class);
        this.$!{tool.firstLowerCase($!{tableInfo.name})}Service.update($!tool.firstLowerCase($!{tableInfo.name}));
        JSONObject obj = new JSONObject();
        obj.put("code", 200);
        obj.put("msg", "success");
        obj.put("data", $!tool.firstLowerCase($!{tableInfo.name}));
        return obj.toJSONString();
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @GetMapping("delete")
    public String deleteById($!pk.shortType id) {
        boolean res = this.$!{tool.firstLowerCase($!{tableInfo.name})}Service.deleteById(id);
        JSONObject obj = new JSONObject();
        obj.put("code", 200);
        obj.put("msg", "success");
        obj.put("data", res);
        return obj.toJSONString();
    }

}

(6)mapper:

##引入mybatis支持
$!mybatisSupport

##设置保存名称与保存位置
$!callback.setFileName($tool.append($!{tableInfo.name}, "Dao.xml"))
$!callback.setSavePath($tool.append($modulePath, "/src/main/resources/mapper"))

##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0))
#end

<?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="$!{tableInfo.savePackageName}.dao.$!{tableInfo.name}Dao">

    <resultMap id="BaseResultMap" type="$!{tableInfo.savePackageName}.entity.$!{tableInfo.name}">
        <!--@Table $!{tableInfo.originTableName}-->
#foreach($column in $tableInfo.fullColumn)
        <result property="$!column.name" column="$!column.obj.name" jdbcType="$!column.ext.jdbcType"/>
#end
    </resultMap>

    <!--查询单个-->
    <select id="queryById" resultMap="BaseResultMap">
        select
          #allSqlColumn()

        from $!{tableInfo.obj.parent.name}.$!tableInfo.obj.name
        where $!pk.obj.name = #{$!pk.name}
    </select>
    
    <!--查询全部数据-->
    <select id="queryAll" resultMap="BaseResultMap">
        select
          #allSqlColumn()

        from $!{tableInfo.obj.parent.name}.$!tableInfo.obj.name
    </select>

    <!--查询指定行数据-->
    <select id="queryAllByLimit" resultMap="BaseResultMap">
        select
          #allSqlColumn()

        from $!{tableInfo.obj.parent.name}.$!tableInfo.obj.name
        limit #{offset}, #{limit}
    </select>

    <!--通过实体作为筛选条件查询-->
    <select id="queryByBean" resultMap="BaseResultMap">
        select
          #allSqlColumn()

        from $!{tableInfo.obj.parent.name}.$!tableInfo.obj.name
        <where>
#foreach($column in $tableInfo.fullColumn)
            <if test="$!column.name != null#if($column.type.equals("java.lang.String")) and $!column.name != ''#end">
                and $!column.obj.name = #{$!column.name}
            </if>
#end
        </where>
    </select>

    <!--新增所有列-->
    <insert id="insert" keyProperty="$!pk.name" useGeneratedKeys="true">
        insert into $!{tableInfo.obj.parent.name}.$!{tableInfo.obj.name}(#foreach($column in $tableInfo.otherColumn)$!column.obj.name#if($velocityHasNext), #end#end)
        values (#foreach($column in $tableInfo.otherColumn)#{$!{column.name}}#if($velocityHasNext), #end#end)
    </insert>

    <!--通过主键修改数据-->
    <update id="update">
        update $!{tableInfo.obj.parent.name}.$!{tableInfo.obj.name}
        <set>
#foreach($column in $tableInfo.otherColumn)
            <if test="$!column.name != null#if($column.type.equals("java.lang.String")) and $!column.name != ''#end">
                $!column.obj.name = #{$!column.name},
            </if>
#end
        </set>
        where $!pk.obj.name = #{$!pk.name}
    </update>

    <!--通过主键删除-->
    <delete id="deleteById">
        delete from $!{tableInfo.obj.parent.name}.$!{tableInfo.obj.name} where $!pk.obj.name = #{$!pk.name}
    </delete>

</mapper>

11.3 社区版idea没有database插件,安装方法如下

File -》settings -》Plugins -》搜索Database Navigator -》安装即可

连接时异常:

在这里插入图片描述
在这里插入图片描述

本项目示例基于spring boot 最新版本(2.1.9)实现,Spring BootSpring Cloud 学习示例,将持续更新…… 在基于Spring BootSpring Cloud 分布微服务开发过程中,根据实际项目环境,需要选择、集成符合项目需求的各种组件和积累各种解决方案。基于这样的背景下,我开源了本示例项目,方便大家快速上手Spring BootSpring Cloud 。 每个示例都带有详细的介绍文档、作者在使用过程中踩过的坑、解决方案及参考资料,方便快速上手为你提供学习捷径,少绕弯路,提高开发效率。 有需要写关于spring bootspring cloud示例,可以给我提issue哦 ## 项目介绍 spring boot demo 是一个Spring BootSpring Cloud的项目示例,根据市场主流的后端技术,共集成了30+个demo,未来将持续更新。该项目包含helloworld(快速入门)、web(ssh项目快速搭建)、aop(切面编程)、data-redis(redis缓存)、quartz(集群任务实现)、shiro(权限管理)、oauth2(四种认证模式)、shign(接口参数防篡改重放)、encoder(用户密码设计)、actuator(服务监控)、cloud-config(配置中心)、cloud-gateway(服务网关)、email(邮件发送)、cloud-alibaba(微服务全家桶)等模块 ### 开发环境 - JDK1.8 + - Maven 3.5 + - IntelliJ IDEA ULTIMATE 2019.1 - MySql 5.7 + ### Spring Boot 模块 模块名称|主要内容 ---|--- helloworld|[spring mvc,Spring Boot项目创建,单元测试](https://github.com/smltq/spring-boot-demo/blob/master/helloworld/HELP.md) web|[ssh项目,spring mvc,过滤器,拦截器,监视器,thymeleaf,lombok,jquery,bootstrap,mysql](https://github.com/smltq/spring-boot-demo/blob/master/web/HELP.md) aop|[aop,正则,前置通知,后置通知,环绕通知](https://github.com/smltq/spring-boot-demo/blob/master/aop/HELP.md) data-redis|[lettuce,redis,session redis,YAML配置,连接池,对象存储](https://github.com/smltq/spring-boot-demo/blob/master/data-redis/HELP.md) quartz|[Spring Scheduler,Quartz,分布式调度,集群,mysql持久化等](https://github.com/smltq/spring-boot-demo/blob/master/quartz/HELP.md) shiro|[授权、认证、加解密、统一异常处理](https://github.com/smltq/spring-boot-demo/blob/master/shiro/HELP.md) sign|[防篡改、防重放、文档自动生成](https://github.com/smltq/spring-boot-demo/blob/master/sign/HELP.md) security|[授权、认证、加解密、mybatis plus使用](https://github.com/smltq/spring-boot-demo/blob/master/security/HELP.md) mybatis-plus-generator|[基于mybatisplus代码自动生成](https://github.com/smltq/spring-boot-demo/blob/master/mybatis-plus-generator) mybatis-plus-crud|[基于mybatisplus实现数据库增、册、改、查](https://github.com/smltq/spring-boot-demo/blob/master/mybatis-plus-crud) encoder|[主流加密算法介绍、用户加密算法推荐](https://github.com/smltq/spring-boot-demo/blob/master/encoder/HELP.md) actuator|[autuator介绍](https://github.com/smltq/spring-boot-demo/blob/master/actuator/README.md) admin|[可视化服务监控、使用](https://github.com/smltq/spring-boot-demo/blob/master/admin/README.md) security-oauth2-credentials|[oauth2实现密码模式、客户端模式](https://github.com/smltq/spring-boot-demo/blob/master/security-oauth2-credentials/README.md) security-oauth2-auth-code|[基于spring boot实现oauth2授权模式](https://github.com/smltq/spring-boot-demo/blob/master/security-oauth2-auth-code/README.md) mybatis-multi-datasource|[mybatis、数据库集群、读写分离、读库负载均衡](https://github.com/smltq/spring-boot-demo/blob/master/mybatis-multi-datasource) template-thymeleaf|[thymeleaf实现应用国际化示例](https://github.com/smltq/spring-boot-demo/blob/master/template-thymeleaf) mq-redis|[redis之mq实现,发布订阅模式](https://github.com/smltq/spring-boot-demo/blob/master/mq-redis) email|[email实现邮件发送](https://github.com/smltq/spring-boot-demo/blob/master/email) jGit|[java调用git命令、jgit使用等](https://github.com/smltq/spring-boot-demo/blob/master/jGit) webmagic|[webmagic实现某电影网站爬虫示例](https://github.com/smltq/spring-boot-demo/blob/master/webmagic) netty|[基于BIO、NIO等tcp服务器搭建介绍](https://github.com/smltq/spring-boot-demo/blob/master/netty) ### Spring Cloud 模块 模块名称|主要内容 ---|--- cloud-oauth2-auth-code|[基于spring cloud实现oath2授权模式](https://github.com/smltq/spring-boot-demo/blob/master/cloud-oauth2-auth-code) cloud-gateway|[API主流网关、gateway快速上手](https://github.com/smltq/spring-boot-demo/blob/master/cloud-gateway) cloud-config|[配置中心(服务端、客户端)示例](https://github.com/smltq/spring-boot-demo/blob/master/cloud-config) cloud-feign|[Eureka服务注册中心、负载均衡、声明式服务调用](https://github.com/smltq/spring-boot-demo/blob/master/cloud-feign) cloud-hystrix|[Hystrix服务容错、异常处理、注册中心示例](https://github.com/smltq/spring-boot-demo/blob/master/cloud-hystrix) cloud-zuul|[zuul服务网关、过滤器、路由转发、服务降级、负载均衡](https://github.com/smltq/spring-boot-demo/blob/master/cloud-zuul) cloud-alibaba|[nacos服务中心、配置中心、限流等使用(系列示例整理中...)](https://github.com/smltq/spring-boot-demo/blob/master/cloud-alibaba) #### Spring Cloud Alibaba 模块 模块名称|主要内容 ---|--- nacos|[Spring Cloud Alibaba(一)如何使用nacos服务注册和发现](https://github.com/smltq/spring-boot-demo/blob/master/cloud-alibaba/README1.md) config|[Spring Cloud Alibaba(二)配置中心多项目、多配置文件、分目录实现](https://github.com/smltq/spring-boot-demo/blob/master/cloud-alibaba/README2.md) Sentinel|[Spring Cloud Alibaba(三)Sentinel之熔断降级](https://github.com/smltq/spring-boot-demo/blob/master/cloud-alibaba/README3.md) Dubbo|[Spring Cloud Alibaba(四)Spring Cloud与Dubbo的融合](https://github.com/smltq/spring-boot-demo/blob/master/cloud-alibaba/README4.md) RocketMQ|[Spring Cloud Alibaba(五)RocketMQ 异步通信实现](https://github.com/smltq/spring-boot-demo/blob/master/cloud-alibaba/README5.md) ### 其它 模块名称|主要内容 ---|--- leetcode|[力扣题解目录](https://github.com/smltq/spring-boot-demo/blob/master/leetcode) ## Spring Boot 概述 Spring Boot简化了基于Spring的应用开发,通过少量的代码就能创建一个独立的、产品级别的Spring应用。 Spring BootSpring平台及第三方库提供开箱即用的设置,这样你就可以有条不紊地开始。多数Spring Boot应用只需要很少的Spring配置。 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Sprin
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值