MyBatis详解:逆向工程自动生成代码

MyBatis详解:逆向工程自动生成代码

 

目录

MyBatis详解:逆向工程自动生成代码

一、什么是逆向工程

二、下载逆向工程

三、创建java工程

工程结构如下:

log4j文件的内容如下:

四、逆向工程的xml配置文件

4.1、xml配置文件分析

4.2、官网解释 

五、逆向工程主程序

5.1、执行主程序

5.2、生成代码后的工程结构

六、遇到的问题

5.1、时区问题

5.2、把其他数据库的同名表也生成下来


 

 

 

 

 

 

 

 

 

 

 

 


一、什么是逆向工程

MyBatis的一个主要的特点就是需要程序员自己编写sql,那么如果表太多的话,难免会很麻烦,所以mybatis官方提供了一个逆向工程,可以针对单表自动生成mybatis执行所需要的代码(包括mapper.xml、mapper.java、po..)。企业实际开发中,常用的逆向工程方式是通过数据库的表生成java代码。

二、下载逆向工程

使用MyBatis的逆向工程,需要导入逆向工程的jar包,这里给出了逆向工程官网下载的内容以及所需要的jar包的百度云链接。

链接:https://pan.baidu.com/s/1U8gtpFtL5cKafN_XXOLkMg 
提取码:kq0t 

三、创建java工程

使用mybatis的逆向工程来由数据库的表生成java代码最好新建一个java工程或者IDEA新建一个模块。原因在于:如果在你要使用到逆向工所生成的代码的工程中生成代码,会存在风险。因为MyBatis是根据配置文件来生成的(下面会说到),如果生成的路径中有相同的文件,那么就会覆盖原来的文件,这样会有风险。所以开发中一般都会新建一个java工程来生成,然后将生成的文件拷贝到自己的工程中,这也不麻烦,而且很安全。

工程结构如下:

我是用的是IDEA软件,eclipse或MyEclipse也是一样的,下面对工程结构做出一些解释:

generatorConfig.xml:这是逆向工程的xml配置文件,本文使用的方法就是逆向工程的使用xml配置文件的方式来生成代码。我把它直接存放在模块下(eclipse可以直接存放在工程下,存放在哪里并不重要,我们会在主程序中用到该文件的相对路径)

lib:这里存放的是jar包,在上面的百度云链接可以下载到

src:存放的执行程序和log4j.proprerties文件

log4j文件的内容如下:

log4j.rootLogger=DEBUG, Console
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

四、逆向工程的xml配置文件

4.1、xml配置文件分析

我们是使用xml配置文件的方式来生成代码,故配置文件是最为重要的步骤。

以下的配置文件主要做了4件事:

1、连接数据库,配置数据库的连接信息

2、相关属性设置

3、指定要生成代码的位置,包括po类,mapper.xml和mapper.java这三类代码,一般po类放在po包下,mapper.xml和mapper.java放在mapper包下

4、指定数据库中哪些表要生成代码

<?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>
	<context id="testTables" targetRuntime="MyBatis3">
		<commentGenerator>
			<!-- 是否去除自动生成的注释 true:是 : false:否 -->
			<property name="suppressAllComments" value="true" />
		</commentGenerator>
		<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
		<jdbcConnection driverClass="com.mysql.jdbc.Driver"
			connectionURL="jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC" userId="root"
			password="mysql">
		</jdbcConnection>
		<!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver"
			connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg" 
			userId="yycg"
			password="yycg">
		</jdbcConnection> -->

		<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和 
			NUMERIC 类型解析为java.math.BigDecimal -->
		<javaTypeResolver>
			<property name="forceBigDecimals" value="false" />
		</javaTypeResolver>

		<!-- targetProject:生成PO类的位置 -->
		<javaModelGenerator targetPackage="po"
			targetProject=".\mybatis-generator\src">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />
			<!-- 从数据库返回的值被清理前后的空格 -->
			<property name="trimStrings" value="true" />
		</javaModelGenerator>
        <!-- targetProject:mapper映射文件生成的位置 -->
		<sqlMapGenerator targetPackage="mapper"
			targetProject=".\mybatis-generator\src">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />
		</sqlMapGenerator>
		<!-- targetPackage:mapper接口生成的位置 -->
		<javaClientGenerator type="XMLMAPPER"
			targetPackage="mapper"
			targetProject=".\mybatis-generator\src">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />
		</javaClientGenerator>
		<!-- 指定数据库表 -->
		<table tableName="items"></table>
		<table tableName="orders"></table>
		<table tableName="orderdetail"></table>
		<table tableName="user"></table>
		<!-- <table schema="" tableName="sys_user"></table>
		<table schema="" tableName="sys_role"></table>
		<table schema="" tableName="sys_permission"></table>
		<table schema="" tableName="sys_user_role"></table>
		<table schema="" tableName="sys_role_permission"></table> -->
		
		<!-- 有些表的字段需要指定java类型
		 <table schema="" tableName="">
			<columnOverride column="" javaType="" />
		</table> -->
	</context>
</generatorConfiguration>

4.2、官网解释 

在官网下载的文件中,可以点击index.html来查看一些官网解释,想深究的大牛可以看看,个人觉得只要学会使用逆向工程就ok了。

五、逆向工程主程序

5.1、执行主程序

通过以下主程序来生成代码,在主程序中需要知名xml配置文件的相对位置。

package main;

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class GeneratorSqlmap {

	public void generator() throws Exception{

		List<String> warnings = new ArrayList<String>();
		boolean overwrite = true;
		//指定 逆向工程配置文件
		File configFile = new File("mybatis-generator/generatorConfig.xml");
		ConfigurationParser cp = new ConfigurationParser(warnings);
		Configuration config = cp.parseConfiguration(configFile);
		DefaultShellCallback callback = new DefaultShellCallback(overwrite);
		MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
				callback, warnings);
		myBatisGenerator.generate(null);

	} 
	public static void main(String[] args) throws Exception {
		try {
			GeneratorSqlmap generatorSqlmap = new GeneratorSqlmap();
			generatorSqlmap.generator();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

}

运行一下即可,就可以看到最新生成的代码了。使用eclipse或者MyEclipse的一定要刷新一下工程才能看到。

这里需要注意一个问题,点击运行之后,就已经帮我们生成好了对应的代码,但是我们需要手动刷新项目才看得见,有些人就会觉得看不见,以为没有生效,然后又第二次运行核心代码,这里就会出现一个很严重的问题,[Mapper.xml文件已经存在时,如果进行重新生成则mapper.xml文件时,内容不被覆盖而是进行内容追加,结果导致mybatis解析失败]

解决办法:删除生成的所有类和mapper.xml,重新在运行一遍即可。

5.2、生成代码后的工程结构

生成的po类放在po包下,mapper.xml和mapper.java放在mapper包下。

六、遇到的问题

5.1、时区问题

Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
java.sql.SQLException: The server time zone value '???ú±ê×??±??' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:73)
	at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:76)
	at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:835)
	at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:455)
	at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:240)
	at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:207)
	at org.mybatis.generator.internal.db.ConnectionFactory.getConnection(ConnectionFactory.java:68)
	at org.mybatis.generator.config.Context.getConnection(Context.java:526)
	at org.mybatis.generator.config.Context.introspectTables(Context.java:436)
	at org.mybatis.generator.api.MyBatisGenerator.generate(MyBatisGenerator.java:222)
	at org.mybatis.generator.api.MyBatisGenerator.generate(MyBatisGenerator.java:133)
	at GeneratorSqlmap.generator(GeneratorSqlmap.java:27)
	at GeneratorSqlmap.main(GeneratorSqlmap.java:33)
Caused by: com.mysql.cj.exceptions.InvalidConnectionAttributeException: The server time zone value '???ú±ê×??±??' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
	at java.base/java.lang.reflect.Constructor.newInstance(Unknown Source)
	at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
	at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:85)
	at com.mysql.cj.util.TimeUtil.getCanonicalTimezone(TimeUtil.java:132)
	at com.mysql.cj.protocol.a.NativeProtocol.configureTimezone(NativeProtocol.java:2234)
	at com.mysql.cj.protocol.a.NativeProtocol.initServerSession(NativeProtocol.java:2258)
	at com.mysql.cj.jdbc.ConnectionImpl.initializePropsFromServer(ConnectionImpl.java:1319)
	at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:966)
	at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:825)
	... 10 more

解决办法:在url后面添加:?serverTimezone=UTC

<jdbcConnection driverClass="com.mysql.jdbc.Driver"
			connectionURL="jdbc:mysql://localhost:3306/mybatis
			?serverTimezone=UTC" userId="root"
			password="mysql">

5.2、把其他数据库的同名表也生成下来

解决办法:添加下列参数:nullCatalogMeansCurrent=true

<jdbcConnection driverClass="com.mysql.jdbc.Driver"
			connectionURL="jdbc:mysql://localhost:3306/mybatis
			?serverTimezone=UTC;seUnicode=true&amp;characterEncoding=utf-8&amp;
			serverTimezone=UTC&amp;nullCatalogMeansCurrent=true" userId="root"
			password="mysql">
		</jdbcConnection>

或者这么添加(每一个参数的意思看注释):

<!-- 数据库链接驱动、地址、用户名、密码 -->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/tmybatis" userId="root" password="mysql">
    <!-- connectionURL属性,防止乱码 -->
    <property name="useUnicode" value="true"/>
    <!-- connectionURL属性,防止乱码 -->
    <property name="characterEncoding" value="utf-8"/>
    <!-- connectionURL属性,防止报时间错误 -->
    <property name="serverTimezone" value="UTC"/>
    <!-- connectionURL属性,防止生成不同数据库同名表的代码 -->
    <property name="nullCatalogMeansCurrent" value="true"/>
</jdbcConnection>

猜你喜欢

转载自blog.csdn.net/qq_42262803/article/details/86596828