MyEclipse老项目搭建MyBatis全流程:版本搭配与踩坑实录

发布时间:2026/10/14 11:14:41
MyEclipse老项目搭建MyBatis全流程:版本搭配与踩坑实录
我做 Java 开发这些年MyEclipse 一直是个绕不开的话题。前阵子接手一套老系统的维护开发环境固定死在 MyEclipse原代码里全是手写 JDBC典型的“能用但没法维护”。跟业务对完需求后我决定引入 MyBatis 统一管理 SQL想着这不是网上遍地都是的教程吗半小时搞定。结果真的动手才发现从 jar 包版本、DTD 解析、数据库驱动到 MyEclipse 自带的编译级别处处都是坑。今天这篇文章就把我在 MyEclipse 下搭建 MyBatis 环境时踩过的坑和最终跑通的完整步骤整理出来。适合正在用 MyEclipse 维护老工程项目、又需要引入 MyBatis 的朋友直接照着做。1. 动手前的准备版本搭配是恶心之源1.1 JDK 和 MyEclipse 版本怎么选很多旧教程还在用 MyBatis 3.2、3.3配合 JDK 1.7 和 MySQL 5.5放到现在很容易出现兼容性问题。我这边的实际环境是 MyEclipse 2019但它创建项目时默认的编译级别居然不是 1.8我得手动去改。如果你还在用更老的 MyEclipse 2014问题也不大只要环境变量 JAVA_HOME 指向 JDK 1.8MyEclipse 里同样指定这个 JDK就能正常编译运行。这里要记住一个底线MyBatis 3.5.x 官方早就要求 JDK 8 以上所以 JDK 8 是基础。别想着一步到位用 JDK 17老 Tomcat 版本加载不了高版本 class 文件而且 MyEclipse 里的旧插件对高版本 JDK 支持也不好容易出现各种莫名其妙的问题。稳妥的搭配是MyEclipse 2014 及以上 JDK 8 Tomcat 8.0/8.5 MyBatis 3.5.x。如果你用的是 MyEclipse 2020 这类偏新的版本界面和菜单可能有些变化但核心操作路径还是大同小异。重点在于创建完项目之后一定要去项目属性里确认 Java Compiler 的编译级别是 1.8同时 Java Build Path 里的 JRE System Library 也是 1.8否则后面写代码不报错一运行就报 UnsupportedClassVersionError。1.2 数据库驱动和 MyBatis 包怎么准备MyBatis 核心其实只有一个 jar 包没有想象中那一堆依赖。以我用的 3.5.13 为例就是 mybatis-3.5.13.jar 这一个文件。数据库驱动要看 MySQL 版本MySQL 5.7 可以用 mysql-connector-java 5.1.49MySQL 8.x 建议用 8.0.33。注意版本差异带来的一个经典坑MySQL 8.x 驱动类名是 com.mysql.cj.jdbc.Driver旧教程里写的 com.mysql.jdbc.Driver 在 8.x 驱动里已经移除了。测试框架我用 JUnit 4如果只是搭环境验证配置至少需要 junit-4.13.2.jar 和 hamcrest-core 这两个包。日志相关的包我不建议一开始就引入因为 MyBatis 在没有日志实现的时候会静默运行不影响功能调试。等环境跑通、想看打印 SQL 了再往 classpath 里加 log4j 或者 slf4j 也不迟这样可以减少变量排查问题时更简单。在动手下载这些包之前先确认自己本机的 MySQL 版本再去访问数据库连一次把用户名、密码、库名都记录下来。这一步看着简单但很多人到最后一步连不上数据库才发现自己连驱动版本都拿错了浪费时间。2. 创建项目并引入依赖2.1 在 MyEclipse 中创建 Web 项目我的建议是直接创建 Web Project不要图省事建一个 Java Project。因为 MyBatis 通常和服务端 Web 项目配套后面需要部署到 Tomcat 时Web Project 能省掉很多发布问题。如果你非要用 Java Project 跑 JUnit 测试也不是不行但后期整合 Servlet、Spring 会非常别扭。创建之前先配置 Tomcat。菜单栏打开 Window - Preferences在搜索框输入 Servers左边找到 Runtime Environments点 Add 添加一个 Tomcat 版本选择对应安装目录再选一个 JDK 1.8 作为 JRE。这一步如果你不配后面创建 Web Project 时 Target Runtime 就选不了项目就算建出来也没法正确发布。配置好后File - New - Other - Web - Web Project给项目起名叫 demo-mybatis。在 Target Runtime 那一栏选择刚配置好的 Tomcat版本这里不用太纠结。Finish 之后项目会生成 src 目录和 WebRoot 目录。老版本 MyEclipse 的 Web 根目录可能叫 WebRoot新版叫 WebContent 或 src/main/webapp都是正常现象不影响咱们的操作。2.2 两种依赖引入方式手动 lib 与 MavenMyEclipse 虽然自带 Maven 插件但公司老项目大多没有统一的 Maven 私服所以我优先推荐传统的手动方式。操作流程如下找到项目的 WebRoot/WEB-INF/lib 目录。把 mybatis-3.5.13.jar、mysql-connector-java-8.0.33.jar、junit-4.13.2.jar 复制进去。右键项目选择 Build Path - Configure Build Path - Libraries 标签页。点击 Add JARs展开项目目录从 WEB-INF/lib 下选中刚才复制的几个 jar。点击 OK 完成。这里为什么要 Add JARs 一次因为 MyEclipse 有时不会自动把 lib 下新加入的 jar 同步到编译 classpath你不手动添加写 UserDao 接口时就会提示找不到 org.apache.ibatis 相关的类。反过来如果你只点了 Add External JARs 把 jar 引用到外部路径而没有复制到 WEB-INF/lib 下编译能过一部署到 Tomcat 就会报 NoClassDefFoundError。所以最稳的组合是先复制 jar 到 lib 目录再通过 Add JARs 从项目内部引入。如果你所在的项目确实走了 Maven 依赖管理也可以直接在 pom.xml 里加入下面的依赖然后右键项目 Maven - Update Projectproperties project.build.sourceEncodingUTF-8/project.build.sourceEncoding maven.compiler.source1.8/maven.compiler.source maven.compiler.target1.8/maven.compiler.target /properties dependencies dependency groupIdorg.mybatis/groupId artifactIdmybatis/artifactId version3.5.13/version /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.33/version /dependency dependency groupIdjunit/groupId artifactIdjunit/artifactId version4.13.2/version scopetest/scope /dependency /dependenciesMaven 的好处是版本传递依赖省心坏处是如果公司内网没有配置好中央仓库镜像拉依赖有可能失败。手动 lib 虽然土但可控性很强环境出问题也更容易定位。3. 配置文件逐行详解3.1 数据库连接参数 jdbc.properties我习惯把数据库连接信息单独放到一个 jdbc.properties 文件里而不是硬编码在 mybatis-config.xml 中。这样做的好处是环境切换时只需要改一个文件不至于翻遍 XML 找连接参数。在 src 根目录下新建 jdbc.propertiesjdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/demo?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8 jdbc.usernameroot jdbc.password123456URL 参数里要重点说明一下useSSLfalseMySQL 8.x 驱动默认会去检查 SSL 证书本地开发环境通常没有配置证书不关掉会报警告加上后能避免 SSL 连接校验失败。serverTimezoneAsia/Shanghai解决时区问题。不设置的话MySQL 8 可能会报 “The server time zone value” 错误。characterEncodingutf8保证数据库连接层面传输中文不乱码后面插入中文数据时非常关键。注意jdbc.properties 文件里的 符号不用转义因为它是普通 properties 文件。但如果这个 URL 要写进 XML 标签里就需要把 写成 这是一个很容易被忽略的细节。3.2 mybatis-config.xml 配置说明在 src 根目录下新建 mybatis-config.xml。完整内容如下?xml version1.0 encodingUTF-8 ? !DOCTYPE configuration PUBLIC -//mybatis.org//DTD Config 3.0//EN http://mybatis.org/dtd/mybatis-3-config.dtd configuration properties resourcejdbc.properties/ settings setting namemapUnderscoreToCamelCase valuetrue/ /settings typeAliases typeAlias typecom.demo.pojo.User aliasUser/ /typeAliases environments defaultdevelopment environment iddevelopment transactionManager typeJDBC/ dataSource typePOOLED property namedriver value${jdbc.driver}/ property nameurl value${jdbc.url}/ property nameusername value${jdbc.username}/ property namepassword value${jdbc.password}/ /dataSource /environment /environments mappers mapper resourcecom/demo/mapper/UserMapper.xml/ /mappers /configuration逐段解释一下。第一段 properties resource 会把 jdbc.properties 里的键值读进来后面的 dataSource 用 ${jdbc.driver} 这种方式引用。settings 里的 mapUnderscoreToCamelCase 是一个很实用的设置开启后数据库字段 user_name 可以自动映射到实体类属性 userName不需要在 SQL 里写一大堆别名。typeAliases 是给实体类起别名。如果不配置后面 UserMapper.xml 里 resultType 必须写全限定名 com.demo.pojo.User配置了别名 User 之后XML 里写起来干净很多。environments 是环境配置default 指定当前使用哪套环境。transactionManager 类型 JDBC 表示 MyBatis 的提交、回滚操作直接交给底层 JDBC 管理这也是 Web 项目里最常见的事务管理方式。dataSource 类型 POOLED 表示使用 MyBatis 内置的连接池查询频繁时能复用连接如果选 UNPOOLED每次访问数据库都新建连接性能很差不推荐。最后 mappers 里声明了映射文件的位置。这里一定注意resource 是 classpath 下的路径不是磁盘路径。我上面的写法意味着 UserMapper.xml 要放在 src 下的 com/demo/mapper 包目录里。很多新手会问MyBatis 3.5 的 DTD 是不是应该写成 mybatis-3-config.dtd其实不是MyBatis 从 3.0 开始这个 DTD 的规范路径就一直沿用没有所谓 3.5 专属的 DTD 文件。你不需要刻意去找新版 DTDURL 保持不变即可。3.3 UserMapper.xml 映射文件在 src/com/demo/mapper 目录下新建 UserMapper.xml。先给一个最简单的查询和插入?xml version1.0 encodingUTF-8 ? !DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.demo.dao.UserDao select idgetUserById parameterTypeint resultTypeUser select id, user_name, user_password, user_email from user where id #{id} /select insert idinsertUser parameterTypeUser insert into user(user_name, user_password, user_email) values(#{userName}, #{userPassword}, #{userEmail}) /insert /mapper这里有几个关键点。mapper 的 namespace 必须是你的 Dao 接口全限定名不能随便写。select 标签的 id 必须和 Dao 接口方法名一致。parameterType 表示入参类型int 是别名insert 的 parameterType 用 User对应前面配置的 typeAlias。resultType 是返回结果映射类型这里写 UserMyBatis 会通过反射将查询结果封装成 com.demo.pojo.User 对象。SQL 里的 #{} 是预编译占位符传参时 MyBatis 会自动把值当字符串参数设置进 PreparedStatement能够防止 SQL 注入。面试中常提到的 ${} 是字符串拼接存在注入风险业务代码里尽量不要用。因为开启了 mapUnderscoreToCamelCaseselect 里的 user_name 会自动映射到 User 类的 userName 字段写起来省心很多。4. 实体类、Dao 接口和测试代码4.1 实体类和 Mapper 接口在 src 下创建 com.demo.pojo 包新增 User 类package com.demo.pojo; public class User { private Integer id; private String userName; private String userPassword; private String userEmail; public User() { } // getter 和 setter 方法 public Integer getId() { return id; } public void setId(Integer id) { this.id id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName userName; } public String getUserPassword() { return userPassword; } public void setUserPassword(String userPassword) { this.userPassword userPassword; } public String getUserEmail() { return userEmail; } public void setUserEmail(String userEmail) { this.userEmail userEmail; } Override public String toString() { return User{ id id , userName userName \ , userPassword userPassword \ , userEmail userEmail \ }; } }实体类尽量保留无参构造方法MyBatis 底层反射创建对象依赖它。字段命名建议直接用驼峰数据库列可以用下划线配合 mapUnderscoreToCamelCase 自动映射省掉不少别名操作。Dao 接口不需要实现类这是 MyBatis 的核心机制之一。新建 com.demo.dao.UserDaopackage com.demo.dao; import com.demo.pojo.User; public interface UserDao { User getUserById(Integer id); int insertUser(User user); }MyBatis 会通过动态代理在运行时为这个接口生成实现对象只要保证接口方法名、参数类型和返回类型与 UserMapper.xml 里的一致即可。如果你把 UserDao 写成 class反而会报 Mapper 绑定异常。4.2 获取 SqlSession 的工具类每次查询都要先创建 SqlSessionFactory。SqlSessionFactory 是一个重量级对象一个应用只要初始化一次就够了所以我把它放在静态块里。新建 com.demo.utils.MyBatisUtilpackage com.demo.utils; import java.io.IOException; import java.io.InputStream; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; public class MyBatisUtil { private static SqlSessionFactory sqlSessionFactory; static { try { String resource mybatis-config.xml; InputStream inputStream Resources.getResourceAsStream(resource); sqlSessionFactory new SqlSessionFactoryBuilder().build(inputStream); } catch (IOException e) { e.printStackTrace(); } } public static SqlSession getSqlSession() { return sqlSessionFactory.openSession(); } }Resources.getResourceAsStream 会从 classpath 下读取文件所以 mybatis-config.xml 必须放在 src 目录或被打包到 classes 根目录。SqlSessionFactoryBuilder 读完配置文件后会返回一个 SqlSessionFactory之后我们通过它来 openSession。默认 openSession 是关闭自动提交的也就是说执行 insert、update、delete 必须手动 commitselect 查询不需要提交但会话用完也要 close释放连接池里的连接。4.3 JUnit 测试增删改查在 src 下创建 com.demo.test 包新增一个测试类。先写一个查询测试package com.demo.test; import com.demo.dao.UserDao; import com.demo.pojo.User; import com.demo.utils.MyBatisUtil; import org.apache.ibatis.session.SqlSession; import org.junit.Test; public class UserDaoTest { Test public void testGetUserById() { SqlSession session MyBatisUtil.getSqlSession(); try { UserDao userDao session.getMapper(UserDao.class); User user userDao.getUserById(1); System.out.println(user); } finally { session.close(); } } }再写一个插入测试重点演示手动提交Test public void testInsertUser() { SqlSession session MyBatisUtil.getSqlSession(); try { UserDao userDao session.getMapper(UserDao.class); User user new User(); user.setUserName(zhangsan); user.setUserPassword(123456); user.setUserEmail(zhangsanexample.com); userDao.insertUser(user); session.commit(); } finally { session.close(); } }运行方式很简单在测试类上右键 Run As - JUnit Test。我个人的习惯是先用查询测试验证配置是否正确再跑插入测试这样即使出错也能把问题范围缩小到增删改操作而不是一上来就怀疑环境搭建有问题。testInsertUser 执行完成后去数据库里查一下 user 表能看到数据就说明整个 MyBatis 环境已经完全打通了。别忘了 MyBatis 默认自动提交是关的不调用 commit 数据不会真正写入数据库这是新手最容易漏的一步。5. 环境搭建中高频踩坑与解决办法5.1 XML 校验导致的卡死问题MyEclipse 的 XML 编辑器非常执着它会按 DOCTYPE 里的 URL 去连接网络下载 DTD 文件。一旦所处环境访问不了外网或者网络不稳定打开 mybatis-config.xml 时就会长时间卡顿甚至让 MyEclipse 看起来像死机一样。我的排查经验是打开 XML 文件后看编辑器下方状态栏是不是一直显示 validating或者卡在 waiting 状态多半就是 DTD 联网校验卡住了。解决办法是把 DTD 下载到本地再告诉 MyEclipse 使用本地文件。Window - Preferences - XML - XML Catalog在 User Specified Entries 里新增一条Key 填 http://mybatis.org/dtd/mybatis-3-config.dtdLocation 填本地 dtd 文件路径。这样 XML 解析器直接读本地缓存速度快很多。同理mybatis-3-mapper.dtd 也可以做同样的配置。如果你只是临时调试也可以先把 DOCTYPE 声明注释掉等 MyEclipse 不卡了再恢复。但我建议不要长期这么干DTD 不只是摆设它还能在编写 XML 时提供标签提示和语法校验去掉后误写标签不报错问题反而不容易发现。5.2 Mapper 接口绑定错误最典型的异常是org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.demo.dao.UserDao.getUserById这个报错基本上就是 XML 没跟接口对应上。排查顺序我总结为四步UserMapper.xml 的 namespace 是不是完整的 com.demo.dao.UserDao。select 标签的 id 是不是和 UserDao 接口方法名一模一样大小写也要核对。mybatis-config.xml 里的 mapper resource 路径是否写成了 com/demo/mapper/UserMapper.xml注意是斜杠不是点号。编译后 classpath 下有没有这个 XML。老项目有时会漏配置构建时的资源复制策略导致 XML 只在源文件里存在、没有编译进 classes 目录。检查项目部署路径或者 target/classes 下有没有 UserMapper.xml没有就去检查构建配置。还有一个隐藏点如果 UserMapper.xml 和 UserDao 接口不在同一个包而你在 mybatis-config.xml 里用 mapper resource 引入时路径写错也会出现同样的问题。路径要以 classpath 为基准不是以项目 src 为基准。5.3 数据库连接失败与驱动坑运行测试时如果报 ClassNotFoundException: com.mysql.jdbc.Driver说明驱动类名写错了。MySQL 8.x 的驱动必须用 com.mysql.cj.jdbc.Driver老驱动 com.mysql.jdbc.Driver 在新版本中已经不存在了。如果你用的是旧版 MySQL 5.7 驱动 5.1.x那反过来用 com.mysql.jdbc.Driver 是没问题的这点要看清楚 jar 包版本。还有一种常见报错是The server time zone value йʱ is unrecognized or represents more than one time zone这是 MySQL 时区设置导致的问题解决方式就是连接 URL 加 serverTimezoneAsia/Shanghai。如果 MySQL 8 驱动还报了 Public Key Retrieval is not allowed就在 URL 再加 allowPublicKeyRetrievaltrue。我最后用下来最省心的 URL 是jdbc:mysql://localhost:3306/demo?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8allowPublicKeyRetrievaltrue注意这个写法是针对 jdbc.properties 文件的如果哪天你要把 URL 写进 XML 格式的 Spring 配置必须把 转成 否则 XML 直接解析失败。5.4 编译级别和部署资源问题MyEclipse 老项目默认编译级别很可能停留在 1.4 或 1.5这会直接导致 MyBatis 3.5.x 的很多语法不被识别甚至编译报错。处理方法是项目右键 Properties - Java Compiler勾选 Enable project specific settings把 Compiler compliance level 改成 1.8。同时去 Java Build Path 里检查 JRE System Library 是不是也指向 1.8两者要同步。还有一个部署期的经典问题明明本地 JUnit 测试能跑发布到 Tomcat 后却说找不到 mybatis-config.xml 或 jar 包。这种情况要先看项目部署结构。右键项目 Properties - Deployment Assembly 里有没有包含 WebRoot/WEB-INF/lib如果没有Tomcat 启动时不会把 lib 下的 jar 发布过去。另一个操作是清理 Tomcat右键服务器 Remove 项目Clean再重新 Add 和 Publish很多发布路径残留问题这样就能解决。说到底MyBatis 环境搭建并不复杂但 MyEclipse 把很多东西藏在菜单深处一步没配到位后续排查成本就很高。我个人的建议是严格按照先建项目、再配依赖、再写配置、最后跑测试的顺序来不要跳步。尤其是配置文件路径和接口绑定关系出问题概率最大提前理清 namespace、id、resource 三个关键点大部分报错都能一眼看穿。