【Maven配置三】Maven Web項目配置MyBatis Generator插件自動生成代碼+訪問MySQL數據庫


我們知道MyBatis的框架爲我們操作數據庫大大減小了工作量,然而實現類和mapper映射仍然需要我們自己編寫。

MyBatis Generator爲我們很好的解決了這個問題,它能自動生成實現類和mapper映射,我們要做的只是直接調用它生成的代碼訪問數據庫。

那我們就開始配置MyBatis Generator以下操作全都基於MyBatis框架配置完成的情況!


配置xml

配置pom.xml

pom.xml<plugins>標籤中加入以下內容:

  • verbose: 指定結果會輸出到控制檯
  • overwrite: 新生成的文件會覆蓋舊文件,不設置此選項新內容將會追加到原文件尾
<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、用戶名和密碼
  • javaModelGeneratorsqlMapGeneratortargetPackage中指定生成的位置
    本例中targerPackage="pojo"即讓實現類生成到main/java/pojo包中
  • table用於指定要生成的數據庫中的數據表名,可以有多個table
<?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>
  <!--mysql 連接數據庫jar 這裏選擇自己本地位置-->
  <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&amp;characterEncoding=UTF-8&amp;serverTimezone=UTC"
                    userId="root"
                    password="123"/>
    <!--生成POJO類-->
    <javaModelGenerator targetPackage="pojo" targetProject="src/main/java">
      <!-- 是否對model添加 構造函數 -->
      <property name="constructorBased" value="true"/>
      <!-- 是否允許子包 -->
      <property name="enableSubPackages" value="false"/>
      <!-- 建立的Model對象是否不可改變,即生成的Model對象不會有setter方法只有構造方法 -->
      <property name="immutable" value="false"/>
      <!-- 是否對類CHAR類型的列的數據進行trim操作 -->
      <property name="trimStrings" value="true"/>
    </javaModelGenerator>
    <!--Mapper映射文件的生成配置,指定包位置和實際位置-->
    <sqlMapGenerator targetPackage="mapper" targetProject="src/main/java"/>
    <!--Mapper接口生成的配置,指定包位置和實際位置-->
    <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

這是我們原來訪問映射文件的方法:

<mappers>
  <mapper resource="xxxmapper.xml"/>
</mappers>

我們將其修改爲:

  <mappers>
    <package name="mapper"/>
  </mappers>

這是利用包名訪問映射文件的方法,通過指定包含所有映射文件和接口的包目錄,mybatis將讀取包中的所有接口文件和對應的同名映射文件。

如果要通過這種方式訪問映射,我們需要在接口中聲明需要的操作方法並在mapper中實現方法,這些代碼MyBatis Generator已經幫我們自動生成了。

實現servlet

接下來我們來實現一個servlet,在main/java中創建service包,包中創建UsersServlet類,前面創建factorysession類的過程和之前沒有區別:

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可以實現selectinsertupdatedeletecount操作,然後對於每種操作,又提供了不同的條件:

  • ByPrimaryKey: 根據主鍵增刪改查
  • ByExample: 根據example輔助類刪改查(不能增)
  • Selective: 選擇性的增刪改(不能查)

我們來寫幾個例子:

//查找主鍵爲3的數據
Users user = mapper.selectByPrimaryKey(3);

//查找所有id不爲空的數據
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;

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>標籤中加入:

 <resources>
      <resource>
        <directory>src/main/java</directory>
        <!-- 此配置不可缺,否則mybatis的Mapper.xml將會丟失 -->
        <includes>
          <include>**/*.xml</include>
        </includes>
      </resource>
      <!--指定資源的位置-->
      <resource>
        <directory>src/main/resources</directory>
      </resource>
    </resources>

這樣映射文件就會正常生成,項目就可以正常訪問啦:
在這裏插入圖片描述

在這裏插入圖片描述


附:關於MBG生成代碼重複的問題

筆者爲取消生成代碼的註釋文件,在GeneratorConfig.xml中加入了以下設置:

<commentGenerator>
  <!--取消時間戳-->
  <property name="suppressDate" value="true"/>
  <!--取消註釋-->
  <property name="suppressAllComments" value="true"/>
</commentGenerator>

加入後卻導致了意想不到的問題,mapper文件中出現了重複代碼!,這直接導致報錯。

筆者查詢了網上的方法,如在<table>標籤中設置用戶名等,然而問題並未解決,直到把新版本的mysql.connector.java-8.0.17降級到5.1.6才正常運行。

因此,筆者推測這裏是版本不兼容的問題, 暫時除降級外我還未找到更好的解決方法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章