MyBatis.NET.SqlMapper.Tool
2.0.1
dotnet tool install --global MyBatis.NET.SqlMapper.Tool --version 2.0.1
dotnet new tool-manifest
dotnet tool install --local MyBatis.NET.SqlMapper.Tool --version 2.0.1
#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
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:
- UserMapper.xml - Define SQL statements
- 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
Global Installation (Recommended)
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:
@paramNamein SQL statements<if test="...">conditions<foreach collection="...">collectionsparameterTypeattribute
2. Type Inference
Smart type guessing based on parameter names:
id,count,age→int?userName,email,role,name→string?date,time,createdDate→DateTime?isActive,enabled,isDeleted→bool?price,amount→decimal?
3. Return Type Detection
Based on returnSingle attribute (v2.0.0+):
<select returnSingle="false">→List<T>(T fromresultType)<select returnSingle="true">→T?(nullable single object)<insert>,<update>,<delete>→int(rows affected)
4. Smart Naming
UserMapper.xml→IUserMapper.csProductMapper.xml→IProductMapper.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
- Type inference is not 100% accurate - Always review generated code
- Complex types - Only detects basic types (int, string, DateTime, etc.)
- Custom collections - Defaults to
List<T>, may need manual adjustment - Method overloading - Not supported (XML doesn't support it either)
- Generic types - Limited support for complex generics
💡 Best Practices
- Always review generated code before using in production
- Don't edit generated files manually - Regenerate from XML instead
- Version control strategy:
- Option A: Commit generated
.csfiles (easier for team) - Option B: Add to
.gitignoreand generate in CI/CD (ensures fresh)
- Option A: Commit generated
- Run in CI/CD to ensure interface/XML sync before build
- Use meaningful parameter names in XML for better type inference
- Keep XML as source of truth - Update XML, then regenerate interface
- 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
idscollection and generatesList<int>based onidname 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 elementreturnSingleattribute 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?
- GitHub: https://github.com/hammond01/MyBatis.NET
- Issues: Report bugs or request features
- Pull Requests: Contributions welcome!
📄 License
MIT License - Same as MyBatis.NET
Related Documentation:
| Product | Versions 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. |
This package has no dependencies.
v2.0.1: Added comprehensive README documentation with installation, usage examples, troubleshooting, and best practices.