MyBatis初步

本章主要介紹的是MyBatis的基礎應用和源碼涉及的相關等,主要包含的內容有MyBatis的簡介、反射、動態代理(包含JDK代理和cglib代理)、MyBatis使用和代碼生成器等。java

1.1 MyBatis簡介

MyBatis 是一款優秀的持久層框架,它支持定製化 SQL、存儲過程以及高級映射。MyBatis 避免了幾乎全部的 JDBC 代碼和手動設置參數以及獲取結果集。MyBatis 可使用簡單的 XML 或註解來配置和映射原生信息,將接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java對象)映射成數據庫中的記錄。mysql

關於MyBatis相關的信息,你們能夠參考以下:
MyBatis官網: http://www.mybatis.org/
MyBatis文檔: http://www.mybatis.org/mybati...
MyBatis源碼地址: https://github.com/mybatis/my...git

1.2 反射

1.2.1 反射簡介

JAVA反射機制是在運行狀態中,對於任意一個類,都可以知道這個類的全部屬性和方法;對於任意一個對象,都可以調用它的任意方法和屬性;這種動態獲取信息以及動態調用對象方法的功能稱爲java語言的反射機制。
JAVA反射(放射)機制:「程序運行時,容許改變程序結構或變量類型,這種語言稱爲動態語言」。從這個觀點看,Perl,Python,Ruby是動態語言,C++,Java,C#不是動態語言。可是JAVA有着一個很是突出的動態相關機制:Reflection,用在Java身上指的是咱們能夠於運行時加載、探知、使用編譯期間徹底未知的classes。換句話說,Java程序能夠加載一個運行時才得知名稱的class,獲悉其完整構造(但不包括methods定義),並生成其對象實體、或對其fields設值、或喚起其methods。程序員

1.2.2 反射的應用場景

從實用的角度看,筆者認爲有以下幾個場景?你們能夠作一個思考。github

(1) 逆向代碼,例如反編譯;web

(2) 與註解結合的框架,如今有很多java框架都採用註解的方式,例如Spring既能夠經過註解管理事務又能夠經過XML方式管理事務;sql

(3) 插件系統, 程序設計了加載新JAR的功能,陌生JAR文件在程序運行時加入,被編譯成class文件,經過反射機制加載進內存;數據庫

(4) 配置文件中的休眠class類, 一個程序有許許多多功能,不可能相對應的class文件一次性所有加載進內存,只能是加載進維持程序運行的基本class,其他功能只有等用的時候,採用觸發機制,經過xml配置文件獲取類名等信息,而後經過反射機制加載相關class進內存。apache

1.2.3 反射實例

代碼以下:api

package cn.reflect;

import java.lang.reflect.Method;

public class ReflectService {

    /**
     * 測試方法
     * @param name
     */
    public void testReflect(String name) {
        System.out.println("hello:"+name);
    }
    
    /**
     * 測試入口
     * @throws Exception 
     */
    public static void main(String[] args) throws Exception {
        
        /**
         * 經過反射建立ReflectService對象
         */
        Object service = Class.forName(ReflectService.class.getName()).newInstance();
        
        /**
         * 獲取服務方法
         */
        Method method = service.getClass().getMethod("testReflect", String.class);
        
        method.invoke(service, "張三");
        
        
    }
    
}

1.2.4反射的優缺點

反射在給咱們帶來極大的便利的同時,也帶給咱們潛在的危害。這也就是有利也有弊。

反射的優勢:

反射提升了程序的靈活性和擴展性,下降耦合性,提升自適應能力。它容許程序建立和控制任何類的對象,無需提早硬編碼目標類。

反射的缺點:

(1)性能問題:使用反射基本上是一種解釋操做,用於字段和方法接入時要遠慢於直接代碼。所以反射機制主要應用在對靈活性和擴展性要求很高的系統框架上,普通程序不建議使用。

(2)使用反射會模糊程序內內部邏輯:程序員但願在源代碼中看到程序的邏輯,反射等繞過了源代碼的技術,於是會帶來維護問題。反射代碼比相應的直接代碼更復雜。

1.3 動態代理

1.3.1 動態代理簡介

動態代理有兩種方式,一種是JDK的代理,另一種是cglib代理。
它們之間的區別是,JDK是代理接口,cglib代理類。
換言之,一個是接口方式,一個是類的方式,類的方式一般表現爲繼承。

1.3.2 JDK代理應用實例

步驟以下:

(1)編寫接口類

HelloService.java

package cn.reflect;
public interface HelloService {

    public void sayHello(String name);
}

(2)編寫實現類
HelloServiceImpl.java

package cn.reflect;

public class HelloServiceImpl implements HelloService {

    public void sayHello(String name) {
        // TODO Auto-generated method stub
        System.err.println("hello:"+name);
    }

}

(3)編寫代理類

HelloServiceProxy.java

package cn.reflect;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class HelloServiceProxy implements InvocationHandler {
    
    /**
     * 真實服務對象
     */
    private Object target;
    
    public Object bind(Object target){
        this.target=target;
        /**
         * 取得代理對象
         */
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);//jdk代理對象須要提供接口
        
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // TODO Auto-generated method stub
        
        System.out.println("我是JDK動態代理對象");
        
        Object result = null;
        
        /**
         * 反射方法調用前
         */
        System.out.println("我準備說hello");
        
        /**
         * 執行方法,至關於調用HelloServiceImpl中的sayHello方法
         */
        result = method.invoke(target, args);
        
        /**
         * 反射方法後調用
         */
        System.out.println("我說過hello了");
        
        return result;

    }

}

(4)編寫運行測試類
HelloServiceMain.java

package cn.reflect;

public class HelloServiceMain {
    public static void main(String[] args) {
        
        HelloServiceProxy helloHandle = new HelloServiceProxy();
    
        HelloService proxy = (HelloService) helloHandle.bind(new HelloServiceImpl());
        proxy.sayHello("張三");
        
    }
}

1.3.3 cglib代理應用實例

JDK提供的動態代理存在缺陷,必須提供接口才能使用,沒有接口就不能使用,爲了克服這個缺陷,咱們能夠採用cglib代理,它是一種流行的動態代理。

步驟以下:

(1) 導入maven依賴

<dependency>
         <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.2.4</version>
       </dependency>

(2) 編寫運行測試類
HelloServiceCgLib.java

package cn.reflect;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class HelloServiceCgLib implements MethodInterceptor{
    private Object target;

    /**
     * 建立代理對象
     */
    public Object getInstance(Object target) {
        
        this.target=target;
        Enhancer enHancer = new Enhancer();
        enHancer.setSuperclass(this.target.getClass());
        enHancer.setCallback(this);
        return enHancer.create();
        
    }
    
    
    public Object intercept(Object obj, Method method, Object[] arg, MethodProxy proxy) throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("我是cglib代理對象");
        Object returnObj = proxy.invoke(obj, arg);
        
        /**
         * 反射方法前調用
         */
        System.out.println("我準備說hello");
        
        /**
         * 反射方法後調用
         */
        System.out.println("我說過hello了");
        
        return returnObj;
        
        
    }
    
    
}

1.4 MyBatis使用

1.4.1 導入依賴

因爲採用的是maven,只需引入maven對應的依賴便可,一般狀況下,只要maven依賴導入準確,通常狀況下不多會出現由於依賴衝突的問題致使項目運行失敗。

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>cn.youcong.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <dependencies>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.38</version>
</dependency>

<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>


  </dependencies>
</project>

1.4.2 準備SQL腳本

CREATE TABLE `user` (
  `user_id` int(8) NOT NULL AUTO_INCREMENT COMMENT '用戶主鍵',
  `login_code` varchar(20) NOT NULL COMMENT '用戶編碼(登陸帳戶) 手機號 郵箱號',
  `user_name` varchar(20) NOT NULL COMMENT '用戶名',
  `password` varchar(40) NOT NULL COMMENT '密碼',
  `sex` int(2) NOT NULL COMMENT '性別',
  `identity_card` varchar(20) DEFAULT NULL COMMENT '身份證',
  `create_time` datetime NOT NULL COMMENT '建立時間',
  `create_by` varchar(10) NOT NULL COMMENT '建立人',
  `update_time` datetime NOT NULL COMMENT '更新時間',
  `update_by` varchar(10) NOT NULL COMMENT '更新人',
  `status` int(2) NOT NULL DEFAULT '0' COMMENT '狀態:0註冊新用戶 1郵件認證用戶 2管理員 3黑名單',
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

1.4.3 編寫實體

package com.blog.entity;

import java.io.Serializable;


import java.util.Date;
import java.io.Serializable;


public class User{

    private static final long serialVersionUID = 1L;

    /**
     * 用戶主鍵
     */
    private Integer userId;
    /**
     * 用戶編碼(登陸帳戶) 手機號 郵箱號
     */
    private String loginCode;
    /**
     * 用戶名
     */
    private String userName;
    /**
     * 密碼
     */
    private String password;
    /**
     * 性別
     */
    private Integer sex;
    /**
     * 身份證
     */
    private String identityCard;
    /**
     * 建立時間
     */
    private Date createTime;
    /**
     * 建立人
     */

    private String createBy;
    /**
     * 更新時間
 */
    private Date updateTime;
    /**
     * 更新人
     */
    private String updateBy;
    /**
     * 狀態:0註冊新用戶 1郵件認證用戶 2管理員 3黑名單
     */
    private Integer status;


    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

    public static long getSerialversionuid() {
        return serialVersionUID;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getLoginCode() {
        return loginCode;
    }

    public void setLoginCode(String loginCode) {
        this.loginCode = loginCode;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getSex() {
        return sex;
    }

    public void setSex(Integer sex) {
        this.sex = sex;
    }

    public String getIdentityCard() {
        return identityCard;
    }

    public void setIdentityCard(String identityCard) {
        this.identityCard = identityCard;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public String getCreateBy() {
        return createBy;
    }

    public void setCreateBy(String createBy) {
        this.createBy = createBy;
    }

    public String getUpdateBy() {
        return updateBy;
    }

    public void setUpdateBy(String updateBy) {
        this.updateBy = updateBy;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }  
}

1.4.4 編寫數據訪問層及其對應的XML文件

package com.blog.dao;

import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

import com.blog.entity.User;

public interface UserDao {
    @Select("select * from `user` where user_id=#{userId}")
    @Results(@Result(property="userName",column="user_name"))
    User selectOne(int userId);

}

@Select是MyBatis的註解寫法,當字段名和屬性名一致時,能夠直接@Select不須要@Results,@Results的做用就是由於實體屬性與字段不一致,爲了獲取查詢結果,必需要這樣。

固然了你也能夠不寫註解,直接在對應的UserDao.xml寫,若是是UserDao.xml裏面寫的話,就會變成這樣

package com.blog.dao;
 
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
 
import com.blog.entity.User;
 
public interface UserDao {
 
    User selectOne(int userId);
 
}

須要在UserDao.xml中編寫

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.blog.dao.UserDao">

    <!-- 通用查詢映射結果 -->
    <resultMap id="BaseResultMap" type="com.blog.entity.User">
        <id column="user_id" property="userId" />
        <result column="login_code" property="loginCode" />
        <result column="user_name" property="userName" />
        <result column="password" property="password" />
        <result column="sex" property="sex" />
        <result column="identity_card" property="identityCard" />
        <result column="create_time" property="createTime" />
        <result column="create_by" property="createBy" />
        <result column="update_time" property="updateTime" />
        <result column="update_by" property="updateBy" />
        <result column="status" property="status" />
    </resultMap>

    <!-- 通用查詢結果列 -->

    <sql id="Base_Column_List">
        user_id, login_code, user_name, password, sex, identity_card, create_time, create_by, update_time, update_by, status
    </sql>
 <select id="selectOne" resultMap="BaseResultMap"> select * from `user` where user_id=#{userId} </select> </mapper>

除了<select>標籤以外,還有<insert>、<update>、<delete>,它們的做用分別是查、增、更、刪。固然了,還有這裏面能夠<sql>,這個<sql>的做用就是爲了複用重複列,省的重複編寫代碼冗餘。若是要引用,寫成這樣既可

<!-- 通用查詢結果列 -->
    <sql id="Base_Column_List">
        user_id, login_code, user_name, password, sex, identity_card, create_time, create_by, update_time, update_by, status
    </sql>
    
    <select id="selectOne" resultMap="BaseResultMap">
        select <include refid="Base_Column_List"/>
        from `user` where user_id=#{userId}
    </select>

MyBatis經常使用的兩種寫法,XML方式和註解方式,可是不管你採用哪一種,對應的XML文件必需要存在。

其實<resultMap id="BaseResultMap" type="com.blog.entity.User"> 能夠變成 <resultMap id="BaseResultMap" type="User">

前提必需要在mybatis-config.xml配置

<typeAliases>
    <typeAlias type="com.blog.entity.User" alias="User"/>
</typeAliases>

可是有人以爲,若是個人類有不少,豈不是要配置不少,太麻煩了,別怕,MyBatis已經爲你想到了

<typeAliases>
    <package name="com.blog.entity"/>
</typeAliases>

這樣配置就解決了重複配置的麻煩
其實除了這樣,若是你想標新立異點,還能夠再實體最上面加上@Alias註解

clipboard.png

這就是MyBatis的別名三種方式/策略。

1.4.5 編寫mybatis-config.xml配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <environments default="development">
   <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/blog_test"/>
        <property name="username" value="root"/>
        <property name="password" value="1234"/>
      </dataSource>
    </environment>
  </environments>
   
  <mappers>
    <mapper resource="mybatis/mapping/UserDao.xml"/>
  </mappers>
</configuration>

mybatis-config.xml這個配置沒多大用,坦白說。

由於後期與Spring整合由Spring來管理數據庫鏈接池對象。

不過仍是要稍微講講,以讓讀者達到開卷有益的目的或者是讓沒有學過的或者已經學過可是不知道的漲漲見識。

<environment id="development">表示咱們默認使用development配置環境

<transactionManager type="JDBC"/> 採用JDBC的事務管理模式

<dataSource type="POOLED"> 數據庫鏈接信息

<mappers> 映射器 一般通常映射XML文件

1.4.6 編寫工具類

package com.blog.config;

import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class SqlSessionFactoryUtils {
    
private static SqlSessionFactory sqlSessionFactory = null;
    
    public static SqlSessionFactory getSqlSessionFactory() {
        InputStream is  = null;
        if(sqlSessionFactory==null) {
            
            String resource = "mybatis/mybatis-config.xml";
            try {
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream(resource));
                return sqlSessionFactory;
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }            
    
        }
    
        return sqlSessionFactory;
    }
        
}

說到上述代碼,順便談談MyBatis的核心組件。它的核心組件主要有這麼幾個,以下所示:

SqlSessionFactoryBuilder:它會根據配置信息或者代碼來生成SqlSessionFactory;

SqlSessionFactory:依賴工廠生成SqlSession;

SqlSession:是一個便可發送SQL執行返回結果,也能夠獲取Mapper接口;

Sql Mapper:它是MyBatis的新設計組件,它是由一個Java接口和XML文件(或註解)構建,須要給出對應的SQL和映射規則。它負責發送SQL去執行並返回結果。

用一張圖來表示它們之間的關係,如圖:

clipboard.png

它們的生命週期在此稍微說一下:

(1)SqlSessionFacotoryBuilder
SqlSessionFacotoryBuilder是利用XML和Java代碼得到資源來構建SqlSessionFactory的,經過它能夠構建多個SqlSessionFactory,它的做用就是一個構建器,一旦咱們構建了SqlSessionFactory,它的做用就完結,它就失去存在的意義。這時咱們應該絕不猶豫的廢棄它,將它回收。因此它的生命週期只存在方法局部,它的做用就是生成SqlSessionFactory。

(2)SqlSessionFactory的做用是建立SqlSession,而SqlSession就是一個會話,至關於JDBC中的Connection對象。每次應用程序須要訪問數據庫,咱們就要經過SqlSessionFactory建立SqlSession,因此SqlSessionFactory應該在MyBatis應用的整個生命週期中。而若是咱們屢次建立同一個數據庫的SqlSessionFactory,則每次建立SqlSessionFactory會打開更多的數據庫鏈接資源,那麼鏈接資源就很快會被耗盡。所以SqlSessionFactory的責任是惟一的,它的責任就是建立SqlSession,因此咱們果斷採用單例模式。若是採用多例,那麼它對數據庫鏈接的消耗是很大的,不利於咱們統一管理。因此正確的作法是使得每一個數據庫只對應一個SqlSessionFactory,管理好數據庫資源分配,避免過多的Connection被消耗。

(3)SqlSession
SqlSession是一個會話,至關於JDBC的一個Connection對象,它的生命週期應該是在請求數據庫處理事務的過程當中。它是一個線程不安全的對象,在涉及多線程的時候咱們須要特別小心,操做數據庫須要注意其隔離級別,數據庫鎖等高級特性。此外,每次建立的SqlSession都必須及時關閉它,它長期存在就會使數據庫鏈接池的活動資源減小,對系統性能的影響很大。

(4)Mapper
Mapper是一個接口,而沒有任何實現類,它的做用是發送SQL,而後返回咱們須要的結果,或者執行SQL從而修改數據庫的數據,所以它應該在一個SqlSession事務方法以內,是一個方法級別的東西。它就如同JDBC中的一條SQL語句的執行,它的最大範圍和SqlSession是相同的。儘管咱們想一直保存着Mapper,可是你會發現它很難控制,因此儘可能在一個SqlSession事務的方法中使用它們,而後廢棄掉。

MyBatis組件生命週期,如圖:

clipboard.png

1.4.7 測試

package mybatis;

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import com.blog.config.SqlSessionFactoryUtils;
import com.blog.dao.UserDao;
import com.blog.entity.User;

public class MyBatisTest {

    
    @Test
    public void testName() throws Exception {
          SqlSession sqlSession = null;
          sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
            
          UserDao userDao = sqlSession.getMapper(UserDao.class);
          
          User user = userDao.selectOne(1);
          System.out.println(user.getUserName());
    }
}

1.5 MyBatis代碼生成器

MyBatis代碼生成器,又稱逆向工程。

關於逆向工程的優勢和缺點,我以爲我仍是要說說。

逆向工程的優勢是:自動化生成實體類和對應的增刪改查,效率相對於以前我的開發時一個個寫增刪改查要高的多

逆向工程的缺點是:xml中的sql語句加入了mybatis自身的動態sql和一大堆判斷等,對於對動態sql不是十分熟練的人而言,之後再功能擴展上會很困難。

================
MyBatis代碼生成器我分爲兩個,一個是動態web工程,另外一個是如今比較流行的maven工程,本質上都是同樣,只是項目管理jar包的方式不同。

1.5.1動態web工程

(1)導包

clipboard.png

(2)新建generator.xml文件,進行配置

<?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">
        <property name="javaFileEncoding" value="UTF-8"/>
        <commentGenerator>
            <!-- 是否去除自動生成的註釋 true:是 : false:否 -->
            <property name="suppressAllComments" value="true" />
        </commentGenerator>
        <!--數據庫鏈接的信息:驅動類、鏈接地址、用戶名、密碼 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
            connectionURL="jdbc:mysql://localhost:3306/pms" userId="root"
            password="1234">
        </jdbcConnection>
        <!-- 默認false,把JDBC DECIMAL 和 NUMERIC 類型解析爲 Integer,爲 true時把JDBC DECIMAL 和 
            NUMERIC 類型解析爲java.math.BigDecimal -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>

        <!-- targetProject:生成model類的位置 -->
        <javaModelGenerator targetPackage="cn.pms.model"
            targetProject=".\src">
            <!-- enableSubPackages:是否讓schema做爲包的後綴 -->
            <property name="enableSubPackages" value="false" />
            <!-- 從數據庫返回的值被清理先後的空格 -->
            <property name="trimStrings" value="true" />
        </javaModelGenerator>
        <!-- targetProject:mapper映射文件生成的位置 -->
        <sqlMapGenerator targetPackage="mapper"
            targetProject=".\src">
            <!-- enableSubPackages:是否讓schema做爲包的後綴 -->
            <property name="enableSubPackages" value="false" />
        </sqlMapGenerator>
        <!-- targetPackage:mapper接口生成的位置 -->
        <javaClientGenerator type="XMLMAPPER"
            targetPackage="cn.pms.mapper"
            targetProject=".\src">
            <!-- enableSubPackages:是否讓schema做爲包的後綴 -->
            <property name="enableSubPackages" value="false" />
</javaClientGenerator>
    
     
     
     <!-- 指定數據庫表 -->
        <table schema="" tableName="hotel" domainObjectName="Hotel"></table>
    </context>

</generatorConfiguration>

(3)測試

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

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;

public class GeneratorSqlmap {

    public void generator() throws Exception{

        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;
        //指定 逆向工程配置文件
        File configFile = new File("src/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();
        }
        
    }

}

測試結果在控制檯打印以下,表示成功

clipboard.png

1.5.2 maven工程

(1)導入maven依賴

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>cn.mybatis.generator</groupId>
    <artifactId>mybatis-generator</artifactId>
    <version>0.0.1-SNAPSHOT</version>
 
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
 
    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.35</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.3.2</version>
        </dependency>
    </dependencies>
 
 
    <build>
         <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                    <version>3.3</version>
                </plugin>
                <plugin>
                    <groupId>org.mybatis.generator</groupId>
                    <artifactId>mybatis-generator-maven-plugin</artifactId>
                    <version>1.3.2</version>
                    <dependencies>
                        <dependency>
                            <groupId>mysql</groupId>
                            <artifactId>mysql-connector-java</artifactId>
                            <version>5.1.35</version>
                        </dependency>
                    </dependencies>
                    <configuration>
                         <!--配置文件的路徑-->
                         <configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
                        <overwrite>true</overwrite>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
 
 
</project>

(2)在src/main/resource目錄下新建配置文件generatorConfig.xml

<?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="test" targetRuntime="MyBatis3">
        <plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"></plugin>
        <plugin type="org.mybatis.generator.plugins.SerializablePlugin"></plugin>
        <plugin type="org.mybatis.generator.plugins.ToStringPlugin"></plugin>
        <commentGenerator>
            <!-- 這個元素用來去除指定生成的註釋中是否包含生成的日期 false:表示保護 -->
            <!-- 若是生成日期,會形成即便修改一個字段,整個實體類全部屬性都會發生變化,不利於版本控制,因此設置爲true -->
            <property name="suppressDate" value="true" />
            <!-- 是否去除自動生成的註釋 true:是 : false:否 -->
            <property name="suppressAllComments" value="true" />
        </commentGenerator>
        <!--數據庫連接URL,用戶名、密碼 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
            connectionURL="jdbc:mysql://localhost:3306/blog" userId="root"
            password="1234">
        </jdbcConnection>
        <javaTypeResolver>
            <!-- This property is used to specify whether MyBatis Generator should
                force the use of java.math.BigDecimal for DECIMAL and NUMERIC fields, -->
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>
        <!-- 生成模型的包名和位置 -->
        <javaModelGenerator targetPackage="cn.blog.model"
            targetProject="target">
            <property name="enableSubPackages" value="true" />
            <property name="trimStrings" value="true" />
        </javaModelGenerator>
        <!-- 生成映射文件的包名和位置 -->
        <sqlMapGenerator targetPackage="cn.blog.mapper"
            targetProject="target">
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>
        <!-- 生成DAO的包名和位置 -->
        <javaClientGenerator type="XMLMAPPER"
            targetPackage="cn.blog.mapper" implementationPackage="cn.blog.service.impl"
            targetProject="target">
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>
 
        <!-- 要生成哪些表 -->
        <table tableName="`post`" domainObjectName="Post"></table>
 
        <table tableName="`posttag`" domainObjectName="PostTag"></table>
 
        <table tableName="`tag`" domainObjectName="Tag"></table>
 
        <table tableName="`type`" domainObjectName="Type"></table>
 
 
        <table tableName="`typetag`" domainObjectName="typetag"></table>
 
 
    </context>
</generatorConfiguration>

(3)右擊進入run as 點擊maven build 以下圖輸入:mybatis-generator:generate

clipboard.png

運行結果以下,表示成功

clipboard.png

注意:運行成功後,直接是看不到生成的代碼,還須要刷新一下(refresh)。

1.6 小結

經過上面的內容,我相信讀者對於MyBatis已經有了大體的瞭解,經過相關的代碼示例,我相信讀者應該知道怎麼使用MyBatis了。固然了,這僅僅只是MyBatis的冰山一角,MyBatis的特性還有不少。不過我之因此講MyBatis也是爲了後續讀者更好理解MyBatis-plus。

本文主要參考我我的的博客園中的MyBatis系列相關的,能夠說這篇文章是以前MyBatis相關教程不太完善的補充。但願可以幫助到你們。

最後,如需轉載本文,請附源地址,謝謝合做。

相關文章
相關標籤/搜索