00:00
呃,好,我们继续上课,那么当然的话呢,就是在这里边,呃实际上我们工具类都写完了,当然就是有些同学可能会对说哎,呃它构建权限的一个过程,可能你呃呃这个递归过程呢,可能它并不是说特别的理解,对吧,虽然说我们这里边呃写的代码并不是太长,但是递归这样的一种呃方式呢,它本身并不是呃说特别直观,对吧,那么我们就来举一个例子。假设我现在。要。针对的是哪一个呢?比如说我们我们先来看一下。对吧,你可以看到说是这个权限管理模块呢,它有两个子权限,一个子权限是用户管理,一个是角色管理,对吧?呃,当然我们的这个,呃,第二个字段呢,实际上就是它负权限的ID,那么在这里边的话呢,我们画一个图对吧,当然你不用画图,因为这实际上已经有了OK,他们的副权限ID呢,是二对吧。
01:05
呃,权限ID。呃,我们的这个负权限ID呢,是二,呃,当然它的负权限ID也是二,对吧?好啊,那么我们就可以针对这样的一个树形结构呢,我们跟着代码呢,对吧,我们在大脑里面跑一遍,看他是怎么执行的好。啊,那在这的话呢,我们来看一下,呃,我们把这个代码呢放在这边,OK,那么find children呢,它接收两个参数。第一个参数呢,是。啊,你要寻找哪一个节点的呃子权限对吧。也就是说我们的第一个参数对吧。
02:03
需要寻找子权限的权限,对吧?那么第二个参数是什么呢?第二个参数所有权限组成的列表,好,然后我们来跟着他来执行一下,首先我们把吹node,也就是权限管理二的呃,Children这个字段呢设为空列表,然后呢,我们便利。所有权限组成的列表。对吧?那么你一旦便利到某一个权限,它的负权限ID等于我们当前吹node的ID,我们当前吹no的ID是二,对吧?那么谁的负权限ID是二呢?用户管理权限以及角色管理权限,也就是说只有这两个子节点吧,只有这两个子节点好,也就是说我们这个循环里面呢,会找出两个节点,它的负权限ID是二。
03:05
那么我们就把用户管理权限以及角色管理权限它的层级设置为对吧,权限管理层级加一对吧,权限管理层级加一,好那么设置完以后呢,我们判断啊,就是说这个权限管理这个tree node它的呃,Children,也就是子节点列表是否为空。啊,当然如果为空的话,我们就给它设置为空列表,对吧,如果不为空的话呢,这个if它就进不来,然后呢,吹no的点get children,当然它目前是一个空列表,然后点A对吧,又进行了一次递归调用,注意啊,这是一个递归寻找,递归查找。呃,子节点,哎,我们继续来递归调用它,你会发现find children这个eat是什么呢?比方说。我们eat当前如果是用户管理权限的话,那么他在整个权限列表里面寻找到的子权限是什么呢?对吧,当然他是没有子权限的,所以说它什么都找不着对吧?那我们在这里面递归调用的时候呢,那么它的这个参数呢,就是用户权限,呃,用户管理权限节点,那这个是整个权限的列表,然后呢,诶给他一个空列表对吧?子子节点列表给他一个空列表,然后呢,我们遍历所有的权限对吧?便利所有的权限没有任何一个权限呢,是用户管理权限的子节点,那么。
04:36
我们这个循环呢,实际上它便利完以后呢,它没有任何一个义会执行,对吧,没有任何一个义府会执行。那么呃它便利完以后呢,就直接返回了,所以说返回以后呢,我们就会把用户管理权限呢,添加到呃权限管理的子节点列表里面,对吧?当然角色管理呢,它也是走同样的一个流程,也就是说如果针对这个权限管理这个呃ID为二的这个权限,我们来运行这个find children的话呢,那最终我们权限管理的子权限列表里面就是用户管理和角色管理,对吧?用户管理和角色管理,那么这个递归调用的话呢,同时它会把用户管理和对吧角色管理去寻找一下他们的子节点,那么最后会发现他们呃并没有任何子节点啊啊,那么呃这样的一个运行过程呢,就把我们的这个呃树形结构呢给它构建出来了,对吧?大家可以在纸上画一下,呃,那你就可以看得比较清楚了,好。
05:43
啊,那接下来的话呢,我们就来编写这个,呃,就是说用户管理模块的一个增删查改的这样的一个服务,对吧?所以我们在这呢,新建一个软件包叫做什么呢?叫做service对吧?呃,当然我在编写呃,Service或者说编写对买Co进行增删查改的这个服务的时候呢,我并没有使用什么呢?呃,并没有使用类似于像呃,Spring boot GPA或者说MY,呃,Battu对吧,以及MYBAT呃,Plus这样的工具,那么为什么我没有使用这些orm工具呢?啊,为什么没有使用这些O工具呢?呃,那主要的原因其实就在于我们针对的是大家刚学完大数据,并且呃,大家。
06:40
没有什么说后端开发的经验对吧?那这是第一点,那么我们直接使用JDBC驱动对数据库进行增删查改的话呢,呃,那么大家会会了解的更清楚对吧?这是第一点,呃,那么第二点的话呢,就是呃。我们直接使用GDBC这样的最底层的驱动呢,呃,大家可以明白说我们呃增删查海数据库的一个过程是什么,并且由于我们使用的是最底层的GDPC驱动,所以说它的性能是非常好的,对吧?性能非常好的,而且优化起来也非常的方便,呃,所以说在一些Java程序员里边呢。
07:21
它直接使用最底层的JDBC驱动呢,呃,实际上也是非常流行的,因为我们使用最底层的驱动的话呢,呃,所有的控制权都在我们的手里面,对吧?啊,比方说你可以针对。每一个API。对吧,都开一个新的连接对吧?然后在呃,就是说API请求完毕的时候呢,把这个呃连接给它关闭掉,对吧?那么你可以进一步比方说呃,如果我们请求的数量很多,对吧,并发很高的话呢,那你可以呃使用连接池呀,或者说使用nit啊这样的一些异步IO这样的一些工具,对吧,那都是可以的,也就是你使用最底层的呃这样的驱动的话呢,那么控制权就都在我们手里边,而像springb的GPA啊,或者说像买BAT这样的orm工具呢,它实际上呃,它是基于JDBC封装的,对吧?它封装的抽象层级太高,那么你想要进行优化的时候呢,其实就不是特别方便了,对吧?呃,所以基于这样的考虑的话呢,我们就直接使用GDBCOK,那在这的话呢,我们首先在service里边,我们创建一个,呃,什么类呢?呃,创建一个叫做data base这样的一个类啊,那么这个。
08:38
Data呢,里边主要存储了一些我们的,呃,比方说MYSQL的地址。呃,以及用户名和密码对吧?好,那在这儿的话呢,我们就是public static string driver对吧?也就是说你使用的driver是什么呢?我们使用的driver是com点买Cq.CG.gdbc.driver对吧?呃,实际上你通过这个driver呢,你就可以看得出来,呃,其实我们要访问的呢,是买CQ的数据库,Public static string对吧?那这个是URL,那么URL是什么呢?URL就是JDBC冒号,买Q冒号双斜杠,Localhost冒号3306。
09:32
对吧,斜杠对吧,数据库的名字是云台下划线的命啊,然后呢,我们把我们不使用SSL这样的加密协议,所以说在这的话是false,呃,然后呢,我们。还可以往数据库里边对吧,也就是说我们的这个呃,Character encoding对吧,我们的编码方式呢,是UTF8编码啊,那这样的话呢,我们就把呃数据库的这样的URL呢,就已经写好了。
10:08
呃,然后呢,我们写完这个URL以后呢,当然在这的话呢,你就是还必须写用户名和密码对吧?我的用户名是root,当然你们要写的是自己的买CQ的用户名和密码,对吧?啊,当然我的密码呢也是root好,那这样的话,我们database呃这个类就写好了,它其实里面就是保存了一些我们的呃数据库的一些信息,OK,那我们写好这个数据库的信息之后呢,接下来我们要写什么呢?比如说接下来我们可以写一个叫做呃,User service这样的一个类,对吧?啊实际上这个user service呢,它基本上他做的事情就是针对user表进行增删查改,对吧?针对user表进行增删查改啊。
11:08
那我们增删查来我们要编写的第一个服务函数,或者说工具函数呢,那就是获取所有的用户信息,对吧?那我们怎么获取所有的用户信息呢?Public static list,当然它获取的呢,就是我们的。对吧,User这样的一个并类的列表,对吧?因为你获取的是所有的用户信息嘛,呃,那我们的函数名呢,就是get all users啊,没有任何参数啊,那么在这的话呢,我们就是针对每一个服务呢,我们都直接开一个,呃,什么呢,开一个这个JDBC连接啊,然后呢,从里面去取数据,对吧?当然你后期优化的时候呢,你可以自己实现一个连接池啊之类的,这个都是没有问问题的,呃,因为实现一个连接池呢,呃,本身也不是说特别复杂的一个事情,对吧?首先我们指定呃这个driver,也就是驱动。
12:12
对吧,首先我们指定这个driver驱动,呃,那么当然它是我们买CQ的一个驱动,然后呢,在这的话呢,我们是需要catch,一些异常的CQ exception竖杠对吧,以及一个class not found exception对吧?然后在这里面的话呢,我们就是1.print。啊stares呃,我们最后的话呢,我们可以返回一个空列表对吧,也就是说没有查到任何用户信息的话呢,我们可以返回一个空列表啊,然后接下来的话呢,我们首先来这个设置,设置驱动类对吧,然后呢,我们。获取数据库的连接。
13:01
获取数据库的连接对吧?Connection等于什么呢?Driver manager.get connection对吧?呃,当然这个get connection的话呢,里边就是database.url对吧?第一个参数,那第二个参数呢,就是呃,我们的这个username了,对吧?第二参数就是我们的username,那么第三个参数呢,就是我们的password,好啊,那这样的话呢,我们就获取了一个数据库的连接,那获取了数据库的连接以后呢,我们构建查询语句对吧?当然由于大家已经学过这个JDBC了,所以说呃,这些应该都不是太复杂的东西哇,Select statement。对吧,那这个就是一个查询语句,然后呢,connection.prepare statement对吧,准备一个呃,这个查询语句,然后呢,是select ID username password from user这张表对吧?呃,当然这个查询语句呢,还是很简单的,我们从user里边呢,查询三列,第一个是ID,第二个是username,第三个是password,对吧?然后呢,我们接下来的话呢,我们执行执行查询对吧?那么它的查询结果呢,是result set等于什么呢?Select statement.execute query对吧,那这个就是执行查询,呃,那么执行查询的话呢,我们再来新建一个users这样的一个呃,Aist,对吧,当然它里边的类呢,是一个呃,就是user这样一个呃,并类。
14:49
呃,我们创建一个空的列表以后呢,这样我们就可以从呃,Result set里面呢,把查询出来的每一行数据都被都给它添加到这个呃,User这个release里边,对吧?好,所以说我们在这的话呢,我们就是提取结果,然后把它放到user里边,While循环result set.next对吧,因为它是个迭代器嘛,我们使用next判断它是否迭代完毕,如果没有迭代完毕的话,也就是说有数据的话,我们把它一条一条的取出来,首先万我们new一个。
15:27
User这样的一个类对吧,然后呢,user.set。User nameme对吧?呃,我们,呃,当然我们可以首先查询这个set ID,我们先查询ID,那么get long这个ID呢,是long类型的,好,然后接下来的话呢,我们user set username啊,Result set.get string对吧?呃,那么它的这个列名呢,是user nameme,然后user.set password对吧,Result set.get string,那么这个是password,然后接下来的话呢,当然我们还需要把这个角色名给它set对吧,给它赋值,但是我们要注意的是什么呢?我们在这个查询语句里边并没有查询它的角色名,换句话说什么呢?也就是我们这个优色表里边,对吧,大家。
16:33
回顾一下,实际上它只有ID,用户名和呃。就是说密码这三个字段,它并没有,呃,角色字段。所以说这里边的话呢,其实我们是需要根据用户ID呢,来把他的角色名查出来。当然就是说我们根据用户ID查询角色名的,呃,这样的一个就是说查找数据库的操作呢,那么它放在user service里面可能不太合适,所以说我们把它放在哪呢?放在role service里面对吧?Get user role name,呃,当然这我们要注意一点,就是我们这个road service呢。
17:15
对不对,我们还没有进行实现对吧,所以说我们一会儿我们就来实现这个service,好,那在这的话呢,就是根据用户ID查询。什么呢?查询角色名啊,当然这个查询操作呢,这个查询操作放在弱service中对吧,放在弱service中啊。然后接下来的话呢,我们在这儿的话,我们就可以users.add对吧,把这个user给它添加进去对不对,添加进去好。啊,然后呢,我们要注意的就是不要忘记把这个语句给关闭掉,对吧,然后呢,不要忘记把连接关闭掉,不要忘记关闭连接对吧?也就是说我们这个打开连接和关闭连接操作呢,它一定要配对,然后我们return user就可以了,我们return user就可以了,好。
18:24
呃,那这一个增删查改操作的话呢,它实际上就是获取了我们所有的用户信息对吧?呃,当然在这里边的话呢,呃,我们的这个rule service对吧,也就是根据用户ID来创建它的,就是说来获取它的角色ID,我们还没有写对吧,我们还没有写好,所以说在这的话呢,我们就可以把。Service里面的get user name呢,先给它写一下,OK,在这里面我首先。新建一个Java类,这个Java类呢,叫做role service,对吧?RA service OK啊,那么在data里边呢,我的这个用户名和密码呢,都是小写,那么我们可以重构一下对吧?呃,因为我们都保持大写会比较好一点,UN password OK啊,当然在这的话呢,我们就可以把它也改一下了,对吧,Username。
19:24
然后呢,把这个也改一下啊,当然大写小写其实都无所谓,你只要知道就可以了,OK,我们现在有了一个Rose service啊,那么有了一个Rose service以后呢,我们现在就要来编写什么呢?编写根据用户ID获取角色名的,对吧?获取角色名称啊,那么它的函数名对吧?呃,是什么呢?Public static,它的角色名返回值是一个string对吧,Get user rule nameme,然后呢,它接收的参数呢,是long user ID对吧,Long类型的,呃,用户ID好,然后在这的话呢,我TRY,然后当然我们这里边还是要捕获一个CQ exception以及一个class not found exception,然后打印我们的,呃,异常站或者说叫错误站,我最后呢,反。
20:24
返回一个空字符串,然后在这儿的话呢,我们还是遵循什么呢?首先呃,设置这个驱动类。对吧,For name,然后这个驱动类呢,是什么呢?Data base.driver呃,设置完驱动类以后呢,我们还是获取什么呢?获取连接对吧?所以说你可以看到这个流程基本上它是一样的,好,data.url data.u name对吧?呃,data.passwor啊,我们这样就获取了一个连接,然后主要的要注意的一点是我们怎么根据用户ID获取角色名呢?呃,我们这里面我们都知道。
21:16
首先我们有一个用户和角色表对吧,所以我们可以根据用户ID呢,在用户角色表里边查出用户ID对应的角色ID,然后呢,我们再根据这个角色ID呢,对不对。在角色表里边查出角色ID所对应的角色名,所以说这个查询其实它是一个两张表的连表查询,对吧,所以说这个我们实际上是一个连表查询,它是个连表查询啊。OK,呃,当然这个连呢是诶连表查询,它其实是个连表查询,当然相信大家应该,呃,因为之前写过很多CQ的话呢,呃,应该不太难理解啊,我们现在我们来写一下这个,呃查询语句connection prepared statement对吧?呃,那么在这的话呢,就是select。
22:16
row.row name,对吧?当然这个是字段,是下划线as row name对吧?我给它起一个别名,From什么呢?From user_row user下划row呢,是用户和角色的一个关系表对吧?当然用户的角色关系表呢,它要和什么进行一个内连接呢?和肉进行一个内连接对吧?那么内连接的时候呢?它的条件是什么呢?那就是user下滑肉的肉ID等于肉点ID对吧?那这个是连表查询条件,也就是说,呃,用户角色表里面的角色ID呢,要等于角色表里面的主键,然后呢,我们接下来Y。
23:07
用户角色表里边的U的ID等于什么呢?对吧,当然它是等于一个占位符对吧,也就是实际上它等于的是我们上面传进来的这个参数,所以说在这样的话呢,我们要针对占位符呢进行赋值,对吧?针对占位符进行赋值,那怎么赋值呢?Select,然后呢,Set long,对吧?因为它只有一个占位符嘛,所以说它是一,然后U的ID,然后接下来的话呢,我们就来进行查询,那么它查出来的话呢,是I XQ query。然后呢?Y name等于空字符串。然后如果查出来的结果。
24:03
对吧,它不为空,也就是if set.next它是触的话,我们就把这个name给它取出来,它等于re result set.get string对吧,RO内呃,实际上一个用户他不一定有一个角色,但是这里面我们为了方便教学的话呢,我们这里边实际上是呃,每一个用户只有一个角色,对吧?为了方便教学,每个用户只有一个角色,呃,当然实际上你就是说你可以,呃就是说每一个用户呢,他有多个角色,然后你在查询的时候呢,把把他所有的角色名查出来,然后拼成一个字符串返回也是可以的,对吧?呃,当然我们这里面为了教学方便,并且一般来讲的话呢,一个用户他其实也就只有一个角色啊好,然后接下来的话。
25:04
那我们把这个查询语句关闭,然后不要忘记把连接关闭,然后呢,返回查询的名字对吧?返回查询的名字好啊,由于我们在数据库里边呢,我们已经写入了一些数据,所以在这的话呢,其实我们是可以进行一些测试的,对吧?比方说main函数我在这里面,我c.out.print。Get all users对吧?诶,我可以看一下它查出来的数据是什么对不对,我们测试一下,看一下这个增删查改语句,我们到底写对了没有对吧?诶那你可以看到他写的是没有任何问题的,我们查出来几条数据呢?对吧?ID为1U的nameme的命对吧?它的密码是这个它的role nameme呢是系统管理员,所以说你可以看到,呃,我们写的这个代码呢,是没有任何问题的,对吧?我们写的这个代码是没有任何问题的啊,当然就是说你写完这个代码之后呢,你就可以写控制器对吧?控制器调用这个服务,然后呢,将服务取得的数据呢,给它返回到前端对吧?给它返回到前端好。
我来说两句