MyBatis.NET.SqlMapper.Tool 2.0.1

dotnet tool install --global MyBatis.NET.SqlMapper.Tool --version 2.0.1
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local MyBatis.NET.SqlMapper.Tool --version 2.0.1
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=MyBatis.NET.SqlMapper.Tool&version=2.0.1
                    
nuke :add-package MyBatis.NET.SqlMapper.Tool --version 2.0.1
                    

MyBatis.NET Mapper Interface Generator

NuGet Version

Auto-generate C# interfaces from XML mappers - Keep your interface and XML in perfect sync!

🎯 Problem Solved

When writing MyBatis mappers, you have to maintain 2 files:

  1. UserMapper.xml - Define SQL statements
  2. IUserMapper.cs - Define interface methods

Problem: Easy to get out of sync:

  • Add method in XML but forget to update interface
  • Rename method/parameter in XML but not in interface
  • Parameter types don't match

Solution: This tool auto-generates interfaces from XML!

� Installation

Install the tool globally to use it anywhere:

dotnet tool install -g MyBatis.NET.SqlMapper.Tool

After installation, the mybatis-gen command will be available globally.

Local Installation (Per Project)

Install the tool for a specific project:

# Create tool manifest if not exists
dotnet new tool-manifest

# Install the tool
dotnet tool install MyBatis.NET.SqlMapper.Tool

# Restore tools
dotnet tool restore

Use with dotnet tool run mybatis-gen or dotnet mybatis-gen.

Update Tool

# Global update
dotnet tool update -g MyBatis.NET.SqlMapper.Tool

# Local update
dotnet tool update MyBatis.NET.SqlMapper.Tool

🚀 Usage

1. Generate from a Single XML File

mybatis-gen generate Mappers/UserMapper.xml

Output: Mappers/IUserMapper.cs

With custom output path and namespace:

mybatis-gen generate Mappers/UserMapper.xml Generated/IUserMapper.cs MyApp.Data.Mappers

2. Generate All XML Files in a Directory

mybatis-gen generate-all Mappers

With custom namespace:

mybatis-gen generate-all Mappers MyApp.Data.Mappers

3. Show Help

mybatis-gen help

📝 Input Example (UserMapper.xml)

<mapper namespace="IUserMapper">
  <select id="GetAll" resultType="User">
    SELECT * FROM Users ORDER BY UserName
  </select>

  <select id="GetById" parameterType="int" resultType="User">
    SELECT * FROM Users WHERE Id = @id
  </select>

  <select id="SearchUsers" resultType="User">
    SELECT * FROM Users
    <where>
      <if test="userName != null">
        UserName LIKE '%' + @userName + '%'
      </if>
      <if test="role != null">
        AND Role = @role
      </if>
    </where>
  </select>

  <select id="FindByRoles" resultType="User">
    SELECT * FROM Users WHERE Role IN
    <foreach collection="roles" item="role" open="(" separator="," close=")">
      @role
    </foreach>
  </select>

  <insert id="InsertUser" parameterType="User">
    INSERT INTO Users (UserName, Email) VALUES (@UserName, @Email)
  </insert>

  <delete id="DeleteUser" parameterType="int">
    DELETE FROM Users WHERE Id = @id
  </delete>
</mapper>

✨ Output Example (IUserMapper.cs)

using System;
using System.Collections.Generic;

namespace MyBatis.ConsoleTest.Mappers;

/// <summary>
/// Auto-generated from UserMapper.xml
/// Generated at: 2025-11-05 15:27:14
/// </summary>
public interface IUserMapper
{
    List<User> GetAll();

    List<User> GetById(int id);

    List<User> SearchUsers(string? userName, string? role);

    List<User> FindByRoles(List<string> roles);

    int InsertUser(User user);

    int DeleteUser(int id);
}

🤖 Smart Features

1. Auto-detect Parameters

The tool automatically analyzes:

  • @paramName in SQL statements
  • <if test="..."> conditions
  • <foreach collection="..."> collections
  • parameterType attribute

2. Type Inference

Smart type guessing based on parameter names:

  • id, count, ageint?
  • userName, email, role, namestring?
  • date, time, createdDateDateTime?
  • isActive, enabled, isDeletedbool?
  • price, amountdecimal?

3. Return Type Detection

Based on returnSingle attribute (v2.0.0+):

  • <select returnSingle="false">List<T> (T from resultType)
  • <select returnSingle="true">T? (nullable single object)
  • <insert>, <update>, <delete>int (rows affected)

4. Smart Naming

  • UserMapper.xmlIUserMapper.cs
  • ProductMapper.xmlIProductMapper.cs
  • Auto-prefix "I" if not present

📋 Command Reference

Command Description Example
generate, gen Generate from single XML mybatis-gen gen Mappers/UserMapper.xml
generate-all, gen-all Generate all in directory mybatis-gen gen-all Mappers
help, -h, --help Show help mybatis-gen help

🔧 Advanced Usage

1. CI/CD Integration

Add to your build script (e.g., .github/workflows/build.yml):

- name: Generate Mapper Interfaces
  run: |
    dotnet tool restore
    dotnet mybatis-gen generate-all Mappers MyApp.Data.Mappers

Or in a shell script:

# Generate all interfaces before build
mybatis-gen generate-all ./MyApp/Mappers MyApp.Data.Mappers
dotnet build

2. Pre-commit Hook

Create .git/hooks/pre-commit:

#!/bin/sh
# Auto-generate interfaces before commit
mybatis-gen generate-all ./Mappers
git add ./Mappers/*.cs

Make it executable:

chmod +x .git/hooks/pre-commit

3. Local Development Workflow

Add npm scripts or make commands for convenience:

package.json (if using npm):

{
  "scripts": {
    "gen": "mybatis-gen generate-all Mappers",
    "build": "npm run gen && dotnet build"
  }
}

Makefile:

.PHONY: gen build

gen:
	mybatis-gen generate-all Mappers

build: gen
	dotnet build

⚠️ Limitations

  1. Type inference is not 100% accurate - Always review generated code
  2. Complex types - Only detects basic types (int, string, DateTime, etc.)
  3. Custom collections - Defaults to List<T>, may need manual adjustment
  4. Method overloading - Not supported (XML doesn't support it either)
  5. Generic types - Limited support for complex generics

💡 Best Practices

  1. Always review generated code before using in production
  2. Don't edit generated files manually - Regenerate from XML instead
  3. Version control strategy:
    • Option A: Commit generated .cs files (easier for team)
    • Option B: Add to .gitignore and generate in CI/CD (ensures fresh)
  4. Run in CI/CD to ensure interface/XML sync before build
  5. Use meaningful parameter names in XML for better type inference
  6. Keep XML as source of truth - Update XML, then regenerate interface
  7. Add XML validation to catch errors early (missing returnSingle, etc.)

📚 Examples

Example 1: Simple CRUD

XML:

<mapper namespace="IProductMapper">
  <select id="GetAll" resultType="Product" returnSingle="false">
    SELECT * FROM Products
  </select>

  <select id="GetById" resultType="Product" returnSingle="true">
    SELECT * FROM Products WHERE Id = @id
  </select>

  <insert id="Insert" parameterType="Product">
    INSERT INTO Products (Name, Price) VALUES (@Name, @Price)
  </insert>
</mapper>

Generated:

public interface IProductMapper
{
    List<Product> GetAll();
    Product? GetById(int id);
    int Insert(Product product);
}

Example 2: Dynamic SQL

XML:

<mapper namespace="IOrderMapper">
  <select id="Search" resultType="Order" returnSingle="false">
    SELECT * FROM Orders
    <where>
      <if test="customerId != null">
        CustomerId = @customerId
      </if>
      <if test="status != null">
        AND Status = @status
      </if>
      <if test="minAmount != null">
        AND TotalAmount >= @minAmount
      </if>
    </where>
  </select>
</mapper>

Generated:

public interface IOrderMapper
{
    List<Order> Search(int? customerId, string? status, decimal? minAmount);
}

Example 3: ForEach Collection

XML:

<mapper namespace="ICategoryMapper">
  <select id="FindByIds" resultType="Category" returnSingle="false">
    SELECT * FROM Categories
    WHERE Id IN
    <foreach collection="ids" item="id" open="(" separator="," close=")">
      @id
    </foreach>
  </select>
</mapper>

Generated:

public interface ICategoryMapper
{
    List<Category> FindByIds(List<int> ids);
}

Note: Tool detects ids collection and generates List<int> based on id name inference.

🔍 Troubleshooting

"command not found: mybatis-gen"

Solution: Make sure the tool is installed and ~/.dotnet/tools is in your PATH.

# Check if tool is installed
dotnet tool list -g

# Add to PATH (Linux/Mac - add to ~/.bashrc or ~/.zshrc)
export PATH="$PATH:$HOME/.dotnet/tools"

# Windows - add to PATH environment variable
%USERPROFILE%\.dotnet\tools

"Invalid XML mapper file"

Solution: Ensure your XML has:

  • Valid XML structure
  • <mapper namespace="..."> root element
  • returnSingle attribute on all <select> statements (v2.0.0+)

"Type inference incorrect"

Solution: The tool uses heuristics. Review and manually adjust types if needed:

// Generated (may need adjustment)
int? customerId

// Adjust if needed
Guid? customerId

🤝 Contributing

Found a bug? Have a suggestion?

📄 License

MIT License - Same as MyBatis.NET


Related Documentation:

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
2.0.1 202 11/6/2025
2.0.0 202 11/5/2025

v2.0.1: Added comprehensive README documentation with installation, usage examples, troubleshooting, and best practices.