最近公司网站进行升级,项目要用.net mvc,mysql和轻量级orm框架dapper。由于美工页面出不来啊,让我先写简单写写后台的列表,同事说用MvcJqGrid,也得到了架构的同意。

可是不得不说这个相关文档真不多啊,以前用过jqgrid,但是早忘透了。其实MVCJqGrid这个东西是一个HtmlHelper扩展。不多说,先来看看这个东西吧。

文档的参考地址   http://mvcjqgrid.skaele.it/

下载地址   https://github.com/robinvanderknaap/MvcJqGrid

首先项目中应该添加MvcJqGrid引用。

view视图引用@using MvcJqGrid;

因为jqgrid相对配置麻烦,所以有了MvcJqGrid,使用起来也是简单明了:

@(Html.Grid("search")                  //设置jqgrid容器,search就是其ID
.SetCaption("Toolbar Search") //设置主标题
.AddColumn(new Column("ID") //添加一列(对应数据集合的列名)
.SetLabel("Id")) //设置列标题
.AddColumn(new Column("NickName"))
.AddColumn(new Column("MobilePhone")
.SetUrl("/Home/GetPagedList_User") //请求数据的地址
.SetAutoWidth(true) //自动宽度
.SetRowNum() //每页条数
.SetRowList(new[] { , , }) //设置可选每页页数
.SetViewRecords(true) //设置显示条数
.SetPager("pager")) //设置分页,pager就是分页容器ID

这样一个简单的列表分页页面前台展示就出来了。

后台取数据简单的这种套路:

public JsonResult GetPagedList_User( GridSettings gridSettings)
{
//参数分别为排序字段,排序方式,当前页,每页条数
List<T> list=获取分页列表(gridSettings.SortColumn, gridSettings.SortOrder, gridSettings.PageIndex, gridSettings.PageSize)
if(list==null)
return Json(new{total=,page=,records=,rows=("")}, JsonRequestBehavior.AllowGet);
var jsonData = new
{
total = 获取总条数(),
page =total / gridSettings.PageSize + ;,
records = content.TotalCount,
rows = (
from c in list
select new
{
id = c.ID,
cell = new[]
{
c.ID.ToString(),
c.NickName,
c.MobilePhone,
......
}
}).ToArray()
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}

展示列表其实很简单,但是查询的时候遇到了麻烦。因为google很多示例都是使用EF这样的操作的,例如:

if (gridSettings.IsSearch)
{
name = gridSettings.Where.rules.Any(r => r.field == "Name") ?
gridSettings.Where.rules.FirstOrDefault(r => r.field == "Name").data : string.Empty;
company = gridSettings.Where.rules.Any(r => r.field == "Company") ?
gridSettings.Where.rules.FirstOrDefault(r => r.field == "Company").data : string.Empty;
}
CustomerRepository repository = new CustomerRepository();
var customers = repository.List(name, company, gridSettings.SortColumn, gridSettings.SortOrder);

乍一看看不明觉厉啊。而当需要手写查询,或者用刀轻量级orm框架需要写sql语句时,就有些手足无措了。

索性通过浏览器f12查看网站示例的请求,发现类似这种参数filters=%7B%22groupOp%22%3A%22AND%22%2C%22rules%22%3A%5B%7B%22field%22%3A%22Last+Modified%22%2C%22op%22%3A%22bw%22%2C%22data%22%3A%2208-11-2013%22%7D%5D%7D,经解码得到{"groupOp":"AND","rules":[{"field":"Last+Modified","op":"bw","data":"08-11-2013"}]}。

后来又看其源码,其实filters就是一个过滤条件类,rules是rule类的集合就是匹配的查询条件,rule类有三个属性field,op,data,意思呢就是字段名,查询方式?,值。其实有这三个就够写sql语句了。例如“select * from user where”+ rule.filed+rule.op+rule.data。

op属性目前有14个查询方式,例如:等于,不等于,小于...包含某值,以某值结束等等。这里拼接rule.op字符串要对此查询方式进行解析。

但是这里问题出来了,没有时间范围查询。


这里我找到他的MvcJqGrid.Enums下的SearchOptions枚举,添加一个RangeDate,表示时间范围。然后在用到此枚举的地方加上。MvcJqGrid下的Column类public Column SetSearchOption方法,它是设置搜索条件的方法,我们在最后添加:

/// Sets search option for column
/// </summary>
/// <param name="searchOption">Search option</param>
public Column SetSearchOption(SearchOptions searchOption)
{
switch (searchOption)
{
case SearchOptions.Equal:
_searchOption = "eq";
break;
case SearchOptions.NotEqual:
_searchOption = "ne";
break;
case SearchOptions.Less:
_searchOption = "lt";
break;
case SearchOptions.LessOrEqual:
_searchOption = "le";
break;
case SearchOptions.Greater:
_searchOption = "gt";
break;
case SearchOptions.GreaterOrEqual:
_searchOption = "ge";
break;
case SearchOptions.BeginsWith:
_searchOption = "bw";
break;
case SearchOptions.DoesNotBeginWith:
_searchOption = "bn";
break;
case SearchOptions.IsIn:
_searchOption = "in";
break;
case SearchOptions.IsNotIn:
_searchOption = "ni";
break;
case SearchOptions.EndsWith:
_searchOption = "ew";
break;
case SearchOptions.DoesNotEndWith:
_searchOption = "en";
break;
case SearchOptions.Contains:
_searchOption = "cn";
break;
case SearchOptions.DoesNotContain:
_searchOption = "nc";
break;
case SearchOptions.RangeDate://新添加的时间范围
_searchOption = "rd";
break;
}
return this;
}

好了,到现在可以了解到查询方式基本有了,但是目前来说MvcJqgrid提供的日期查询js插件是DatePicker,好像没有时间查询。于是我找到了一个好用的东西—>daterangepicker.js

下载地址:https://github.com/dangrossman/bootstrap-daterangepicker

打开一看英文的展示啊,于是我用了最笨最直接的方法,直接修改它源文件。实例中需要引用moment.min.js,和主文件daterangepicker.js。前者是一个日期处理类库,直接找到_month和_weekdays关键字,对应后面字符串Jan_Feb_Mar_Apr_......修改成一月_二月_...你懂得,Sun_Mon_Tue_...改成星期日_星期一_...注意文件保存格式应为Unicode,要不有乱码。daterangepicker我也把能看懂的展示的文字改成了中文,另外精简了下它的展示方式。看起来还不错的样子:

好了,现在就是两者关联了,直接在MvcJqgrid类库中搜索DatePicker关键字,于是又在Column类中第585行找到了,代码如下:

// SearchType datepicker
if (_searchType == Searchtype.Datepicker)
{
if (_searchDateFormat.IsNullOrWhiteSpace())
script.Append(
", dataInit:function(el){$(el).datepicker({changeYear:true, onSelect: function() {var sgrid = $('###gridid##')[0]; sgrid.triggerToolbar();},dateFormat:'dd-mm-yy'});}");
else
script.Append(
", dataInit:function(el){$(el).datepicker({changeYear:true, onSelect: function() {var sgrid = $('###gridid##')[0]; sgrid.triggerToolbar();},dateFormat:'" +
_searchDateFormat + "'});}");
}

看不太明白,只知道有个回调函数onSelect,这里估计就是要触发Jqgrid的查询事件了,但是确定按钮(未修改前叫Apply)daterangepicker中貌似没有事件啊。只能为它添加一个:

var DateRangePicker = function (element, options, cb) {
var hasOptions = typeof options == 'object';
......
this.cb = function () { };
//添加onApplyClick回调函数,用于jqgrid获取事件
this.onApplyClick = function () { };
...... //event listeners(找到它,在下面添加一句)
if (typeof options.onApplyClick == 'function') {
//此处为调用确定按钮回调
this.container.find('.ranges').on('click', 'button.applyBtn', options.onApplyClick);
}
......
}

然后修改Column类下的这里部分

// SearchType datepicker
if (_searchType == Searchtype.Datepicker)
{
if (_searchDateFormat.IsNullOrWhiteSpace())
script.Append(
",dataInit:function(el){$(el).daterangepicker({onApplyClick:function(){var sgrid = $('###gridid##')[0]; sgrid.triggerToolbar();}});}");
else
script.Append(
",dataInit:function(el){$(el).daterangepicker({format:'" + _searchDateFormat + "',onApplyClick:function(){var sgrid = $('###gridid##')[0]; sgrid.triggerToolbar();}});}");
}

好了。准备工作完了。下面要有一个通用的模板才行。我在MvcJqgrid类库中加入了一个文件夹,名字叫MyExtend。

首先需要一个枚举来标识查询的字段是不是可以用引号的(当然我的理解很粗俗)。OptionType:

/// <summary>
/// 查询时候需不需要用引号
/// </summary>
public enum OptionType
{
/// <summary>
/// 不用引号
/// </summary>
Number = ,
/// <summary>
/// 用引号
/// </summary>
String =
}

其次通过前面说过的后台列表代码,我们知道其实应该有四个属性,列表List<T>,当前页PageIndex,总条数TotalCount,总页数TotalPage。于是起了个名字叫GridContent的实体类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace MvcJqGrid.MyExtend
{
public class GridContent<T> where T : new()
{
/// <summary>
/// 查询列表 2013.11.27
/// </summary>
public List<T> GList { get; set; }
/// <summary>
/// 总条数
/// </summary>
public int TotalCount { get; set; }
/// <summary>
/// 总页数
/// </summary>
public int TotalPage { get; set; }
/// <summary>
/// 当前页
/// </summary>
public int PageIndex { get; set; }
}
}

然后就是我们要提取出来一个接口,作为获取根据条件查询的数据列表和根据条件查询的总条数。起了名字叫ICanSetGrid:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace MvcJqGrid.MyExtend
{
/// <summary>
/// 设置jqgrid的接口。后台类用到要查询列表时需实现此接口 2013.11.27
/// </summary>
/// <typeparam name="T"></typeparam>
public interface ICanSetGrid<T> where T : new()
{
/// <summary>
/// 获取分页列表
/// </summary>
/// <param name="sidx">排序字段</param>
/// <param name="sort">排序方式</param>
/// <param name="page">当前页</param>
/// <param name="rows">每页条数</param>
/// <param name="where">查询条件</param>
/// <returns></returns>
List<T> GetPagedList(string sidx, string sort, int page, int rows, string where = null);
/// <summary>
/// 获取总条数
/// </summary>
/// <param name="where">查询条件</param>
/// <returns></returns>
int GetTotalCount(string where=null);
}
}

最后就是主要的了,起名为JqGridHelper:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Web.Mvc; namespace MvcJqGrid.MyExtend
{
/// <summary>
/// jqgrid帮助,controller用到GetGridContent方法 2013.11.27
/// </summary>
public class JqGridHelper
{ /// <summary>
/// jqgrid匹配查询条件
/// </summary>
/// <param name="oType">字符串类型或者值类型</param>
/// <param name="searchOption">MvcJqGrid.Enums.SearchOptions对应的搜索条件字符串(搜索规则MvcJqGrid.Rule对应的op属性)</param>
/// <param name="column">搜索字段</param>
/// <param name="value">搜索值</param>
/// <returns>例如ID!=5,Phone like '%1581111222%'</returns>
private static string FormatSearchTerm(OptionType oType, string searchOption, string column, string value)
{
StringBuilder str = new StringBuilder();
switch (searchOption)
{
case "eq"://等于
return oType == OptionType.Number ? str.Append(column).Append("=").Append(value).ToString() : str.Append(column).Append("='").Append(value).Append("'").ToString(); case "ne"://不等于
return oType == OptionType.Number ? str.Append(column).Append("<>").Append(value).ToString() : str.Append(column).Append("<>'").Append(value).Append("'").ToString(); case "lt"://小于
return oType == OptionType.Number ? str.Append(column).Append("<").Append(value).ToString() : str.Append(column).Append("<'").Append(value).Append("'").ToString(); case "le"://小于等于
return oType == OptionType.Number ? str.Append(column).Append("<=").Append(value).ToString() : str.Append(column).Append("<='").Append(value).Append("'").ToString(); case "gt"://大于
return oType == OptionType.Number ? str.Append(column).Append(">").Append(value).ToString() : str.Append(column).Append(">'").Append(value).Append("'").ToString(); case "ge"://大于等于
return oType == OptionType.Number ? str.Append(column).Append(">=").Append(value).ToString() : str.Append(column).Append(">='").Append(value).Append("'").ToString(); case "bw"://从某处开始查询
return str.Append(column).Append(" like '").Append(value).Append("%'").ToString(); case "bn"://不从某处开始查询
return str.Append(column).Append(" not like '").Append(value).Append("%'").ToString(); case "in"://包含某值
return str.Append(column).Append(" in (").Append(value).Append(")").ToString(); case "ni"://不包含某值
return str.Append(column).Append(" not in (").Append(value).Append(")").ToString(); case "ew"://以某值结束
return str.Append(column).Append(" like '%").Append(value).Append("'").ToString(); case "en"://不以某值结束
return str.Append(column).Append(" not like '%").Append(value).Append("'").ToString(); case "cn"://包含,全字匹配
return str.Append(column).Append(" like '%").Append(value).Append("%'").ToString(); case "nc"://不包含
return str.Append(column).Append(" not like '%").Append(value).Append("%'").ToString(); case "rd"://日期范围
return GetRangeDateSearchTerm(column, value); default://默认以某处开始
return str.Append(column).Append(" like '").Append(value).Append("%'").ToString();
}
}
/// <summary>
/// 获取设置jqgrid的GridContent对象
/// </summary>
/// <typeparam name="T">操作的类</typeparam>
/// <param name="type">此处用到仅是获取类型,所以只传入T的一个实例就可以</param>
/// <param name="gridSettings">前台到后台的jqgrid参数</param>
/// <param name="SetGrid">实现ICanSetGrid接口的bll操作类</param>
/// <returns></returns>
public static GridContent<T> GetGridContent<T>(GridSettings gridSettings, ICanSetGrid<T> SetGrid) where T:new()
{
GridContent<T> content = new GridContent<T>();
if (gridSettings.IsSearch && gridSettings.Where != null)//有查询时候
{
StringBuilder rulestr = new StringBuilder();
var rules = gridSettings.Where.rules;
for (int i = ; i < rules.Length; i++)
{
rulestr.Append(JqGridHelper.FormatSearchTerm(JqGridHelper.GetOptionType(new T().GetType(), rules[i].field), rules[i].op, rules[i].field, rules[i].data)); rulestr.Append(" and ");
}
rulestr.Remove(rulestr.Length - , );
content.GList = SetGrid.GetPagedList(gridSettings.SortColumn, gridSettings.SortOrder, gridSettings.PageIndex, gridSettings.PageSize,rulestr.ToString());
content.TotalCount = SetGrid.GetTotalCount(rulestr.ToString());
}
else//没有查询时候
{
content.GList = SetGrid.GetPagedList(gridSettings.SortColumn, gridSettings.SortOrder, gridSettings.PageIndex, gridSettings.PageSize, null);
content.TotalCount = SetGrid.GetTotalCount(null);
}
//如果总条数和每页数相等,那么总页数就是2页,所以判断是一页
content.TotalPage = (content.TotalCount <= gridSettings.PageSize ? : content.TotalCount) / gridSettings.PageSize + ;
content.PageIndex = gridSettings.PageIndex;
return content;
}
/// <summary>
/// 获取类型属性
/// </summary>
/// <param name="localType">当前类类型</param>
/// <param name="columnName">属性名</param>
/// <returns></returns>
private static OptionType GetOptionType(Type localType, string columnName)
{
foreach (var item in localType.GetProperties())
{
if (item.Name == columnName)
{
string typeName = item.PropertyType.Name;
//数字返回,不需要引号
if (typeName.Contains("Int") || typeName.Contains("Double") || typeName.Contains("Decimal") || typeName.Contains("Single"))
{
return OptionType.Number;
}
//返回需要引号类型
return OptionType.String;
}
continue;
}
return OptionType.String;
}
/// <summary>
/// 日期范围条件
/// </summary>
/// <param name="column">要进行日期范围查询的字段名</param>
/// <param name="inputRange">查询值</param>
/// <returns></returns>
private static string GetRangeDateSearchTerm(string column, string inputRange)
{
Regex r = new Regex(@"(\d{8}) - (\d{8})");
if (!r.IsMatch(inputRange))
return column + " like '" + inputRange + "'";//如果不符合范围则匹配模糊查询
Match m = r.Match(inputRange);
string start = DateTime.ParseExact(m.Groups[].Value, "yyyyMMdd", Thread.CurrentThread.CurrentCulture).ToString();
string end = DateTime.ParseExact(m.Groups[].Value, "yyyyMMdd", Thread.CurrentThread.CurrentCulture).AddSeconds().ToString();
return column + " between '" + start + "' and '" + end + "' ";
}
}
}

下面是例子,首先是相关Bll层的操作类实现ICanSetGrid<T>,两个方法对应Dao层的方法应该不难吧,这里举个栗子:

/// <summary>
/// 获得数据列表
/// </summary>
public List<UserInfo> GetEntityList(string strWhere)
{
try
{
StringBuilder strSql = new StringBuilder();
strSql.Append("select * FROM UserInfo ");
if (strWhere.Trim() != "")
{
strSql.Append(" where " + strWhere);
}
IEnumerable<UserInfo> list = null;
using (var conn = DbConnect.MysqlConnectObj())
{
list = conn.Query<UserInfo>(strSql.ToString(), null);
}
if (list != null && list.Count() > )
return list.ToList();
return null;
}
catch (Exception e)
{
throw new LDSystemException("UserInfo0x15", "系统错误", e);
}
} /// <summary>
/// 分页获取查询所得到的用户列表
/// </summary>
/// <param name="where">查询条件,默认为1=1</param>
/// <param name="sidx">排序字段</param>
/// <param name="sort">升序降序</param>
/// <param name="page">当前页</param>
/// <param name="rows">每页条数</param>
/// <returns></returns>
public List<UserInfo> GetEntityPagedList(string where, string sidx, string sort, int page, int rows)
{
return GetEntityList((string.IsNullOrEmpty(where) ? " 1=1 " : where) + "order by " + sidx + " " + sort + " limit " + (page - ) * rows + "," + rows);
} /// <summary>
/// 获取用户数量
/// </summary>
/// <param name="where">条件</param>
/// <returns></returns>
public int GetTotalCount(string where)
{
try
{
StringBuilder sb = new StringBuilder();
sb.Append("select count(1) as Count from UserInfo ");
if (!string.IsNullOrEmpty(where))
{
sb.Append(" where ");
sb.Append(where);
}
using (var conn = DbConnect.MysqlConnectObj())
{
var query = conn.Query(sb.ToString()).Single();
if (query == null)
{
return ;
}
else
{
return (int)query.Count;
}
}
}
catch (Exception e)
{
throw new LDSystemException("UserInfo0x25", "系统错误", e);
}
}

然后是Controller中的例子了:

public JsonResult GetPagedList_User( GridSettings gridSettings)
{
GridContent<UserInfo> content = JqGridHelper.GetGridContent<UserInfo>(gridSettings, UserInfoBll.CreateInstance());
if(content.GList==null)
return Json(new{total=,page=,records=,rows=("")}, JsonRequestBehavior.AllowGet);
var jsonData = new
{
total = content.TotalPage,
page = content.PageIndex,
records = content.TotalCount,
rows = (
from c in content.GList
select new
{
id = c.UserID,
cell = new[]
{
c.UserID.ToString(),
c.NickName,
c.Phone,
c.EMail,
c.LastLoginTime.ToString("yyyy-MM-dd HH:mm"),
c.isAct==?"激活":"未激活",
}
}).ToArray()
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}

最后来看下页面展示吧:

@using MvcJqGrid;
@{
ViewBag.Title = "UserList";
}
<link href="~/Content/jqgrid/css/jquery-ui-custom.min.css" rel="stylesheet" />
<link href="~/Content/jqgrid/css/ui.jqgrid.css" rel="stylesheet" />
<link href="~/Content/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<link href="~/Content/daterangepicker/css/daterangepicker-bs3.css" rel="stylesheet" /> <script src="~/Scripts/jquery-1.8.3.min.js"></script>
<script src="~/Content/jqgrid/js/grid.locale-cn.js"></script>
<script src="~/Content/jqgrid/js/jquery.jqGrid.min.js"></script>
<script src="~/Content/daterangepicker/js/moment.min.js" charset="utf-8"></script>
<script src="~/Content/daterangepicker/js/daterangepicker.js"></script> <h2>用户列表</h2> @(Html.Grid("UserGrid")//定义容器ID
.SetCaption("用户列表")//设置标题
.AddColumn(new Column("UserID").SetLabel("ID").SetSearch(false))
.AddColumn(new Column("NickName").SetLabel("昵称").SetSearchOption(MvcJqGrid.Enums.SearchOptions.Contains))
.AddColumn(new Column("Phone").SetLabel("手机号").SetSearchOption(MvcJqGrid.Enums.SearchOptions.Contains))
.AddColumn(new Column("EMail").SetLabel("邮箱").SetSearchOption(MvcJqGrid.Enums.SearchOptions.Contains))
.AddColumn(new Column("LastLoginTime").SetLabel("最后登录时间").SetSearchType(MvcJqGrid.Enums.Searchtype.Datepicker).SetSearchOption(MvcJqGrid.Enums.SearchOptions.RangeDate))
.AddColumn(new Column("isAct").SetLabel("是否激活").SetSearchType(MvcJqGrid.Enums.Searchtype.Select).SetSearchTerms(new Dictionary<string, string>() { {"0","未激活"},{"1","激活"}}).SetSearchOption(MvcJqGrid.Enums.SearchOptions.Equal))
.SetUrl(Url.Action("GetPagedList_User", "UserInfo")).SetRowNumbers(true)//设置取数据的地址
.SetSortName("UserID")//默认排序
.SetAutoWidth(true)
.SetHeight(450)
.SetRowNum(10)//设置每页条数
.SetRowList(new[] { 10, 15, 20 })//可选择每页条数
.SetViewRecords(true)//显示条数
.SetSearchToolbar(true).SetSearchOnEnter(true)//设置可以搜索
.SetPager("pager")//设置分页
.SetLoadText("请等待")
.SetMultiSelect(true)
.SetToolbar(true).SetToolbarPosition(MvcJqGrid.Enums.ToolbarPosition.Bottom)
)

好了,大概就是这么个样子。数据库拼接字符串查询确实不太好,我再看看别的方法。

另外bootstrap是个好东西啊,建议大家看看。

使用MVCJqGrid的心得的更多相关文章

  1. 使用MVCJqGrid

    使用MVCJqGrid的心得   最近公司网站进行升级,项目要用.net mvc,mysql和轻量级orm框架dapper.由于美工页面出不来啊,让我先写简单写写后台的列表,同事说用MvcJqGrid ...

  2. 我的MYSQL学习心得(一) 简单语法

    我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  3. NoSql数据库使用半年后在设计上面的一些心得

    NoSql数据库这个概念听闻许久了,也陆续看到很多公司和产品都在使用,优缺点似乎都被分析的清清楚楚.但我心里一直存有一个疑惑,它的出现究竟是为了解决什么问题? 这个疑惑非常大,为此我看了很多分析文章, ...

  4. 我的MYSQL学习心得(二) 数据类型宽度

    我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  5. 我的MYSQL学习心得(三) 查看字段长度

    我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  6. 我的MYSQL学习心得(四) 数据类型

    我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(五) 运 ...

  7. 我的MYSQL学习心得(五) 运算符

    我的MYSQL学习心得(五) 运算符 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...

  8. 我的MYSQL学习心得(六) 函数

    我的MYSQL学习心得(六) 函数 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...

  9. 我的MYSQL学习心得(七) 查询

    我的MYSQL学习心得(七) 查询 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...

随机推荐

  1. HW7.6

    import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...

  2. [AHOI2006]文本编辑器 Splay tree区间操作

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1269 Description 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个 ...

  3. HDU 3488--Tour(KM or 费用流)

    因为每个点只能经过一次 所以考虑拆点 这题有坑,有重边.. KM算法 把一个点拆成入点和出点 入点在X部,出点在Y步. 如果u,v之间有路径,就在X部的u点连接Y部的v点 求完美匹配. 当完美匹配的时 ...

  4. hdu 5505 GT and numbers

    GT and numbers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  5. stm32 cortext-M3 类型对齐问题【worldsing笔记】

    经过细测,Cortex-M3的double类型必须4字节对齐访问,其他诸如float,int,short 可以非对齐访问.否则将会产生硬件异常!即访问double类型地址必须能被4整除,测试代码如下: ...

  6. function和感叹号,运算符号的转化

    1.下面的程序经过运算之后,a为true,这个很好理解,但是函数怎么会运行呢? var a = !function(){ alert('message'); }(); console.log(a); ...

  7. 强烈推荐android studio用的几个插件,androidstudio

    不懂安装studio插件,看参考博文:android stuido插件安装:http://blog.csdn.net/liang5630/article/details/46372447 1.Butt ...

  8. VPN介绍--虚拟网络

      VPN属于远程访问技术,简单地说就是利用公网链路架设私有网络.例如 公司员工出差到外地,他想访问企 原理 业内网的 服务器资源,这种访问就属于远程访问.怎么才能让外地员工访问到内网资源呢?VPN的 ...

  9. 手把手教你Android来去电通话自动录音的方法

    我们在使用Android手机打电话时,有时可能会需要对来去电通话自动录音,本文就详细讲解实现Android来去电通话自动录音的方法,大家按照文中的方法编写程序就可以完成此功能. 来去电自动录音的关键在 ...

  10. pomelo 开发环境搭建

    开发前提条件:  Windows系统,请确保你的Windows系统包括源代码编译工具.Node.js的源代码主要由C++代码和JavaScript代码构成,可是却用gyp工具来做源代码的项目管理,该工 ...