XIKEW.COM - 实用教程 - (2)LinkCore插件开发之数据驱动 - 实用教程,WebMain项目为例 - 除了自己实现或者引入三方数据驱动外还可以使用已封装好的IDB方法,目前支持 Mongodb 和 Mysql

(2)LinkCore插件开发之数据驱动
LINKCORE NETCORE 4/17/2020 11:57:49 AM 阅读:3

除了自己实现或者引入三方数据驱动外还可以使用已封装好的IDB方法,目前支持 Mongodb 和 Mysql

注意

LINKCORE已经支持到 NET5.0+ 本文章只使用NET3.0

LinkCore?

点击查看介绍

说明

IDB方法过于老旧,推荐使用 IORMIDB2 代替

更新说明

  • 2020.05.26
    • 新增 SqlServer 驱动支持 (最低支持SqlSserver 2008 R2 SP3)
  • 2020.05.05
    • 新增 Mysql 驱动支持
    • 新增 MysqlJoin 联表方法
    • 新增 MysqlQuery 查询方法
    • 新增通用方法 Avg 取平均数方法
    • 增加 Mysql Where Lambda 支持

提前准备

  1. 参考路由设置新建一个 WebMain 的路由项目
  2. 或者你也可以直接 WebMain 或 WPFMain 根目录下的 LinkCore.Interface.dll

这里用WebMain项目为例

协定(容我偷个懒) :)

  • 主键请使用 _id 来命名

选择驱动连接数据库

//InstanceName 可以在不同的插件中使用相同的驱动,当然越少的Instance性能越好
var db = IDB.GetMongoDB("MongoDBInstanceName");

//可以创建Mysql的驱动实例
var MysqlDB = IDB.GetMysql("MysqlInstanceName");

//可以创建Mssql的驱动实例
var MssqlDB = IDB.GetMysql("MssqlInstanceName");

//返回布尔值结果
bool result = db.Connect("ip","port","username","password");

设置表前缀

IDB db = db.SetDbPrefixName("Pre_");

设置主键名

当某些时候主键没办法处理为_id的情况时

IDB db = db.SetPKName("UserID");

Table 选择操作的表格

IDB db = db.Table("tableName")

Where 查询条件

string condition;
//单一条件 Mongodb 的_id是ObjectId,_id加不加单引号都可以使用
//_id为统一为数字的情况下不加单引号更好,为字符串的情况下加单引号更好
condition = "_id=123";

//且条件
condition = "_id=123 & Name='xchan'";

//或条件
condition = "_id=123 | _id=456";

//混合情况
condition = "(Name='Jack' | Name='Lisa') & Sex=1 & (Age <= 18)";

//LIKE
condition = "Name LIKE 'Jack%'";

//IN
condition = "Name IN ('Jack', 'Lisa')";

//增加布尔值兼容模式 (可以兼容 Mysql 和 Mongodb )
condition = "Has = bool:True"

IDB db = db.Where(condition)

Where Lambda查询 (暂时只支持Mysql)

// 常规查询
IDB db = db.Where<TestModel>(tableName => tableName.Name == "Jack" && tableName.Sex == 1);

// LIKE
IDB db = db.Where<TestModel>(tableName => tableName.Contains("%Jack%"));

// IN
IDB db = db.Where<TestModel>(tableName => tableName.InList("'Jack','Lisa'"));

// 传值查询
// 传字符串类型时,如果是字符串需要加单引号
var InList1 = "'Jack','Lisa'";
var InList2 = "'李小龙','李连杰'";
IDB db = db.Where<TestModel>(tableName => tableName.Name.InList("{0}") && tableName.Name.InList("{1}"), InList1, inList2);

// 传数组 ,数组类型系统自动判断所以不需要传单引号
var inlist1 = new[] { 1, 2};
var inlist2 = new[] { "Jack", "Lisa" };
var objParams = new[] { inlist1, inlist2 };
IDB db = db.Where<TestModel>(tableName => tableName.Sex.InList("{0}") && tableName.Name.InList("{1}")), objParams);

注意 =!= 字符串尽量使用 '单引号' 包起来.这样在使用 MongodbMysql 的时候具有一定的兼容性

Sort 排序

//正序
db.Sort("Money", asc: true)
//倒序
db.Sort("Money", asc: false)

Page 分页获取数据

//按照10条每页规则获取第一页
IDB db = db.Page(size:10, pageNum:1);

Count 获取数据数量

long count = db.Count();

//可以指定一个字段名
long idCount = db.Count("_id");

FindOne / FindAll / Distinct 获取数据

/************单条数据示例************/

//按照字典类型返回数据
Dictionary<string, object> result = db.FindOne<Dictionary<string, object>>();

//按照模型返回数据
UserModel user = db.FindOne<UserModel>();


/************多条数据示例************/

//按照字典类型返回数据
List<Dictionary<string, object>> results = db.FindAll<Dictionary<string, object>>();

//按照模型返回数据
List<UserModel> user = db.FindAll<UserModel>();

//去重获取列表(同FindAll指定了去重字段)
List<UserModel> user = db.Distinct<UserModel>("Age");

Insert / Update / Delete 增删改

//准备数据
Dictionary<string, object> data = new Dictionary<string, object>();
data.Add("Name", "SuperMan");

//新增一条数据
string insertId = db.Insert(data);

//修改一条或多条数据
long count = db.Where("_id=xxx").Update(data);
long count = db.Where("Name=xchan").UpdateMany(data);
//修改全部
long count = db.UpdateMany(data);

//修改或新增数据
long insertId = db.Where("Name=Jack").UpdateInsert(data);

//删除一条或多条数据
db.Where("_id=xxx").Delete();
db.Where("Name=xchan").DeleteMany();
//删除所有数据
db.DeleteMany();

注意:为了安全删改 Update() 和 Delete() 函数不存在Where条件则会抛出异常.

UpdateFieldValue 原字段修改

//向后追加
db.Where("UserName=xxx").UpdateFieldValue("UserName", "$UserName_A");

//向前追加
db.Where("UserName=xxx_A").UpdateFieldValue("UserName", "B_$UserName");

可以使用 $字段名 代替原字段的值 原来的UserName为 xxx 的用户全部被更名为 B_xxx_A

Inc 字段值加减

//增加
db.Where("_id=xxx").Inc("Money", +100);

//减少
db.Where("_id=xxx").Inc("Money", -99);

Sum 求和

//不分组求和
db.Sum("Money");

//分组求和
db.Sum("Money", "Sex");

Avg 取平均值

//不分组求和
db.Avg("Money");

//分组求和
db.Avg("Money", "Sex");

Join 联表查询 (暂时只支持SQL)

为了有更好的性能,请尽量不要超过3表联查!

List<Dictionary<string, object>> items = MysqlDB.Table("T1")
    .Where("T1.Name = 'xchan'")
    .Join("T2", "T2.Tid = T1._id")
    .FindAll<Dictionary<string, object>>(new string[] { "T1.*", "T2.Sex" });

Query 语句执行 (暂时只支持SQL)

List<Dictionary<string, object>> items = MysqlDB.Query<Dictionary<string, object>>("SELECT * FROM TableName");

使用示例

class Demo : Router
{
    private IDB db;
    
    public Demo()
    {
        //暂时只开放了MongoDB的驱动
        db = IDB.GetMongoDB("InstanceName");
        try
        {
            if (db.Connect("ip","port","username","password")
            {
                db.Database("DemoDB");
            }
        }
        catch (Exception)
        {
            throw new Exception("数据库连接失败");
        }
    }
    
    public void Test()
    {
        var password = "123456";
        UserModel user = new UserModel(db) { UserName = "admin", Password = password };
        var addResult = user.Add();
        Logger.Debug("添加用户==>" + addResult);

        var newpassword = "654321";
        user.Password = newpassword;
        var upResult = user.UpdatePassword(password);
        Logger.Debug("修改密码==>" + upResult);

        Logger.Debug("验证登录==>" + user.Auth("admin", newpassword));

        user.Delete();
        Logger.Debug("删除用户==>");

        ResponseWriteBody("Success!");
    }
}

定义一个UserModel

public class UserModel : BaseModels
{
    private string md5Key = "3FyiLohfC7kxDvL1";
    private IDB db;
    public UserModel(IDB db)
    {
        this.db = db;
    }

    //为了兼容数据库,_id类型要指定为object
    public object _id { get; set; }
    // 用户名
    public string UserName { get; set; }
    // 密码
    public string Password { get; set; }
    // 验证用户
    public string Auth(string username, string password)
    {
        var user = db.Table("User").Where($"UserName={username}&Password={GenerateMD5(GenerateMD5(password) + md5Key)}").FindOne<UserModel>();
        return user == null ? "" : user._id.ToString();
    }

    // 新增用户
    public string Add()
    {
        if (db.Table("User").Where($"UserName={UserName}").Count() > 0)
        {
            return "";
        }

        Dictionary<string, object> data = new Dictionary<string, object>();
        data.Add("UserName", UserName);
        data.Add("Password", GenerateMD5(GenerateMD5(Password) + md5Key));
        this._id = db.Table("User").Insert(data);
        return this._id.ToString();
    }

    // 更新密码
    public long UpdatePassword(string oldPwd)
    {
        string whereId;
        if (_id == null)
        {
            if (UserName == "")
            {
                return -2;
            }
            whereId = "UserName=" + UserName;
        }
        else
        {
            whereId = "_id=" + _id;
        }
        Dictionary<string, object> data = new Dictionary<string, object>();
        data.Add("Password", GenerateMD5(GenerateMD5(Password) + md5Key));
        return db.Table("User").Where($"({whereId})&Password=" + GenerateMD5(GenerateMD5(oldPwd) + md5Key)).Update(data);
    }

    // 删除用户
    public void Delete()
    {
        db.Table("User").Where("_id=" + _id).Delete();
        db.Table("UserFormData").Where("TargetId=" + _id).Delete();
    }

    private string GenerateMD5(string txt)
    {
        using (MD5 mi = MD5.Create())
        {
            byte[] buffer = Encoding.Default.GetBytes(txt);
            byte[] newBuffer = mi.ComputeHash(buffer);
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < newBuffer.Length; i++)
            {
                sb.Append(newBuffer[i].ToString("x2"));
            }
            return sb.ToString();
        }
    }
}

多线程使用问题

Table方法会自动创建实例对象

//多例
var db1 = IDB.GetMongoDB("one");
var db2 = IDB.GetMongoDb("two");

//释放实例
db1.DisposeInstance("one");
db2.DisposeInstance("two");

//多库多线程
var db = IDB.GetMongoDB("dbName");
var db1 = db.Database("DB1")
var db2 = db.Database("DB2")

//释放数据库
db1.Dispose();
db2.Dispose();