目录
说在前面:
遇到的坑点:
认识Springboot的实体层,服务层和控制层:
实体层:
控制层:
服务层:
DAO/Mapper层(访问mysql的接口,并与之.xml文件对应)
总结:
自从上次用完mybatis后,觉得配置起来完后方便(毕竟再也不用写原生的jdbc代码了),新生起初配置起来因为自己还不是很熟悉,出问题还得自己独自解决。但配置好后好用是真的好用,后面的工作就能省很多时间。而用springboot整合mybatis则更规范化(连通过mybatis获取session都不需要了,通过@Autowired自动在容器中生成mapper接口)。
第一:看别人的博客用的yml去配置数据库驱动和端口信息,它们的yml上的数据库密码就是一串数字,我也用一串数字,结果就是数据库一直连接不上,报错:
java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)
而我用idea测试数据库连接又都能连接上,查了至少3个多小时的博客,直到看到了这篇
SpringBoot数据访问CannotGetJdbcConnectionException: Failed to obtain JDBC Connection异常的解决方式。_一步两步走呀走的博客-CSDN博客
在此感谢这位老哥~
把密码改成字符串形式,一片的错误提示全部解决,特别纪念这个坑点。
第二:关于Mapper或dao接口不能被springboot加载的问题,在service层和control层(即对应的service包和conrol包下)用@Autowired注解下的对象有红线提示,编译也出错。
解决方法是在启动类加上
@MapperScan(value = "emqx.demo.mapper")说明mapper所在的路径。
如果没有MapperScan方法,则是MapperScan注解缺少依赖,添加依赖
org.mybatis
mybatis-spring
1.3.2
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.1.1
这样做之后,用@Autowired注释下的对象依然会有红线,但编译却能够通过。
第三:注意yml配置文件的格式严格对齐,键: 值(":"号后特别注意带一个空格),它是按照缩进来读取配置文件的。
server:
port: 8087
spring:
datasource:
username: root
password: "123547"
url: jdbc:mysql://localhost:3306/devices?useJDBCCompliantTimezoneShift=true&allowPublicKeyRetrieval=true&serverTimezone=UTC&useSSL=false&allowMultiQueries=true
driver-class-name: com.mysql.jdbc.Driver
mybatis:
mapper-locations: mapper/*.xml
type-aliases-package: emqx.demo.entity
springboot的主函数可以理解为开启了一个服务
package emqx;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan(value = "emqx.demo.mapper")
public class MySpringBoot {
public static void main(String[] args) {
SpringApplication.run(MySpringBoot.class, args);
}
}
其中的@SpringBootApplication会自动把该主类下的各级包下competent自动装载到容器中(如果被注解了的)所以该类必须放在包的最外层。
(我一开始并未放最外层,该类也能自动装载,保险起见,还是放最外层)
如我的目录结构
@Component
就是java的pojo对象,需要自动生成实体的get和set方法,因为在对mysql实现CRUD会自动去封装对象也就会自动去调用实体的get和set方法。
@RestController(一个注解相当于几个注解,等效于n行代码)
外界对tomacat服务器接口访问时需要处理的事务层。一般会通过@Autowired自动生成一个对应service对象,并写各种接口请求的方法(比如get或post请求等等,方法里返回service对象的各方法),service对象实现对请求的数据的合法校验或是初步处理后,再调用请求mysql的方法,也就是mapper所映射的sql语句的方法。
package emqx.demo.control;
import emqx.demo.Service.ESP32Service;
import emqx.demo.entity.ESP32;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
public class ESP32Contoler {
@Autowired
private ESP32Service esp32Service;
/**
*
* @param name 被更新的传感器名
* @param state 被更新的传感器状态
*/
@GetMapping("/change/{name}/{state}")
public void update(@PathVariable("name") String name,@PathVariable("state") String state){
Map map= new HashMap();
map.put("sname",name);
map.put("state",state);
System.out.println(map.toString());
esp32Service.updateDeviceState(map);
}
/**
*
* @param name 传感器名
* @return 对应的工作状态
*/
@GetMapping("/DeviceState")
public String Inform(@RequestParam String name){
return esp32Service.GetState(name);
}
/**
* 获取最新传感器数据
* @return 最新数据
*/
@GetMapping("/getlatest")
public ESP32 getlatest(){
return esp32Service.GetlatestData();
}
/**
* 获取全部传感器数据
* @return List
*/
@RequestMapping("/getall")
public List Selsectall( ){
return esp32Service.SelectALL();
}
/**
*
* 测试
* @return yes
*/
@RequestMapping("/alp")
public String test2( ){
return "yes";
}
}
在web上发起对应请求经测试正常执行。
在APIPOST(一个国产的api测试工具)发起get请求也符合预期。
@Service。
为control控制层服务,主要用于对数据的校验和初步处理。(由于只是测试并未做任何对输入参数的校验和初步处理,测试只是直接mapper/dao下的对mysql处理的方法)如下。
package emqx.demo.Service;
import emqx.demo.entity.ESP32;
import emqx.demo.mapper.ESP32Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
@Service
public class ESP32Service {
@Autowired
private ESP32Mapper esp32Mapper;
public List SelectALL(){
return esp32Mapper.SelectALL();
}
public String GetState(String name){
return esp32Mapper.GetState(name);
}
public void updateDeviceState(Map map){
esp32Mapper.updateDeviceState(map);
}
public ESP32 GetlatestData(){
return esp32Mapper.GetlatestData();
}
public void InsertLatestInfo(ESP32 esp32){
esp32Mapper.InsertLatestInfo(esp32);
}
}
package emqx.demo.mapper;
import emqx.demo.entity.ESP32;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
import java.util.Map;
@Mapper
public interface ESP32Mapper {
ListSelectALL();
String GetState(String name);
void updateDeviceState(Map map);
ESP32 GetlatestData();
void InsertLatestInfo(ESP32 esp32);
}
最后就是Mapper下的.xml文件
insert into sensor (temperature, humidity, lightval) values (#{temperature},#{humidity},#{lightval})
update devices.action set state=#{state} where sname=#{sname}
springboot工程开启了一个服务,control层提供接口访问的方法,再调用service层的service对象的相关方法,最后service层调用dao/mapper层下对mysql访问的相关方法。
Control层(食堂窗口)->Service层(食堂后厨)->Dao/Mapper层(食堂仓库(把mysql的处理方法当做是食材))
不知道这比喻贴不贴切,哈哈哈,希望诸君能更进一步理解!