java吧 关注:1,252,918贴子:12,741,422

回复:学习记录贴,从零造一个简单db库。

取消只看楼主收藏回复

这个玩意,实现起来有点复杂的。改天再实现
我们看点简单的,jpa 哪里,有个方法名即sql。
这个概念,在某些查询非常有用。
我们实现他试试看
我们定义前缀,findBy 无意义前缀
条件判别式
${Key} ${Where}
${key} sql实体字段名 ${where} 查询条件别名
多个条件判别式,用And Or 链接
拿用户表做演示
根据账号查询用户信息
SysUser findByUsernameEq(String username);
根据账号密码查询用户
SysUser findByUsernameEqAndPasswordEq(String username,String password);
//查询部门下面的用户
List<SysUser> findBySysUserDeptIdEq(String sysDeptId);


IP属地:马来西亚28楼2020-11-27 20:42
回复
    方法名怎么解析呢?
    我们先设计一个Wrapper,他是根据方法名称做解析的
    fingByUsernameEqAndPasswordEq
    这个我们要做字符串分解,根据And关键字分割
    也就是用正则实现


    IP属地:马来西亚29楼2020-11-27 22:02
    回复
      编写单元测试

      运行效果如下

      看起来,和实体类差不多的,但多了灵活性


      IP属地:马来西亚30楼2020-11-27 22:26
      回复
        前面,基本把查询相关的,都实现了。
        现在把更新相关的实现一下。
        更新分为
        插入
        修改
        删除
        3种类型
        插入,删除都是简单类型的,实现起来也比较简单。
        修改复杂点,分情况讨论
        1:字段被JoinPrimary 修饰的
        2:字段被JoinWhere 修饰的
        当修改操作发生时,所有JoinPrimary 的字段都有值,则它们已经唯一定位了数据。
        此时,被JoinWhere 的字段哪怕有值,也不会作为条件
        如果JoinPrimary 字段,存在至少一个没有值,则所有JoinWhere字段都作为条件的一部分


        IP属地:马来西亚31楼2020-11-28 20:37
        回复
          我们拿sys_user做例子演示,并且实现一个简单的乐观锁
          id 主键
          version 版本号,每次更新,都会+1

          编写测试

          运行的效果,生成的sql和预想一致


          IP属地:马来西亚32楼2020-11-28 21:04
          回复
            现在,crud 4个基本能力,及其一对多,一对一能力已经实现了。
            和多数框架一样,这个东西,会有一些拦截器之类的东西。
            用来拦截器sql对象,做一些sql增强或者日志打印之类的操作。

            ISqlFilter 拦截器抽象,
            check 判断是否可以处理
            handle 拦截器处理,返回false的话,下一个拦截器继续拦截
            SqlFilterManager 拦截器管理者
            注册拦截器
            handle 处理


            IP属地:马来西亚33楼2020-11-28 21:51
            回复
              前面实现的哪些东西,现在干脆叫做组件好了。
              哪些组件,都是一些简单的,基础的小玩意,很简单容易。
              现在,我们要,运用这些玩具组件,来实现一些复杂一点的功能。
              我们都知道,mybatis 他对dao接口产生了代理,我们才能获得接口实例的,现在我们也要实现这个能力。
              我们用spring里面的,cglib来用,它内置了,砸门直接用,代码这样写

              interClass 就是dao的那个接口类了,他返回一个代理,这个代理,会去调用哪些简单组件,完成查询。


              IP属地:马来西亚35楼2020-11-30 20:46
              回复
                我们来看一个简单的示例,也就是,部门用户的一对多实例
                部门类

                我们看到,有个奇怪的字段,他加了JoinQuery 注解。
                从能力看,他就是基于sys_user类,用里面JoinWherr的条件,反查询了数据,再注入进去的。
                用户类


                IP属地:马来西亚36楼2020-11-30 20:50
                回复
                  下面是dao接口,我们用方法名做sql表达式

                  下面是单元测试,看看效果

                  我们再看下打印的sql

                  可以看到,这个所为的一对多实现。
                  他仅仅是简化的编写sql的时间,实际上,还是多条sql执行的。
                  他再某处,分解了sql,再合并结果,再增强结果,再返回。


                  IP属地:马来西亚37楼2020-11-30 20:55
                  回复
                    在某些情况下,我们可能很想要一些,懒更新的能力。
                    一般情况下,大多是,先查数据库,new一个实体,根据业务不断向new实例设置值。
                    如果实例至少被赋值一次,则更新到里面去。
                    典型的写法类似这样

                    这种写法可以是可以,就是有点麻烦,一大堆if,set,get 之类的。
                    实际上,这个过程,可以被简化的,jpa就有这个懒更新能力。
                    现在我们也要这个能力。


                    IP属地:马来西亚38楼2020-11-30 21:02
                    回复
                      现在到了封装dao,对外开放的时候了。
                      设计模板类接口,如下

                      insert 开头的,都是插入
                      update开头的,都是更新
                      delete 开头的,都是更新
                      find 开头的,都是查询
                      count开头的,都是求总数


                      IP属地:马来西亚39楼2020-12-02 21:34
                      回复
                        我们把上面的写的类
                        分为2部分存放,
                        一个丢在base模块,
                        一个丢在core模块
                        base 只负责逻辑抽象
                        core 复杂抽象具体实现
                        也就是这样子的


                        IP属地:马来西亚40楼2020-12-02 21:37
                        回复
                          现在,我们新建admin模块。
                          开发一个简易的管理系统来用,从rbac模块开始
                          dept部门
                          menu 菜单
                          role 角色
                          user 用户
                          至于 要不要关联表,后续再看看有没有必要
                          数据库设计如下


                          IP属地:马来西亚41楼2020-12-02 21:41
                          回复
                            好像还缺少一些补充的,这里额外补充下。
                            序列化器,java类型到数据库类型的映射用的。
                            底层一般都是通过这个类来设置值的,PreparedStatement
                            这个玩意,可以设置基本类型相关的,
                            int double string date 之类的,一般通过这个玩意,来实现中间转换的。
                            我们需求有,存储 list ,map ,enum ,通过自定义序列化器是转换到基本类型
                            现在我们来定义,序列化怎么设计。
                            自定义字段类型

                            序列器

                            序列化管理家


                            IP属地:马来西亚42楼2020-12-04 14:20
                            回复
                              接下来测试,定义SysUser 实体。

                              执行单元测试,看下效果
                              嗯,还挺好用的,简化了很多。


                              IP属地:马来西亚43楼2020-12-04 14:24
                              回复