文章目录
- 1 SpringBoot小例子练习
- 2 SpringBoot带数据库例子---select
- 3 controller和html交互例子---select
- 4 增删改查
- 5 访问静态资源
- 6 小例子
- 6.1 JS + controller实现页面间跳转
- 6.2 session实现登陆显示(“请登录”和“lzh”互相转换)
- 6.3 购物车,根据选中项动态更新价格
- 6.4 js调用model中的属性参数
- 6.5 ajax使用
- 6.6 iframe父子页面间数据控制
- 6.7 js修改div的css、属性、文字、增删子div
- 6.8 js字符串替换
- 6.9 form上传文件
- 6.10 form ajax上传文件
- 6.11 计时器使用,修改div width无效果
- 6.12 controller返回List,html页面如何接收
- 6.13 controller返回JSONObject,html页面如何接收
- 6.14 组织架构树
- 6.15 导出excel
- 7 数据库操作
- 8 项目迁移
- 9 JS
- 10 html
- 11 逆向工程EasyCodeMybatisHelper插件
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">×</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 -》安装即可
连接时异常: