前言:这是我学习springboot 从0到实战的 实战了,如果你有不懂的地方可以看我前两个学过来的博客,
这里附上链接:
第一部分:传送门:SpringBoot详解,完整版。从0到1!(持更
第二部分:传送门:https://blog.csdn.net/qq_44850489/article/details/109309405
如果还是有不懂得地方可以私信我啦。我们一起想办法解决
springboot实战练习
先给看到的小伙伴源码链接
**学习提示:**我是用idea来编译的,
**学习提示:**如果你拿到了我的源码,建议你看着博客另起一个项目跟这个写,哪里不懂,或者导入一些配置的时候可以从我源码里面拿(里面注释也很详细,自认为很详细了,你应该可以找到,看懂)
传送门链接: https://pan.baidu.com/s/1d6eI3ClOPgUERTjAcGDOqA 提取码: vmua
学习提示: 运行源码需要先启动zookeeper 和redis,在下面会讲到。
(搓搓手,开始好好写)
ok,上面的技术我再前两个博客都有讲到,就是因为篇幅太长我才分开的,有需要可以去看哦
一,我是先建立了一个空项目,然后再在里面建立了三个子模块:建立 interface consumer ,provider(提供者) 三个模块。
二,源码里我已经给了数据库的sql文件哦,需要先将数据库搭建好。然后在provider导入代码自动生成的配置文件。扫描项目路径中的xml等配置。配置好数据库,然后配置mabatis起步依赖,mysql数据库驱动,以及mabatis代码自动生成依赖,然后利用代码生成功能生成model和mapper。在启动类上添加dubbo的注解扫描(记住导包的时候会有两个包,选着有dubbo的)
扫描项目路径中的xml等配置文件 就是指:
<!--扫描项目路径中的xml等配置文件-->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
三,然后将model放到interface接口模块中,然后在里面写service接口(也就是需求),然后打成jar包,在provider,consumer中引入interface的坐标,
四,然后写service接口的实现类。配置@Componetspring注解,然后在配置@Service注解,这个注解引入dubbo包中的,因此导入dubbo,顺便导入zookeeper的起步依赖。(这是再interface模块中哦)
五,打开zookeeper,测试运行private是否正常启动 ,这个(zookeeper)是需要我们自己下载的,我记得下载带有bin的包,然后将conf中的zoo_sample.cfg复制一份重命名为zoo.cfg。再bin目录下 以管理员身份运行zkSercer.cmd (win10)大家可以自行百度安装
我在csdn中也将已经配置好的打包放到了我的资源里,需要自提;https://download.csdn.net/download/qq_44850489/13061424
第一个功能 分页查询,先在mapper中书写相关sql
sql语句接收参数用map封装,需要两个,一个是从多少条开始查(startRow),一个是每次查多少条(pageSize)。
select
<include refid="Base_Column_List>
from u_user
limit #{startRow,jdbcType=INTEGER}, #{papeSize,jdbcType=INTEGER}
在mapper中生成相应的接口。
然后再service层中创建相应的接口方法,实现此方法(我的实现接口的类建立再private中)再实现类中直接调用mapper中相关方法。并返回结果
六,打开consumer端,书写Controller层代码,调用远程服务@Reference,从远程拿到类(就是引入interface中的service),调用其中的分页功能和总数功能,要查询第几个分页要从前端传递过来,(@RequestParam(value=“页码”,required=false) Integer 页码)传递过来,如果为空,则设置默认值
再将数据放到model类中,新建index页面,引入tymleaf 。返回到页面index中,在index页面中引用bootstrap前端框架。在菜鸟教程上找到引用固定格式即可。
七,利用tymeleaf中的each遍历出数据,查看结果。
这里总结:实现分页查询,向后台交互两个数据,1:从多少开始查,一次查多少条。2:总共多少条数据。
然后在controller中,规定一次查多少,然后通过 总数 / 一次查多少 计算出一共有多少页。然后通过
要查页的开始条数 = (要查页 -1) * 每页多少数
然后通过if语句使得当处在第一页时 上一页和首页两个按钮变成灰色。也解决访问超过合法页数时的基本情况。
在页面上tymeleaf中通过对传递过来的当前页,加一 ,减一来实现传递要查询的页码
然后添加 添加,修改,删除按钮,并跳转到指定的controller。
八,实现添加功能,
在页面上指定 跳转到指定controller层,controller层指定其跳转到添加页面,添加页面也用tymeleaf框架搭建好,提交后 到指定add的controller中,controller中可以直接用 User对象接受数据,这是用springmvc提供的技术,可以直接将表单中的数据提交到user对象中,但是要求表单中的字段名必须和model中的字段名相同。然后调用service层的添加方法。
九,在service层,添加上 添加方法,顺便添加上 删除 修改方法。然后重新打包 install
十,写servicelmp实现接口,调用mapper层中的相关方法即可。
这里值得注意:我遇到问题,我的代码自动生成并没有生成相应的方法,只有添加的一些方法(insert)。需要将GeneratorMapper.xml(我给的源码已经改好,需要的小伙伴自提)中的最后***Example就是关于修改 删除 还有指定查询的改为。
enableSelectByPrimaryKey=“true”
enableUpdateByPrimaryKey=“true”
enableDeleteByPrimaryKey=“true”
然而我还是遇到了问题,网上似乎是说没有办法自动识别主键
后来在节点jdbcConnection里配置useInformationSchema属性,解决了不识别主键问题 (这里修改是直接在全局搜索到这个地方改的,在哪我也不知道)
connectionURL=“
u
r
l
"
u
s
e
r
I
d
=
"
{url}" userId="
url"userId="{username}”
password=“${password}”>
十一,调试好后,我们的update 和delete也容易实现了。先来实现update方法,我们使update方法直接在add方法上面实现。这样我们需要调出要修改的这条数据,所以在点击修改的时候跳转到指定的controller中,在controller中通过接受的id查询到这条语句,。这里通过id获取数据的接口没有写,要补上。在mapper层中的selectByPrimaryKey方法就是通过单个值调用整条数据的方法。
然后放到model中跳转到添加页面,在添加页面上,我们要通过tymeleaf th:value${user?.nick}将数据放到指定的输入框中,并要写一个隐藏的id输入框,将id也写进去一起提交。这里表达式中的?号表示,如果数据有就显示,如果没有就忽略这条语句。如果没有 ? 号、那么再调用添加方法时就会报错,因为调用添加方法的时候model中没有user对象。这样通过有无提交id我们可以知道用户是在添加 还是在修改。
然后也提交到add的controller里面,在add的controller中我们要稍做修改,用if判断是否传进来id,如果传进来id就调用修改的方法。如果没有传进来,就走原来的添加方法。这样我们的修改功能也完成了。
十二,最后的delete的方法简单。跳转到指定的controller中,传递进来id,通过id将数据删除。然后在controller中重定向到index页面。大功告成了。
十三,然后我们再添加redis缓存机制,
这是最后一步:首先引入redis起步依赖,然后配置连接信息,连接地址,连接端口,密码。在service中先注入RedisTemplate,然后调用redisTemplate.opsForValue().get(“totalRows”); 在注意:防止缓存穿透,将在判空里添加锁,synchronize。另外添加和删除都是会改变总数的,所以在添加和删除中也要对缓存进行更新。然后实现redis的key的序列化方式,采用字符串的形式,这样可读性比较好。
同时添加上redis后,我们启动程序之前就要先启动zookeeper和redis之后 先运行private 再运行consumer。