我们知道MyBatis的框架为我们操作数据库大大减小了工作量,然而实现类和mapper映射仍然需要我们自己编写。MyBatis Generator为我们很好的解决了这个问题,它能自动生成实现类和mapper映射,我们要做的只是直接调用它生成的代码访问数据库。
那我们就开始配置MyBatis Generator, 以下操作全都基于MyBatis框架配置完成的情况!
配置xml 配置pom.xml 在pom.xml的<plugins>标签中加入以下内容:
verbose: 指定结果会输出到控制台
overwrite: 新生成的文件会覆盖旧文件,不设置此选项新内容将会追加到原文件尾
1 2 3 4 5 6 7 8 9 <plugin > <groupId > org.mybatis.generator</groupId > <artifactId > mybatis-generator-maven-plugin</artifactId > <version > 1.3.7</version > <configuration > <verbose > true</verbose > <overwrite > true</overwrite > </configuration > </plugin >
配置GeneratorConfig.xml 在src/main/resources中创建GeneratorConfig.xml,输入以下内容:
jdbcConnection中的设置我们已经很熟悉,输入驱动、URL、用户名和密码
在javaModelGenerator和sqlMapGenerator的targetPackage中指定生成的位置 本例中targerPackage="pojo"即让实现类生成到main/java/pojo包中
table用于指定要生成的数据库中的数据表名,可以有多个table
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" > <generatorConfiguration > <classPathEntry location ="D:\software\system\mysql-8.0.19-winx64\lib\mysql-connector-java-8.0.19.jar" /> <context id ="MysqlGenerator" targetRuntime ="MyBatis3" > <jdbcConnection driverClass ="com.mysql.cj.jdbc.Driver" connectionURL ="jdbc:mysql://localhost:3306/hello_mysql?useUnicode=true& characterEncoding=UTF-8& serverTimezone=UTC" userId ="root" password ="123" /> <javaModelGenerator targetPackage ="pojo" targetProject ="src/main/java" > <property name ="constructorBased" value ="true" /> <property name ="enableSubPackages" value ="false" /> <property name ="immutable" value ="false" /> <property name ="trimStrings" value ="true" /> </javaModelGenerator > <sqlMapGenerator targetPackage ="mapper" targetProject ="src/main/java" /> <javaClientGenerator type ="XMLMAPPER" targetPackage ="mapper" targetProject ="src/main/java" /> <table tableName ="users" /> </context > </generatorConfiguration >
配置命令行 在intellij idea中点击右上角的Edit Configurations: 点击左侧加号 → 在左侧栏中找到Maven → 在Command line中输入mybatis-generator:generate
-e(-e指定结果显示到控制台中),并为配置命名: 接下来,我们就可以启动运行项目啦,运行之后,MyBatis Generator就为我们指定的Users表生成了mapper包和pojo包:
mapper: 提供了Mapper接口,Mapper.xml配置文件
pojo: 提供了Users实现类,Example用于辅助查询的类
使用生成的代码访问Mysql 在提供Servlet之前,我们先来看一下生成的文件,注意到生成的mapper并不像之前在resources中,而是在java中,那么此时要怎么访问映射文件呢?
修改mybatis-config.xml 这是我们原来访问映射文件的方法:
1 2 3 <mappers > <mapper resource ="xxxmapper.xml" /> </mappers >
我们将其修改为:
1 2 3 <mappers > <package name ="mapper" /> </mappers >
这是利用包名访问映射文件的方法,通过指定包含所有映射文件和接口的包目录,mybatis将读取包中的所有接口文件和对应的同名映射文件。
如果要通过这种方式访问映射,我们需要在接口中声明需要的操作方法并在mapper中实现方法,这些代码MyBatis Generator已经帮我们自动生成了。
实现servlet 接下来我们来实现一个servlet,在main/java中创建service包,包中创建UsersServlet类,前面创建factory和session类的过程和之前没有区别:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package service;import mapper.UsersMapper;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;import pojo.Users;import pojo.UsersExample;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.InputStream;import java.util.List;public class UsersServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("UsersServlet: GET" ); InputStream stream = Resources.getResourceAsStream("mybatis-config.xml" ); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream); SqlSession session = factory.openSession(); } @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this .doGet(req, resp); } }
MyBatis Generator为我们使用session访问数据库提供了很多种方法,我们先得到一个mapper映射
UsersMapper mapper = session.getMapper(UsersMapper.class);
而mapper有很多方法,首先mapper可以实现select、insert、update、delete、count操作,然后对于每种操作,又提供了不同的条件:
ByPrimaryKey: 根据主键增删改查
ByExample: 根据example辅助类删改查(不能增)
Selective: 选择性的增删改(不能查)
我们来写几个例子:
1 2 3 4 5 6 7 8 9 10 11 Users user = mapper.selectByPrimaryKey(3 ); UsersExample example = new UsersExample(); example.createCriteria().andIdIsNotNull(); List<Users> usersList = mapper.selectByExample(example); Users record = new Users(null , "John" , null ); mapper.insertSelective(record);
这里简单说一下selective,对于这个例子record(null,"John",null):
mapper.insert相当于:insert into users value(null,'John',null)
mapper.insertSelective则相当于:insert into users(name) value('John')
笔者实现了一个servlet类:
package service;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 import mapper.UsersMapper;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;import pojo.Users;import pojo.UsersExample;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.InputStream;import java.util.List;public class UsersServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("UsersServlet: GET" ); InputStream stream = Resources.getResourceAsStream("mybatis-config.xml" ); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream); SqlSession session = factory.openSession(); UsersMapper mapper = session.getMapper(UsersMapper.class ) ; UsersExample example = new UsersExample(); example.createCriteria().andIdIsNotNull(); List<Users> usersList = mapper.selectByExample(example); Users record = new Users(null , "John" , null ); mapper.insertSelective(record); req.setAttribute("usersList" , usersList); req.getRequestDispatcher(req.getContextPath() + "index.jsp" ).forward(req, resp); } @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this .doGet(req, resp); } }
我们启动服务器试一下效果:
点击超链接: 报错HTTP ERROR 500,关键信息:Invalid bound statement (not found): mapper.UsersMapper.selectByExample
服务器并没有找到UsersMapper映射,这是为什么呢?
解决找不到映射的错误 我们来观察一下生成的target文件,发现mapper包中只生成了接口,却没有映射: 要解决此问题,我们需要在pom.xml的<build>标签中加入:
src/main/java */ .xml src/main/resources
这样映射文件就会正常生成,项目就可以正常访问啦:
附:关于MBG生成代码重复的问题 笔者为取消生成代码的注释文件,在GeneratorConfig.xml中加入了以下设置:
1 2 3 4 5 6 7 8 9 10 11 12 13 <commentGenerator > <property name ="suppressDate" value ="true" /> <property name ="suppressAllComments" value ="true" /> </commentGenerator > 加入后却导致了意想不到的问题, **`mapper`文件中出现了重复代码!**,这直接导致报错。 笔者查询了网上的方法,如在`<table > `标签中设置用户名等,然而问题并未解决,直到把新版本的`mysql.connector.java-8.0.17`降级到`5.1.6`才正常运行。 因此,笔者推测这里是版本不兼容的问题, **暂时除降级外我还未找到更好的解决方法** 。