还是一如既往先把结构图放出来,上上个版本添加了redis的缓存,但是不满足我的需求,因为公司有项目要求是分布式所以呢,这里我就增加了mongoDb进行缓存分布式,好了先看结构图(1)。

总的来说比较蛋疼,因为从来没有使用过mongoDB,从安装,到转为windows服务,设置权限等等,好吧这都是题外话。

在写这个MongoDB版本的时候遇到的一些问题,我先总结下:

1.MongoDb版本是官网最新版3.4.4,官方驱动为2.4.3,首先我的项目是以GUID做为主键,在往MongonDB中插入时遇到的是将GUID生成了MongoDB的LUUID格式产生了这样的格式(2)并且和我的数据库不同(3)当然redis也不同(4)。

a)带着问题我们去解决查了文档发现原来因为bson的键要标识成GUID,并且格式要转为string,既然知道问题了就去解决找到我的GUID主键,如下图(5):

在主键上加上 [BsonId(IdGenerator = typeof(GuidGenerator)), BsonRepresentation(BsonType.String)]这段就可以了,看了下效果确实可以了(6)。

2.但是在测试过程中查询的时候却找不到,一查原来我的数据库redis的id值都不一样,这又是怎么回事?

b)原来mongoDB生成的GUID和C#生成的GUID的进制是不一样的,为了解决这个问题,Google了一下,找到了一个脚本,把这个js脚本放在mongoDB里面执行一下,然后生成的GUID就和数据库的一样了。如图(7):

然后生成的_id就和我数据redis的一样了。(8)(9)

解决完成这些问题后开始写自己的封装类。

希望大家多给出建议,博主也是第一次玩mongoDB,如果有好的学习资源也请推荐给博主。

第一步创建连接:

using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace KuRuMi.Mio.DoMain.MongoDbCache.MongoDbCommon
{
public class MongoDbManager
{
private static IMongoDatabase db = null;
private static readonly object locker = new object();
/// <summary>
/// 使用单列模式创建连接
/// </summary>
/// <returns></returns>
public static IMongoDatabase CreateDb()
{
if (db == null)
{
lock (locker)
{
if (db == null)
{
MongoClient Client = new MongoClient(MongoDbConfig.Host);
db = Client.GetDatabase(MongoDbConfig.DataBase);
}
}
}
return db;
}
}
}

第二步创建DB:

using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace KuRuMi.Mio.DoMain.MongoDbCache.MongoDbCommon
{
public class MongoDbBase
{
private IMongoDatabase db = null;
public IMongoDatabase Db { get => db; }
public MongoDbBase()
{
db = MongoDbManager.CreateDb();
}
}
}

然后呢献上自己的封装helper:

using KuRuMi.Mio.DoMain.MongoDbCache.MongoDbCommon;
using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks; namespace KuRuMi.Mio.DoMain.MongoDbCache.MongoDbCache
{
/// <summary>
/// MongoDb缓存
/// </summary>
public sealed class MongoDbCacheService : MongoDbBase
{
#region 同步
#region 增加
/// <summary>
/// 保存单个对象
/// </summary>
/// <param name="Root"></param>
/// <returns></returns>
public bool AddSignleObject<TAggregateRoot>(TAggregateRoot Root)
{
try
{
var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
collection.InsertOne(Root);
return true;
}
catch (Exception)
{
return false;
} }
/// <summary>
/// 批量保存多个对象
/// </summary>
/// <param name="Root"></param>
/// <returns></returns>
public bool AddManyObject<TAggregateRoot>(List<TAggregateRoot> Root)
{
try
{
var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
collection.InsertMany(Root);
return true;
}
catch (Exception)
{
return false;
} }
#endregion #region 删除
/// <summary>
/// 删除单个记录
/// </summary>
/// <typeparam name="TAggregateRoot"></typeparam>
/// <param name="parameter"></param>
/// <returns></returns>
public int DeleteSingleIndex<TAggregateRoot>(Expression<Func<TAggregateRoot, bool>> filter)
{
try
{
var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
return (int)collection.DeleteOne(filter).DeletedCount;
}
catch (Exception e)
{
throw e;
}
}
#endregion #region 查询
/// <summary>
/// 查询单条记录
/// </summary>
/// <typeparam name="TAggregateRoot"></typeparam>
/// <param name="parameter"></param>
/// <returns></returns>
public TAggregateRoot FindSingleIndex<TAggregateRoot>(Expression<Func<TAggregateRoot, bool>> filter)
{
try
{
var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
return collection.Find(filter).FirstOrDefault();
}
catch (Exception e)
{
throw e;
}
}
/// <summary>
/// 查询整个集合
/// </summary>
/// <typeparam name="TAggregateRoot"></typeparam>
/// <param name="filter"></param>
/// <returns></returns>
public List<TAggregateRoot> FindMany<TAggregateRoot>(Expression<Func<TAggregateRoot, bool>> filter)
{
try
{
var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
return collection.Find(filter).ToList();
}
catch (Exception e)
{
throw e;
}
}
#endregion #region 更新
/// <summary>
/// 更新单个值
/// </summary>
/// <typeparam name="TAggregateRoot"></typeparam>
/// <param name="filter"></param>
/// <param name="field"></param>
/// <param name="parameter"></param>
/// <returns></returns>
public int UpdateSingle<TAggregateRoot>(Expression<Func<TAggregateRoot, bool>> filter, string name, string parameter)
{
try
{
var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
var set = Builders<TAggregateRoot>.Update.Set(name, parameter);
return (int)collection.UpdateOne(filter, set).ModifiedCount;
}
catch (Exception e)
{
throw e;
}
}
/// <summary>
/// 更新多个值
/// </summary>
/// <typeparam name="TAggregateRoot"></typeparam>
/// <param name="filter"></param>
/// <param name="Root"></param>
/// <param name="property"></param>
/// <param name="replace"></param>
public int UpdateMany<TAggregateRoot>(Expression<Func<TAggregateRoot, bool>> filter, TAggregateRoot Root, List<string> property = null, bool replace = false)
{
try
{
var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
var type = Root.GetType();
//修改集合
var list = new List<UpdateDefinition<TAggregateRoot>>();
foreach (var propert in type.GetProperties())
{
if (propert.Name.ToLower() != "id")
{
try
{
if (property == null && property.Count < || property.Any(o => o.ToLower() == propert.Name.ToLower()))
{
var replaceValue = propert.GetValue(Root);
if (replaceValue != null)
list.Add(Builders<TAggregateRoot>.Update.Set(propert.Name, replaceValue));
else if (replace)
list.Add(Builders<TAggregateRoot>.Update.Set(propert.Name, replaceValue));
}
}
catch (Exception)
{
if (property == null)
{
var replaceValue = propert.GetValue(Root);
if (replaceValue != null)
list.Add(Builders<TAggregateRoot>.Update.Set(propert.Name, replaceValue));
else if (replace)
list.Add(Builders<TAggregateRoot>.Update.Set(propert.Name, replaceValue));
}
} }
}
if (list.Count > )
{
var builders = Builders<TAggregateRoot>.Update.Combine(list);
return (int)collection.UpdateOne(filter, builders).ModifiedCount;
}
return ;
}
catch (Exception e)
{
throw e;
}
}
#endregion
#endregion #region 异步
#region 增加
/// <summary>
/// 异步保存单个对象
/// </summary>
/// <param name="Root"></param>
/// <returns></returns>
public bool AddSignleObjectAsync<TAggregateRoot>(TAggregateRoot Root)
{
try
{
var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
collection.InsertOneAsync(Root);
return true;
}
catch (Exception)
{
return false;
} }
/// <summary>
/// 批量保存多个对象
/// </summary>
/// <param name="Root"></param>
/// <returns></returns>
public bool AddManyObjectAsync<TAggregateRoot>(List<TAggregateRoot> Root)
{
try
{
var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
collection.InsertManyAsync(Root);
return true;
}
catch (Exception)
{
return false;
} }
#endregion #region 删除
/// <summary>
/// 异步删除单个记录
/// </summary>
/// <typeparam name="TAggregateRoot"></typeparam>
/// <param name="parameter"></param>
/// <returns></returns>
public int DeleteSingleIndexAsync<TAggregateRoot>(Expression<Func<TAggregateRoot, bool>> filter)
{
try
{
var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
return (int)collection.DeleteOneAsync(filter).Result.DeletedCount;
}
catch (Exception e)
{
throw e;
}
}
#endregion #region 查询
/// <summary>
/// 异步查询单条记录
/// </summary>
/// <typeparam name="TAggregateRoot"></typeparam>
/// <param name="parameter"></param>
/// <returns></returns>
public TAggregateRoot FindSingleIndexAsync<TAggregateRoot>(Expression<Func<TAggregateRoot, bool>> filter)
{
try
{
var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
return collection.FindAsync(filter).Result.FirstOrDefault();
}
catch (Exception e)
{
throw e;
}
}
/// <summary>
/// 异步查询整个集合
/// </summary>
/// <typeparam name="TAggregateRoot"></typeparam>
/// <param name="filter"></param>
/// <returns></returns>
public List<TAggregateRoot> FindManyAsync<TAggregateRoot>(Expression<Func<TAggregateRoot, bool>> filter)
{
try
{
var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
return collection.FindAsync(filter).Result.ToList();
}
catch (Exception e)
{
throw e;
}
}
#endregion #region 更新
/// <summary>
/// 异步更新单个值
/// </summary>
/// <typeparam name="TAggregateRoot"></typeparam>
/// <param name="filter"></param>
/// <param name="field"></param>
/// <param name="parameter"></param>
/// <returns></returns>
public int UpdateSingleAsync<TAggregateRoot>(Expression<Func<TAggregateRoot, bool>> filter, string name, string parameter)
{
try
{
var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
var set = Builders<TAggregateRoot>.Update.Set(name, parameter);
return (int)collection.UpdateOneAsync(filter, set).Result.ModifiedCount;
}
catch (Exception e)
{
throw e;
}
}
/// <summary>
///异步更新多个值
/// </summary>
/// <typeparam name="TAggregateRoot"></typeparam>
/// <param name="filter"></param>
/// <param name="Root"></param>
/// <param name="property"></param>
/// <param name="replace"></param>
public int UpdateManyAsync<TAggregateRoot>(Expression<Func<TAggregateRoot, bool>> filter, TAggregateRoot Root, List<string> property = null, bool replace = false)
{
try
{
var collection = Db.GetCollection<TAggregateRoot>(typeof(TAggregateRoot).Name);
var type = Root.GetType();
//修改集合
var list = new List<UpdateDefinition<TAggregateRoot>>();
foreach (var propert in type.GetProperties())
{
if (propert.Name.ToLower() != "id")
{
try
{
if (property == null && property.Count < || property.Any(o => o.ToLower() == propert.Name.ToLower()))
{
var replaceValue = propert.GetValue(Root);
if (replaceValue != null)
list.Add(Builders<TAggregateRoot>.Update.Set(propert.Name, replaceValue));
else if (replace)
list.Add(Builders<TAggregateRoot>.Update.Set(propert.Name, replaceValue));
}
}
catch (Exception)
{
if (property == null)
{
var replaceValue = propert.GetValue(Root);
if (replaceValue != null)
list.Add(Builders<TAggregateRoot>.Update.Set(propert.Name, replaceValue));
else if (replace)
list.Add(Builders<TAggregateRoot>.Update.Set(propert.Name, replaceValue));
}
} }
}
if (list.Count > )
{
var builders = Builders<TAggregateRoot>.Update.Combine(list);
return (int)collection.UpdateOneAsync(filter, builders).Result.ModifiedCount;
}
return ;
}
catch (Exception e)
{
throw e;
}
}
#endregion
#endregion
}
}

最后是脚本文件:

function HexToBase64(hex) {
var base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var base64 = "";
var group;
for (var i = 0; i < 30; i += 6) {
group = parseInt(hex.substr(i, 6), 16);
base64 += base64Digits[(group >> 18) & 0x3f];
base64 += base64Digits[(group >> 12) & 0x3f];
base64 += base64Digits[(group >> 6) & 0x3f];
base64 += base64Digits[group & 0x3f];
}
group = parseInt(hex.substr(30, 2), 16);
base64 += base64Digits[(group >> 2) & 0x3f];
base64 += base64Digits[(group << 4) & 0x3f];
base64 += "==";
return base64;
} function Base64ToHex(base64) {
var base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var hexDigits = "0123456789abcdef";
var hex = "";
for (var i = 0; i < 24;) {
var e1 = base64Digits.indexOf(base64[i++]);
var e2 = base64Digits.indexOf(base64[i++]);
var e3 = base64Digits.indexOf(base64[i++]);
var e4 = base64Digits.indexOf(base64[i++]);
var c1 = (e1 << 2) | (e2 >> 4);
var c2 = ((e2 & 15) << 4) | (e3 >> 2);
var c3 = ((e3 & 3) << 6) | e4;
hex += hexDigits[c1 >> 4];
hex += hexDigits[c1 & 15];
if (e3 != 64) {
hex += hexDigits[c2 >> 4];
hex += hexDigits[c2 & 15];
}
if (e4 != 64) {
hex += hexDigits[c3 >> 4];
hex += hexDigits[c3 & 15];
}
}
return hex;
} function UUID(uuid) {
var hex = uuid.replace(/[{}-]/g, ""); // remove extra characters
var base64 = HexToBase64(hex);
return new BinData(4, base64); // new subtype 4
} function JUUID(uuid) {
var hex = uuid.replace(/[{}-]/g, ""); // remove extra characters
var msb = hex.substr(0, 16);
var lsb = hex.substr(16, 16);
msb = msb.substr(14, 2) + msb.substr(12, 2) + msb.substr(10, 2) + msb.substr(8, 2) + msb.substr(6, 2) + msb.substr(4, 2) + msb.substr(2, 2) + msb.substr(0, 2);
lsb = lsb.substr(14, 2) + lsb.substr(12, 2) + lsb.substr(10, 2) + lsb.substr(8, 2) + lsb.substr(6, 2) + lsb.substr(4, 2) + lsb.substr(2, 2) + lsb.substr(0, 2);
hex = msb + lsb;
var base64 = HexToBase64(hex);
return new BinData(3, base64);
} function CSUUID(uuid) {
var hex = uuid.replace(/[{}-]/g, ""); // remove extra characters
var a = hex.substr(6, 2) + hex.substr(4, 2) + hex.substr(2, 2) + hex.substr(0, 2);
var b = hex.substr(10, 2) + hex.substr(8, 2);
var c = hex.substr(14, 2) + hex.substr(12, 2);
var d = hex.substr(16, 16);
hex = a + b + c + d;
var base64 = HexToBase64(hex);
return new BinData(3, base64);
} function PYUUID(uuid) {
var hex = uuid.replace(/[{}-]/g, ""); // remove extra characters
var base64 = HexToBase64(hex);
return new BinData(3, base64);
} BinData.prototype.toUUID = function () {
var hex = Base64ToHex(this.base64()); // don't use BinData's hex function because it has bugs in older versions of the shell
var uuid = hex.substr(0, 8) + '-' + hex.substr(8, 4) + '-' + hex.substr(12, 4) + '-' + hex.substr(16, 4) + '-' + hex.substr(20, 12);
return 'UUID("' + uuid + '")';
} BinData.prototype.toJUUID = function () {
var hex = Base64ToHex(this.base64()); // don't use BinData's hex function because it has bugs in older versions of the shell
var msb = hex.substr(0, 16);
var lsb = hex.substr(16, 16);
msb = msb.substr(14, 2) + msb.substr(12, 2) + msb.substr(10, 2) + msb.substr(8, 2) + msb.substr(6, 2) + msb.substr(4, 2) + msb.substr(2, 2) + msb.substr(0, 2);
lsb = lsb.substr(14, 2) + lsb.substr(12, 2) + lsb.substr(10, 2) + lsb.substr(8, 2) + lsb.substr(6, 2) + lsb.substr(4, 2) + lsb.substr(2, 2) + lsb.substr(0, 2);
hex = msb + lsb;
var uuid = hex.substr(0, 8) + '-' + hex.substr(8, 4) + '-' + hex.substr(12, 4) + '-' + hex.substr(16, 4) + '-' + hex.substr(20, 12);
return 'JUUID("' + uuid + '")';
} BinData.prototype.toCSUUID = function () {
var hex = Base64ToHex(this.base64()); // don't use BinData's hex function because it has bugs in older versions of the shell
var a = hex.substr(6, 2) + hex.substr(4, 2) + hex.substr(2, 2) + hex.substr(0, 2);
var b = hex.substr(10, 2) + hex.substr(8, 2);
var c = hex.substr(14, 2) + hex.substr(12, 2);
var d = hex.substr(16, 16);
hex = a + b + c + d;
var uuid = hex.substr(0, 8) + '-' + hex.substr(8, 4) + '-' + hex.substr(12, 4) + '-' + hex.substr(16, 4) + '-' + hex.substr(20, 12);
return 'CSUUID("' + uuid + '")';
} BinData.prototype.toPYUUID = function () {
var hex = Base64ToHex(this.base64()); // don't use BinData's hex function because it has bugs
var uuid = hex.substr(0, 8) + '-' + hex.substr(8, 4) + '-' + hex.substr(12, 4) + '-' + hex.substr(16, 4) + '-' + hex.substr(20, 12);
return 'PYUUID("' + uuid + '")';
} BinData.prototype.toHexUUID = function () {
var hex = Base64ToHex(this.base64()); // don't use BinData's hex function because it has bugs
var uuid = hex.substr(0, 8) + '-' + hex.substr(8, 4) + '-' + hex.substr(12, 4) + '-' + hex.substr(16, 4) + '-' + hex.substr(20, 12);
return 'HexData(' + this.subtype() + ', "' + uuid + '")';
}

仓储层的调用:

using KuRuMi.Mio.DoMain.Model.Model;
using KuRuMi.Mio.DoMain.Model.Repositories;
using KuRuMi.Mio.DoMain.Repository.EFRepository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace KuRuMi.Mio.DoMain.Repository.ModelRepository
{
public class UserRepositoryImpl : RepositoryImpl<User>, IUserRepository
{
public KurumiMioDbContext context => lazy.Context as KurumiMioDbContext;
/// <summary>
/// 登录
/// </summary>
/// <param name="Email"></param>
/// <param name="PassWord"></param>
/// <returns></returns>
public string CheckUser(string Email, string PassWord)
{
try
{
User entity = null;
//MongoDb取
entity = Mongo.FindSingleIndex<User>(a => a.Email == Email);
if (entity == null)
{
//redis取
entity = Redis.RedisString.Value.StringGet<User>(Email);
}
if (entity == null)
{
//数据库取
string sql = "select Id,UserName,Password,email from [User] as a where a.Email ='{0}' and a.PassWord ='{1}'";
string select = string.Format(sql, Email, PassWord);
entity = context.user.SqlQuery(select).FirstOrDefault();
}
return entity.UserName;
}
catch (Exception e)
{
return "";
}
} /// <summary>
/// 保存
/// </summary>
/// <param name="aggregateRoot"></param>
public async override void Add(User aggregateRoot)
{
base.Add(aggregateRoot);
await Redis.RedisString.Value.StringSetAsync(aggregateRoot.Email, aggregateRoot);//保存一份到redis
Mongo.AddSignleObjectAsync(aggregateRoot);//保存一份到mongoDb
} /// <summary>
/// 注册
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
public User GetAll(User info)
{
string sql = "select Id,UserName,Password,email from [User] as a where a.UserName ='{0}' and email ='{1}'";
string select = string.Format(sql, info.UserName, info.Email);
return context.user.SqlQuery(select).FirstOrDefault();
}
}
}

图1:

图2:

图3:

图4:

图5:

图6:

图7:

图8:

图9:

基于官方驱动封装mongodb的更多相关文章

  1. [转载]在C#中使用官方驱动操作MongoDB

    在C#中使用官方驱动操作MongoDB 8.1)下载安装 想要在C#中使用MongoDB,首先得要有个MongoDB支持的C#版的驱动.C#版的驱动有很多种,如官方提供的,samus. 实现思路大都类 ...

  2. 在.net下打造mongoDb基于官方驱动最新版本

    还是一如既往先把结构图放出来,上上个版本添加了redis的缓存,但是不满足我的需求,因为公司有项目要求是分布式所以呢,这里我就增加了mongoDb进行缓存分布式,好了先看结构图. 总的来说比较蛋疼,因 ...

  3. 在C#中使用官方驱动操作MongoDB

    MongoDB的官方驱动下载地址:https://github.com/mongodb/mongo-csharp-driver/releases 目前最新的版本是2.10,支持.NET 4.5以上.由 ...

  4. C#中使用官方驱动操作MongoDB

    想要在C#中使用MongoDB,首先得要有个MongoDB支持的C#版的驱动.C#版的驱动有很多种,如官方提供的,samus. 实现思路大都类似.这里我们先用官方提供的mongo-csharp-dri ...

  5. C#/.NET 使用官方驱动操作MongoDB(一):插入、查询

    概述 想要在C#中使用MongoDB,首先得要有个MongoDB支持的C#版的驱动. C#版的驱动有很多,这里我们先用官方提供的 MongoDB.Driver(使用 Nuget 安装),当前版本为2. ...

  6. 使用MongoDB C#官方驱动操作MongoDB

    想要在C#中使用MongoDB,首先得要有个MongoDB支持的C#版的驱动.C#版的驱动有很多种,如官方提供的,samus. 实现思路大都类似.这里我们先用官方提供的mongo-csharp-dri ...

  7. 在C#中使用官方驱动操作MongoDB ---转载

    http://blog.csdn.net/dannywj1371/article/details/7440916

  8. C#基于Mongo的官方驱动手撸一个Super简易版MongoDB-ORM框架

    C#基于Mongo的官方驱动手撸一个简易版MongoDB-ORM框架 如题,在GitHub上找了一圈想找一个MongoDB的的ORM框架,未偿所愿,就去翻了翻官网(https://docs.mongo ...

  9. 适用于app.config与web.config的ConfigUtil读写工具类 基于MongoDb官方C#驱动封装MongoDbCsharpHelper类(CRUD类) 基于ASP.NET WEB API实现分布式数据访问中间层(提供对数据库的CRUD) C# 实现AOP 的几种常见方式

    适用于app.config与web.config的ConfigUtil读写工具类   之前文章:<两种读写配置文件的方案(app.config与web.config通用)>,现在重新整理一 ...

随机推荐

  1. openfire Android学习(一)----实现用户注册、登录、修改密码和注销等

    以前学习过用Scoket 建立聊天,简单的建立聊天是没问题的,但如果要实现多人复杂的聊天,后台服务器代码就比较复杂,对于我这新手来讲就比较难了.后来在网上看到用openfire做服务器,利用强大的Sm ...

  2. docker run 报错——WARNING: IPv4 forwarding is disabled. Networking will not work.

    执行  docker run  时遇到如下WARNING: [root@etcd1 volumes]# docker run -d -p 8080:80 -v /tmp/test_mount http ...

  3. sqlalchemy如何实现时间列自动更新?

    目标:数据表的时间列在其他列内容更新的时候,自动更新时间列到更新的时间 方法:数据库表模型如下:server_default表示初始时间,onupdate表示更新的时间 class MonitorDa ...

  4. SilverLight:基础控件使用(5)-TreeView控件-基本使用

    ylbtech-SilverLight-Basic-Control:基础控件使用(5)-TreeView控件-基本使用 前台编辑 后台逐个添加 后台绑定数据源 1.A,返回顶部TreeView控件(树 ...

  5. Python 自动登录网站(处理Cookie)

    http://digiter.iteye.com/blog/1300884 Python代码   def login():     cj = cookielib.CookieJar()     ope ...

  6. shell(3):文本处理、基本语法和脚本编写

    一.awk.变量.运算符.if多分支 awk:shell编辑器的一种文本处理工具/命令,同grep.sed一样均可解释正则.具体运用下面awk文本处理有详细说明. 变量:分为系统变量和临时变量.变量一 ...

  7. .net网站上传图片换电脑不显示 当不用网站的IP地址访问图片,只用相对路径访问时,在发布网站的时候,将上传图片的目标文件夹,包含在项目中再发布即可。

    .net网站上传图片换电脑不显示 当不用网站的IP地址访问图片,只用相对路径访问时,在发布网站的时候,将上传图片的目标文件夹,包含在项目中再发布即可.

  8. Python+Selenium框架unittest执行脚本方法之discover()方法

    继续接着介绍,如何利用unittest管理和执行测试用例的问题,这里我们还是利用之前已经有的三条测试用例,如果你跳过了前面文章,请回到框架设计篇的第八篇和第七篇,里面有相关测试类的文件.本文来介绍,如 ...

  9. Spring.net1.3.1+Nhibernate3.0+Mysql/Access/SqlServer/Oracel/SQlite

    详情请看我的博文:http://www.ruisoftcn.com/blog/article.asp?id=999

  10. SWIM接口及STM8烧录过程

    1. 硬件连接 SWIM接口只需要一根传输线,即可完成双向的传输.传输过程,都是由主控制端(host)发起,设备端然后做出反应.host端需要在一个总线上实现读和写,那就是说必须要同时接一个输出IO和 ...