[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hdkt2cEr-1668096223478)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220916221010142.png)]
对于数据访问层,无论是 SQL(关系型数据库) 还是 NOSQL(非关系型数据库),Spring Boot 底层都是采用 Spring Data 的方式进行统一处理。
Spring Boot 底层都是采用 Spring Data 的方式进行统一处理各种数据库,Spring Data 也是 Spring 中与 Spring Boot、Spring Cloud 等齐名的知名项目。
Sping Data 官网:https://spring.io/projects/spring-data
数据库相关的启动器 :可以参考官方文档:
https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/htmlsingle/#using-boot-starter
1,整合JDBC
1,创建项目
添加默认的环境,导入jdbc,和mysql驱动
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GZUUtvQD-1668096223481)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220917134422921.png)]
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
2,在springboot核心配置文件中添加数据源
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver #数据库驱动,8.0以上版本的
username: root #数据库用户名
password: 123456 #数据库密码
url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC #链接路径
#mybatis 数据库的名字 useUnicode=true&characterEncoding=utf-8 防止乱码 serverTimezone=UTC 时区设置为中国
3,使用springboot的内置类的方法操作数据库
主要两个:
使用内置类都需要自动装配
//springboot内置的一个模板类,里面包含处理SQL操作的方法
@Autowired
JdbcTemplate jdbcTemplate;(具体方法)
//springboot内置的一个模板类,里面包含数据源的信息
// springBoot默认数据源:class com.zaxxer.hikari.HikariDataSource
@Autowired
DataSource dataSource;(有关数据源)
4,调方法操作数据库
JdbcTemplate常用方法:
execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;
query方法及queryForXXX方法:用于执行查询相关语句;
call方法:用于执行存储过程、函数相关语句。
/**
* 注意,jdbctemplate的方法是可以传递参数的,同时SQL可以动态传递数据,方式和原来一样
*/
//查询信息
String sql="select * from user";
List<Map<String,Object>> list=jdbcTemplate.queryForList(sql);
System.out.println(list.get(0).toString());
//删除信息
String sql2="delete from user where id='1'";
int delete=jdbcTemplate.update(sql2);//删除,修改都是用的updata方法,SQL不一样
System.out.println(delete);
//修改信息
String sql3="update user set name='王五' where id='2'";
int update=jdbcTemplate.update(sql3);
System.out.println(update);
//增加信息
String sql4="insert into user(id,name,pwd) value(4,'蔡闪','123456')";
int add=jdbcTemplate.update(sql4);
System.out.println(add);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aMRwvP8p-1668096223482)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220917160525495.png)]
注意点:
1,springboot默认的数据库是8.0+(8+版本要添加时区)的所以如果直接在创建项目时导入mysql驱动那么会报错
nested exception is java.sql.SQLNonTransientConnectionException: CLIENT_PLUG
解决方法:
降低mysql驱动版本
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.43</version>
</dependency>
变为:========5.1版本的
2,整合Druid数据源
Druid 是阿里巴巴开源平台上一个数据库连接池实现,结合了 C3P0、DBCP 等 DB 池的优点,同时加入了日志监控。
Druid 可以很好的监控 DB 池连接和 SQL 的执行情况,天生就是针对监控而生的 DB 连接池。
Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。
Spring Boot 2.0 以上默认使用 Hikari 数据源,可以说 Hikari 与 Driud 都是当前 Java Web 上最优秀的数据源,我们来重点介绍 Spring Boot 如何集成 Druid 数据源,如何实现数据库监控。
Github地址:https://github.com/alibaba/druid/
2,1添加Druid数据源
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>
2,2切换数据源
通过spring.datasource.type 指定数据源。
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
#type后面接的是数据源的路径
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BKf6VDOU-1668096223482)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220917164608450.png)]
2,3druid数据源特殊功能
切换成功,就可以设置数据源连接初始化大小、最大连接数、等待时间、最小连接数 等设置项;可以查看源码
#Spring Boot 默认是不注入这些属性值的,需要自己绑定
#druid 数据源专有配置
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
#**************************** 核心 ****************************************
#配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
#如果允许时报错 java.lang.ClassNotFoundException: org.apache.log4j.Priority
#则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
.看到需要用到log4j,所以需要在pom中导入log4j的依赖
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
2,3,1 自己修改druid配置
现在需要程序员自己为 DruidDataSource 绑定全局配置文件中的参数,再添加到容器中,而不再使用 Spring Boot 的自动生成了;我们需要 自己添加 DruidDataSource 组件到容器中,并绑定属性;
@Configuration//表示这是一个自定义配置,类似前面的mvcconfig
public class DruidConfig {
//作用是将springboot核心配置文件中前缀为spring.datasource的属性与自定义配置绑定
@ConfigurationProperties(prefix = "spring.datasource")
//这个方法(组件)是核心,@Bean是将这个组件注册到springboot容器中,然后这个组件是指将这个配置文件注册到spring中
//这一套下来,类似于原来的创建application.xml这种文件
@Bean
public DataSource druidDataSource() {
return new DruidDataSource();
}
}
2,3,2打开druid的数据监控页面
在droid配置文件中
//前提:项目是一个web项目,要不然哪来的页面
//配置 Druid 监控管理后台的Servlet;
//内置 Servlet 容器时没有web.xml文件,所以使用 Spring Boot 的注册 Servlet 方式
//死代码
@Bean
public ServletRegistrationBean statViewServlet() {
ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");// "/druid/*"意思是访问druid路径下面的页面就是数据监控页面
// 这些参数可以在 com.alibaba.druid.support.http.StatViewServlet
// 的父类 com.alibaba.druid.support.http.ResourceServlet 中找到
Map<String, String> initParams = new HashMap<>();
//map的key值不能变
initParams.put("loginUsername", "admin"); //后台管理界面的登录账号,
initParams.put("loginPassword", "123456"); //后台管理界面的登录密码
//后台允许谁可以访问
//initParams.put("allow", "localhost"):表示只有本机可以访问
//initParams.put("allow", ""):为空或者为null时,表示允许所有访问
initParams.put("allow", "");
//deny:Druid 后台拒绝谁访问
//initParams.put("kuangshen", "192.168.1.20");表示禁止此ip访问
//设置初始化参数
bean.setInitParameters(initParams);
return bean;
}
配置完毕后,我们可以选择访问 :http://localhost:8080/druid/login.html
2,3,3设置过滤器
//配置 Druid 监控 之 web 监控的 filter
//WebStatFilter:用于配置Web和Druid数据源之间的管理关联监控统计
@Bean
public FilterRegistrationBean webStatFilter() {
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new WebStatFilter());//添加过滤器,自带的过滤器
//exclusions:设置哪些请求进行过滤排除掉,从而不进行统计
Map<String, String> initParams = new HashMap<>();
initParams.put("exclusions", "*.js,*.css,/druid/*,/jdbc/*");
//设置初始化参数
bean.setInitParameters(initParams);
//"/*" 表示过滤所有请求
bean.setUrlPatterns(Arrays.asList("/*"));
return bean;
}
注意点:
DruidConfig文件一定要添加配置注解,在里面配置的一些servlet和filter都要添加@Bean注解
3,整合mybatis
这一步就和普通的mybatis项目没什么大的差距了
存放sql方法的接口(添加@mapper,@repository)
对应的mapper.xml(和原来的写法一致)
在yaml中配置mybatis: mapper-locations: classpath:mybatis/mapper/*.xml(类似原来在注册mapper)
3,1导入相关包
创建项目也需要导入这两个环境
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4JXNpfhP-1668096223483)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220917134422921.png)]
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
3,2yaml中配置数据源
spring:
datasource:
username: root
password: "000000"
#?serverTimezone=UTC解决时区的报错
url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8&useSSL=false&useUnicode=true&characterEncoding=UTF-8&allowPublicKeyRetrieval=true #注意8.0和5.0的区别
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
3,3 创建实体类
3,4 创建接口
@Mapper//表示这是一个mapper接口
@Repository//在容器中注册 等价于 @Component
public interface UserMapper {
public static final int age=18;
List<User> queryUserList();
User queryUserById(Integer id);
int addUser(User user);
int updateUser(User user);
int deleteUserById(Integer id);
}
也可以在springboot的主体类中添加@MapperScan(“mapper包路径”)//可以代替@mapper注解
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VIclQMVm-1668096223483)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220917175919982.png)]
3,5创建mapper.xml文件
接下来该去配置mapper.xml文件了,这里建议创建在resources的目录下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--configuration core file-->
<mapper namespace="com.guo.mapper.UserMapper">
<select id="queryUserList" resultType="User">
</select>
//如果返回结果没有起别名,那么就要写全路径
<!-- <select id="queryUserList"
resultType="com.example.springbootjdbc.pojo.User.User">
select * from user
</select>
-->
</mapper>
3,6在springboot核心配置文件中配置mybatis
mybatis:
type-aliases-package: com.example.springbootjdbc.pojo.User #对包下的类起别名(首字母大小)
mapper-locations: classpath:mybatis/mapper/*.xml #注册mapper.xml classpath:resources资源目录
4,整合Dubbo
1,安装zooKeeper
网址:https://zookeeper.apache.org/releases.html
运行
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RQoMav3i-1668096223483)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220928192648691.png)]
初次运行会报错,没有zoo.cfg配置文件;
解决方案:编辑zkServer.cmd文件末尾添加pause 。这样运行出错就不会退出,会提示错误信息,方便找到原因。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SsKyqls7-1668096223484)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220928192842879.png)]
3、修改zoo.cfg配置文件
将conf文件夹下面的zoo_sample.cfg复制一份改名为zoo.cfg即可。
注意几个重要位置:
dataDir=./ 临时数据存储的目录(可写相对路径)
clientPort=2181 zookeeper的端口号
修改完成后再次启动zookeeper
2,安装Dubbo-admin
1,下载
地址 :https://github.com/apache/dubbo-admin/tree/master
2、解压进入目录
修改 dubbo-admin\src\main\resources \application.properties 指定zookeeper地址
server.port=7001
spring.velocity.cache=false
spring.velocity.charset=UTF-8
spring.velocity.layout-url=/templates/default.vm
spring.messages.fallback-to-system-locale=false
spring.messages.basename=i18n/message
spring.root.password=root
spring.guest.password=guest
dubbo.registry.address=zookeeper://127.0.0.1:2181
//默认情况下是没有改的
开启方式一:
这种方式目前还有问题
3、在项目目录下打包dubbo-admin
mvn clean package -Dmaven.test.skip=true
4、执行 dubbo-admin\target 下的dubbo-admin-0.0.1-SNAPSHOT.jar
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dVZuH0Oh-1668096223484)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220928212813041.png)]
java -jar dubbo-admin-0.0.1-SNAPSHOT.jar
【注意:zookeeper的服务一定要打开!】
执行完毕,我们去访问一下 http://localhost:7001/ , 这时候我们需要输入登录账户和密码,我们都是默认的root-root;
登录成功后,查看界面
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8X6Twbyo-1668096223485)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220928232724616.png)]
5,报错:
解决方法:
首先是ui模块构建失败,所以找到ui模块的pom.xml
找到导入失败的插件com.github.eirslett:frontend-maven-plugin
手动去远程仓库查找对应的插件
链接:https://repo.maven.apache.org/maven2/com/github/eirslett/frontend-maven-plugin/
更名为刚刚pom.xml所对应的名字 frontend-maven-plugin-1.9.0.jar (对应版本号
再前往pom.xml修改对应配置,与刚刚在本地仓库创建的文件夹、文件名一致
然后把
<goals>
<goal>npm</goal>
</goals>
都删除掉
防止构建时用npm的方式下载插件
完整代码:
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.9.0</version>
<executions>
<execution>
<id>install node and npm</id>
<configuration>
<nodeVersion>v9.11.1</nodeVersion>
</configuration>
</execution>
<!-- Install all project dependencies -->
<execution>
<id>npm install</id>
<!-- optional: default phase is "generate-resources" -->
<phase>generate-resources</phase>
<!-- Optional configuration which provides for running any npm command -->
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
<!-- Build and minify static files -->
<execution>
<id>npm run build</id>
<configuration>
<arguments>run build</arguments>
</configuration>
</execution>
</executions>
</plugin>
再用maven打包就ok啦
mvn clean package -Dmaven.test.skip=true
大概原理是,maven在远程仓库找不到该依赖,我们用我们找到的依赖放到本地仓库,构建时会先检查本地仓库是否有所需依赖。
开启方式二
第一步,启动zookeeper
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KSNzzF9n-1668096223485)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220928233605597.png)]
第二步: 启动 dubbo-admin-ui:
cd
找到 dubbo-admin-ui 执行:npm run dev
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AgO9xyUi-1668096223485)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220928233740103.png)]
如果报错vue-cli不是内部命令,就重新npm install一下
第三步:idea启动dubbo-admin-server
找到 dubbo-admin-server
下的 application,并 配置端口号 :
server.port = 7001
之后启动 项目:
值得注意的是:
此时 dubbo-admin-ui
下的vue.config.js
:
需要将 target 的端口号与后端的一致:
最后,点击如下任意一个 即可启动前端页面
Dubbo(注册中心)分布式开发
1,创建一个**provider(服务者)**项目
这个项目相当于是一个服务的提供者
2,创建一个**Consumer(消费者)**项目
这个项目相当于一个服务的消费者
3,在两个项目中导入需要的包
<!--dubbo-->
<!--将服务提供者注册到注册中心,我们需要整合Dubbo和zookeeper,所以需要导包-->
<!-- Dubbo Spring Boot Starter -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.3</version>
</dependency>
<!--zookeeper-->
<!--zookeeper的包我们去maven仓库下载,zkclient;-->
<!-- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient -->
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.12.0</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.14</version>
<!--排除这个slf4j-log4j12
【新版的坑】zookeeper及其依赖包,解决日志冲突,还需要剔除日志依赖;-->
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
4,修改消费者,服务者的配置文件
《服务者配置文件》
#当前应用名字(项目名)
dubbo.application.name=provider-server
#注册中心地址(这个地址和你的zookeeper相关)
dubbo.registry.address=zookeeper://127.0.0.1:2181
#扫描指定包下服务(需要注册在注册中心上给消费者使用的服务【自己写的方法和类】)
dubbo.scan.base-packages=com.example.providerserver.service
#服务者端口
server.port=8081
#因为之前的20880端口被占,所以修改端口
dubbo.protocol.port=20881
《消费者配置文件》
#当前应用名字(项目名)
dubbo.application.name=consumer-server
#注册中心地址
dubbo.registry.address=zookeeper://127.0.0.1:2181
#服务者是将自己的信息,和自己要发送的服务传递给注册中心
#消费者是将自己的信息发送给注册中心去取服务
5,将服务放在容器和注册中心中
@Component //放在容器中,这里不用service注解的原因是为了区分
@Service//项目一启动发布到注册中心
//service关联的类import org.apache.dubbo.config.annotation.Service;
public class TicketServiceImpl implements TicketService{
@Override
public String getTicket() {
return "《狂神说Java》";
}
}
6,开启zookeeper,然后启动服务者项目就可以看到服务被注册
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dMdo9pFQ-1668096223486)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220929221716552.png)]
也可以通过dubbo-admin看
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Iax9fvlt-1668096223486)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220929224440444.png)]
消费者取服务的流程
1,导入相关包
2,编写配置类
3,编写一个获取服务的类
@Component //注入到容器中
public class UserService {
/**
* 我们需要去拿去注册中心的服务
* @Reference 远程应用自动装配
* 等价于 @Autowired的自动装配,只是Autowired是装配本地项目的类
* @Reference 是装配其他项目中的类(在注册中心注册的接口)
* 此时可以发现会爆红这是因为本项目没有这个类
* 解决方法:
* 1,引用pom坐标(不会)
* 2,创建一个被引用类相同的路径类,内容可以不一样
*/
@Reference//远程注册这个类
TicketService ticketService;
public void buyTicket(){
String ticket = ticketService.getTicket();
System.out.println("在注册中心买到"+ticket);
}
}
4,还原远程注册接口的路径
首先服务者向注册中心注册的服务类路径:
在消费者项目中还原这个路径(可以不用遵循所有资源要在springboot主类的同一路径上)
里面的方法可以不同,但是服务者有的消费者尽量有(因为一会要调这个方法)
5,编写测试类
@SpringBootTest
class ConsumerServerApplicationTests {
//这里自动装配的是那个调服务的类
@Autowired
UserService userService;
@Test
public void contextLoads() {
userService.buyTicket();
}
}
6,运行结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a3T6qYIu-1668096223487)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220929231930809.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6Q7MkWNA-1668096223487)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220929233255504.png)]
可能报错
Fail to start server(url: dubbo://192.168.0.9:20880/service
原因:
20880端口被占
只需要修改项目的dubbo端口即可
//在服务者核心配置文件中写
dubbo.protocol.port=20881