Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 7257|回复: 0

Spring + SpringMVC + Druid + MyBatis 给你一个灵活的后端解决方案

[复制链接]
  • TA的每日心情
    奋斗
    前天 11:25
  • 签到天数: 792 天

    [LV.10]以坛为家III

    2049

    主题

    2107

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    723136
    发表于 2021-4-21 09:21:54 | 显示全部楼层 |阅读模式

       生命不息,折腾不止。

       折腾能遇到很多坑,填坑我理解为成长。

       两个月前自己倒腾了一套用开源框架构建的 JavaWeb 后端解决方案。

       Spring + SpringMVC + Druid + JPA(Hibernate impl) 给你一个稳妥的后端解决方案

       引入到项目组后经过几番打磨,现在也出落的有模有样。

       最近将工程中的 Hibernate 换了换 Mybatis 试试,毕竟人都需要新鲜感。

       我 Hibernate 接触的要比 MyBatis 早,作为最流行的两 ORM 框架,个人认为其中很多思想都相通。

       但 MyBatis 特有的 ResultMap 构想,能进行更为细致的 SQL 调整和优化。

       在开发社区、版本更新速度、支持的工具上,Hibernate 比 MyBatis 更胜一筹。

       项目 Git 地址:https://git.oschina.net/LanboEx/sdm

    1.方案整体一览

       由  Controller 层接受前端参数并响应请求,携带数据跳转页面。

       Controller 层注入 ServiceInter, ServiceImpl 层组织业务数据。

       ServiceImpl 层注入 Mybatis Mapper, Mapper 进行数据的访问。

       和 Hibernate 类似整个 dao 层,都可以由工具生成,工程中使用的是 org.mybatis.generator 插件。

    web.xml
    pom.xml

    2.遇到的坑

       浅坑这里就不说了,下面梳理比较深的几个坑。

       如果你以前遇到过这些问题,并且有比我还完美的解决方法,请赐教。

    a. MapperScannerConfigurer 提前初始化导致 spring 注入配置文件失效

     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="basePackage" value="com.rambo.sdm.dao.inter"/>
            <property name="sqlSessionFactory " ref="sessionFactory"/>
        </bean>

      因为希望 Spring 能扫描 Mapper 接口类加载 Mapper.xml 并自动生成实现代理类,注入到相应的 ServiceImpl 中。

      刚开始配置如上,但是发现 Spring 无法正常加载配置文件中的信息。

      也就是用 ${jdbc.username} 这样之类的表达式,无法获取到 properties 文件里的内容。

      几次尝试未果之后,发现 MapperScannerConigurer 实际是在解析加载 bean 定义阶段,这个时候设置 sqlSessionFactory 的话。

      会导致提前初始化一些类,PropertyPlaceholderConfigurer 还没来得及替换定义中的变量,导致把表达式当作字符串复制了。

      将 sqlSessionFactory 替换为 sqlSessionFactoryBeanName 问题解决,配置如下:

     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="basePackage" value="com.rambo.sdm.dao.inter"/>
            <property name="sqlSessionFactoryBeanName" value="sessionFactory"/>
        </bean>

    b. dao 层数据表主键自动生成

       在编写工程例子运行后,发现提示错误 UUID 不为 NUll。

       自动生成的 mapper.xml 中,对于主键(自增序列/uuid)需要自己配置,这点确实有点 low。

       自己配置就自己配置吧,mapper.xml 中 UUID 配置如下:

        <selectKey keyProperty="uuid" resultType="String" order="BEFORE"> select replace(uuid(),'-','') UUID </selectKey>

      假设项目推进中,生成数据表配置文件后需要研发手动在 mapper.xml 的新增方法中添加主键生成策略,不仅繁琐而且出问题的概率极大。

      试着摸索有没有什么统一配置的地方,发现了一种但还是不够完美。统一配置在 generatorConfig.xml 生成表的地方:

     <table tableName="user" domainObjectName="UserPO">
                <generatedKey column="uuid" sqlStatement="SELECT REPLACE(UUID(),'-','') UUID FROM DUAL"/>
            </table>

       主键生成策略使用 SQL 语句这点,就注定 Mybatis 在数据库移植方面无法尽善尽美。

    c. maven 编译后未将 xml 文件编译到 class文件夹下

       工程中需要输出到编译目录的配置文件有两部分,各数据表 mapper.xml 和 框架之间的各种各种的 .xml/.properties。

       编译运行时报错:org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)

       说是未绑定? 辗转半天,发现 mapper.xml 没有被编译到对应的文件夹下。

       maven build --> resources 节点下新增子 resource 子节点:

                <resource>
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>true</filtering>
                </resource>

       添加子节点后,mapper.xml 确实编译到对应的文件夹下了,但工程中原 Resources 下的文件没有像以前一样编译到 classes 下。

       maven build --> resources 节点下继续新增子 resource 子节点后解决:

                <resource>
                    <directory>src/main/resources</directory>
                    <includes>
                        <include>**/*.xml</include>
                        <include>**/*.properties</include>
                    </includes>
                    <filtering>true</filtering>
                </resource>

    d. jetty 插件启动web 项目时,会同时启动 mybatis 逆向工程插件

       当使用 jetty:run 启动 web 项目后,总会有莫名其妙的问题。

       报错君是这样的:java.lang.IllegalArgumentException: Result Maps collection already contains value for com.rambo.sdm.dao.inter.UserPOMapper.BaseResultMap

       顺着启动日志发现,每次 jetty:run 时,mybatis.generator 插件会先运行,并逆向数据库工程。

       逆向生成就逆向生成吧,按道理需要生成的东西已经存在的话,跳过即可。

       generator 插件运行机制还是有点问题的,生成的类它跳过,但配置文件会将内容追加进去,所以才有了上述那个报错。

       移除 generator 插件 executions --> execution 下 goals 子节点问题得以解决。

                    <executions>
                        <execution>
                            <id>Generate MyBatis Artifacts</id>
                        </execution>
                    </executions>

      需要逆向工程时,手动启动插件即可。

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-9-16 13:12 , Processed in 0.058752 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表