Excel在web项目里的使用变得越来越广泛,特别是和线下耦合度较高的业务,Excel导入导出变得非常频繁,尽管很多人写了诸多的工具方法,但是终究没有解决一个问题:有效的控制字段英文名称和实际表头名称(这里指Excel中文表头名称)的对应关系,在编码开发过程中,大量时间用于解决这些问题,并因此衍生出大量的工作量,以至于硬性的加了许多约定,在开发过程中,工具方法通用性并不高。因此,基于实体Bean的Annotation化是一个比较不错的尝试。

Excel导入到Bean

public class ExcelToBean{

    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private int etimes = 0; /**
* 从文件读取数据,最好是所有的单元格都是文本格式,日期格式要求yyyy-MM-dd HH:mm:ss,布尔类型0:真,1:假
*
* @param edf
* 数据格式化
*
* @param file
* Excel文件,支持xlsx后缀,xls的没写,基本一样
* @return
* @throws Exception
*/
@SuppressWarnings("unchecked")
public <E> List<E> readFromFile(ExcelDataFormatter edf, File file, Class<?> clazz) throws Exception {
Field[] fields = ReflectUtils.getClassFieldsAndSuperClassFields(clazz); Map<String, String> textToKey = new HashMap<String, String>(); Excel _excel = null;
for (Field field : fields) {
_excel = field.getAnnotation(Excel.class);
if (_excel == null || _excel.skip() == true) {
continue;
}
textToKey.put(_excel.name(), field.getName());
} InputStream is = new FileInputStream(file); Workbook wb = new XSSFWorkbook(is); Sheet sheet = wb.getSheetAt(0);
Row title = sheet.getRow(0);
// 标题数组,后面用到,根据索引去标题名称,通过标题名称去字段名称用到 textToKey
String[] titles = new String[title.getPhysicalNumberOfCells()];
for (int i = 0; i < title.getPhysicalNumberOfCells(); i++) {
titles[i] = title.getCell(i).getStringCellValue();
} List<E> list = new ArrayList<E>(); E e = null; int rowIndex = 0;
int columnCount = titles.length;
Cell cell = null;
Row row = null; for (Iterator<Row> it = sheet.rowIterator(); it.hasNext();) { row = it.next();
if (rowIndex++ == 0) {
continue;
} if (row == null) {
break;
} e = (E)clazz.newInstance(); for (int i = 0; i < columnCount; i++) {
cell = row.getCell(i);
if(null==cell)continue;
etimes = 0;
readCellContent(textToKey.get(titles[i]), fields, cell, e, edf);
}
list.add(e);
}
return list;
} public static void main(String[] args) throws Exception {
} /**
* 从单元格读取数据,根据不同的数据类型,使用不同的方式读取<br>
* 有时候经常和我们期待的数据格式不一样,会报异常,<br>
* 我们这里采取强硬的方式<br>
* 使用各种方法,知道尝试到读到数据为止,然后根据Bean的数据类型,进行相应的转换<br>
* 如果尝试完了(总共7次),还是不能得到数据,那么抛个异常出来,没办法了
*
* @param key
* 当前单元格对应的Bean字段
* @param fields
* Bean所有的字段数组
* @param cell
* 单元格对象
* @param obj
* @throws Exception
*/
public void readCellContent(String key, Field[] fields, Cell cell, Object obj, ExcelDataFormatter edf) throws Exception { Object o = null; try {
switch (cell.getCellType()) {
case XSSFCell.CELL_TYPE_BOOLEAN:
o = cell.getBooleanCellValue();
break;
case XSSFCell.CELL_TYPE_NUMERIC:
o = cell.getNumericCellValue();
if (HSSFDateUtil.isCellDateFormatted(cell)) {
o = DateUtil.getJavaDate(cell.getNumericCellValue());
}
break;
case XSSFCell.CELL_TYPE_STRING:
o = cell.getStringCellValue();
break;
case XSSFCell.CELL_TYPE_ERROR:
o = cell.getErrorCellValue();
break;
case XSSFCell.CELL_TYPE_BLANK:
o = null;
break;
case XSSFCell.CELL_TYPE_FORMULA:
o = cell.getCellFormula();
break;
default:
o = null;
break;
} if (o == null)
return; for (Field field : fields) {
field.setAccessible(true);
if (field.getName().equals(key)) {
Boolean bool = true;
Map<String, String> map = null;
if (edf == null) {
bool = false;
} else {
map = edf.get(field.getName());
if (map == null) {
bool = false;
}
} if (field.getType().equals(Date.class)) {
if (o.getClass().equals(Date.class)) {
field.set(obj, o);
} else {
field.set(obj, sdf.parse(o.toString()));
}
} else if (field.getType().equals(String.class)) {
if (o.getClass().equals(String.class)) {
field.set(obj, o);
} else {
field.set(obj, o.toString());
}
} else if (field.getType().equals(Long.class)) {
if (o.getClass().equals(Long.class)) {
field.set(obj, o);
} else {
field.set(obj, Long.parseLong(o.toString()));
}
} else if (field.getType().equals(Integer.class)) {
if (o.getClass().equals(Integer.class)) {
field.set(obj, o);
} else {
// 检查是否需要转换
String ostr = o.toString();
ostr = ostr.split("\\.").length>0?ostr.split("\\.")[0]:ostr;
if (bool) {
field.set(obj, map.get(ostr) != null ? Integer.parseInt(map.get(ostr)) : Integer.parseInt(ostr));
} else {
field.set(obj, Integer.parseInt(ostr));
} }
} else if (field.getType().equals(BigDecimal.class)) {
if (o.getClass().equals(BigDecimal.class)) {
field.set(obj, o);
} else {
field.set(obj, BigDecimal.valueOf(Double.parseDouble(o.toString())));
}
} else if (field.getType().equals(Boolean.class)) {
if (o.getClass().equals(Boolean.class)) {
field.set(obj, o);
} else {
// 检查是否需要转换
if (bool) {
field.set(obj, map.get(o.toString()) != null ? Boolean.parseBoolean(map.get(o.toString())) : Boolean.parseBoolean(o.toString()));
} else {
field.set(obj, Boolean.parseBoolean(o.toString()));
}
}
} else if (field.getType().equals(Float.class)) {
if (o.getClass().equals(Float.class)) {
field.set(obj, o);
} else {
field.set(obj, Float.parseFloat(o.toString()));
}
} else if (field.getType().equals(Double.class)) {
if (o.getClass().equals(Double.class)) {
field.set(obj, o);
} else {
field.set(obj, Double.parseDouble(o.toString()));
} } }
} } catch (Exception ex) {
ex.printStackTrace();
// 如果还是读到的数据格式还是不对,只能放弃了
if (etimes > 7) {
throw ex;
}
etimes++;
if (o == null) {
readCellContent(key, fields, cell, obj, edf);
}
}
} }

Bean导出到Excel

public class BeanToExcel {
/**
* 获得Workbook对象
*
* @param list
* 数据集合
* @return Workbook
* @throws Exception
*/
public static <T> Workbook getWorkBook(List<T> list, ExcelDataFormatter edf) throws Exception {
// 创建工作簿
Workbook wb = new SXSSFWorkbook(); if (list == null || list.size() == 0)
return wb; // 创建一个工作表sheet
Sheet sheet = wb.createSheet();
// 申明行
Row row = sheet.createRow(0);
// 申明单元格
Cell cell = null; CreationHelper createHelper = wb.getCreationHelper(); Field[] fields = ReflectUtils.getClassFieldsAndSuperClassFields(list.get(0).getClass()); XSSFCellStyle titleStyle = (XSSFCellStyle) wb.createCellStyle();
titleStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
// 设置前景色
titleStyle.setFillForegroundColor(new XSSFColor(new java.awt.Color(159, 213, 183)));
titleStyle.setAlignment(CellStyle.ALIGN_CENTER); Font font = wb.createFont();
font.setColor(HSSFColor.BROWN.index);
font.setBoldweight(Font.BOLDWEIGHT_BOLD);
// 设置字体
titleStyle.setFont(font); int columnIndex = 0;
Excel excel = null;
for (Field field : fields) {
field.setAccessible(true);
excel = field.getAnnotation(Excel.class);
if (excel == null || excel.skip() == true) {
continue;
}
// 列宽注意乘256
sheet.setColumnWidth(columnIndex, excel.width() * 256);
// 写入标题
cell = row.createCell(columnIndex);
cell.setCellStyle(titleStyle);
cell.setCellValue(excel.name()); columnIndex++;
} int rowIndex = 1; CellStyle cs = wb.createCellStyle(); for (T t : list) {
row = sheet.createRow(rowIndex);
columnIndex = 0;
Object o = null;
for (Field field : fields) { field.setAccessible(true); // 忽略标记skip的字段
excel = field.getAnnotation(Excel.class);
if (excel == null || excel.skip() == true) {
continue;
}
// 数据
cell = row.createCell(columnIndex); o = field.get(t);
// 如果数据为空,跳过
if (o == null)
continue; // 处理日期类型
if (o instanceof Date) {
// excel.dateFormat()获取注解的日期格式,默认yyyy-MM-dd HH:mm:ss
cs.setDataFormat(createHelper.createDataFormat().getFormat(excel.dateFormat()));
cell.setCellStyle(cs);
cell.setCellValue((Date) field.get(t));
} else if (o instanceof Double || o instanceof Float) {// 浮点数
cell.setCellValue(field.get(t).toString());
if (excel.precision() != -1) {
cell.setCellValue(new BigDecimal(field.get(t).toString()).setScale(excel.precision(), excel.round() == true ? BigDecimal.ROUND_HALF_UP : BigDecimal.ROUND_FLOOR).toString());
}
} else if (o instanceof BigDecimal) {// BigDecimal
cell.setCellValue((field.get(t).toString()));
if (excel.precision() != -1) {
cell.setCellValue(new BigDecimal(field.get(t).toString()).setScale(excel.precision(), excel.round() == true ? BigDecimal.ROUND_HALF_UP : BigDecimal.ROUND_FLOOR).toString());
}
} else if (o instanceof Boolean) {// 布尔类型
Boolean bool = (Boolean) field.get(t);
if (edf == null) {
cell.setCellValue(bool);
} else {
Map<String, String> map = edf.get(field.getName());
if (map == null) {
cell.setCellValue(bool);
} else {
cell.setCellValue(map.get(bool.toString().toLowerCase()));
}
} } else if (o instanceof Integer) {// 整型 Integer intValue = (Integer) field.get(t); if (edf == null) {
cell.setCellValue(intValue);
} else {
Map<String, String> map = edf.get(field.getName());
if (map == null) {
cell.setCellValue(intValue);
} else {
cell.setCellValue(map.get(intValue.toString()));
}
}
} else {
cell.setCellValue(field.get(t).toString());
} columnIndex++;
} rowIndex++;
} return wb;
} /**
* 将数据写入到EXCEL文档
*
* @param list
* 数据集合
* @param edf
* 数据格式化,比如有些数字代表的状态,像是0:女,1:男,或者0:正常,1:锁定,变成可读的文字
* 该字段仅仅针对Boolean,Integer两种类型作处理
* @param filePath
* 文件路径
* @throws Exception
*/
public static <T> void writeToFile(List<T> list, ExcelDataFormatter edf, String filePath) throws Exception {
// 创建并获取工作簿对象
Workbook wb = getWorkBook(list, edf);
// 写入到文件
FileOutputStream out = new FileOutputStream(filePath);
wb.write(out);
out.close();
}

数据格式化工具类

public class ExcelDataFormatter {

    private Map<String,Map<String,String>> formatter=new HashMap<String, Map<String,String>>();

    public void set(String key,Map<String,String> map){
formatter.put(key, map);
} public Map<String,String> get(String key){
return formatter.get(key);
} }

反射工具类

public class ReflectUtils {

    /**
* 获取成员变量的修饰符
*
* @param clazz
* @param field
* @return
* @throws Exception
*/
public static <T> int getFieldModifier(Class<T> clazz, String field) throws Exception {
// getDeclaredFields可以获取所有修饰符的成员变量,包括private,protected等getFields则不可以
Field[] fields = clazz.getDeclaredFields(); for (int i = 0; i < fields.length; i++) {
if (fields[i].getName().equals(field)) {
return fields[i].getModifiers();
}
}
throw new Exception(clazz + " has no field \"" + field + "\"");
} /**
* 获取成员方法的修饰符
*
* @param clazz
* @param method
* @return
* @throws Exception
*/
public static <T> int getMethodModifier(Class<T> clazz, String method) throws Exception { // getDeclaredMethods可以获取所有修饰符的成员方法,包括private,protected等getMethods则不可以
Method[] m = clazz.getDeclaredMethods(); for (int i = 0; i < m.length; i++) {
if (m[i].getName().equals(m)) {
return m[i].getModifiers();
}
}
throw new Exception(clazz + " has no method \"" + m + "\"");
} /**
* [对象]根据成员变量名称获取其值
*
* @param clazzInstance
* @param field
* @return
* @throws NoSuchFieldException
* @throws SecurityException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
public static <T> Object getFieldValue(Object clazzInstance, Object field) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { Field[] fields = clazzInstance.getClass().getDeclaredFields(); for (int i = 0; i < fields.length; i++) {
if (fields[i].getName().equals(field)) {
// 对于私有变量的访问权限,在这里设置,这样即可访问Private修饰的变量
fields[i].setAccessible(true);
return fields[i].get(clazzInstance);
}
} return null;
} /**
* [类]根据成员变量名称获取其值(默认值)
*
* @param clazz
* @param field
* @return
* @throws NoSuchFieldException
* @throws SecurityException
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public static <T> Object getFieldValue(Class<T> clazz, String field) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException { Field[] fields = clazz.getDeclaredFields(); for (int i = 0; i < fields.length; i++) {
if (fields[i].getName().equals(field)) {
// 对于私有变量的访问权限,在这里设置,这样即可访问Private修饰的变量
fields[i].setAccessible(true);
return fields[i].get(clazz.newInstance());
}
} return null;
} /**
* 获取所有的成员变量(通过GET,SET方法获取)
*
* @param clazz
* @return
*/
public static <T> String[] getFields(Class<T> clazz) { Field[] fields = clazz.getDeclaredFields(); String[] fieldsArray = new String[fields.length]; for (int i = 0; i < fields.length; i++) {
fieldsArray[i] = fields[i].getName();
} return fieldsArray;
} /**
* 获取所有的成员变量,包括父类
*
* @param clazz
* @param superClass
* 是否包括父类
* @return
* @throws Exception
*/
public static <T> Field[] getFields(Class<T> clazz, boolean superClass) throws Exception { Field[] fields = clazz.getDeclaredFields();
Field[] superFields = null;
if (superClass) {
Class superClazz = clazz.getSuperclass();
if (superClazz != null) {
superFields = superClazz.getDeclaredFields();
}
} Field[] allFields = null; if (superFields == null || superFields.length == 0) {
allFields = fields;
} else {
allFields = new Field[fields.length + superFields.length];
for (int i = 0; i < fields.length; i++) {
allFields[i] = fields[i];
}
for (int i = 0; i < superFields.length; i++) {
allFields[fields.length + i] = superFields[i];
}
} return allFields;
} /**
* 获取所有的成员变量,包括父类
*
* @param clazz
* @return
* @throws Exception
*/
public static <T> Field[] getClassFieldsAndSuperClassFields(Class<T> clazz) throws Exception { Field[] fields = clazz.getDeclaredFields(); if (clazz.getSuperclass() == null) {
throw new Exception(clazz.getName() + "没有父类");
} Field[] superFields = clazz.getSuperclass().getDeclaredFields(); Field[] allFields = new Field[fields.length + superFields.length]; for (int i = 0; i < fields.length; i++) {
allFields[i] = fields[i];
}
for (int i = 0; i < superFields.length; i++) {
allFields[fields.length + i] = superFields[i];
} return allFields;
} /**
* 指定类,调用指定的无参方法
*
* @param clazz
* @param method
* @throws NoSuchMethodException
* @throws SecurityException
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
* @throws InstantiationException
*/
public static <T> Object invoke(Class<T> clazz, String method) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
Object instance = clazz.newInstance();
Method m = clazz.getMethod(method, new Class[] {});
return m.invoke(instance, new Object[] {});
} /**
* 通过对象,访问其方法
*
* @param clazzInstance
* @param method
* @return
* @throws NoSuchMethodException
* @throws SecurityException
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
* @throws InstantiationException
*/
public static <T> Object invoke(Object clazzInstance, String method) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
Method m = clazzInstance.getClass().getMethod(method, new Class[] {});
return m.invoke(clazzInstance, new Object[] {});
} /**
* 指定类,调用指定的方法
*
* @param clazz
* @param method
* @param paramClasses
* @param params
* @return Object
* @throws InstantiationException
* @throws IllegalAccessException
* @throws NoSuchMethodException
* @throws SecurityException
* @throws IllegalArgumentException
* @throws InvocationTargetException
*/
public static <T> Object invoke(Class<T> clazz, String method, Class<T>[] paramClasses, Object[] params) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
Object instance = clazz.newInstance();
Method _m = clazz.getMethod(method, paramClasses);
return _m.invoke(instance, params);
} /**
* 通过类的实例,调用指定的方法
*
* @param clazzInstance
* @param method
* @param paramClasses
* @param params
* @return
* @throws InstantiationException
* @throws IllegalAccessException
* @throws NoSuchMethodException
* @throws SecurityException
* @throws IllegalArgumentException
* @throws InvocationTargetException
*/
public static <T> Object invoke(Object clazzInstance, String method, Class<T>[] paramClasses, Object[] params) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
Method _m = clazzInstance.getClass().getMethod(method, paramClasses);
return _m.invoke(clazzInstance, params);
} // @SuppressWarnings("unchecked")
// public static void main(String[] args) throws Exception {
// // getFields(User.class);
// User u = new User();
// invoke(u, "setName", new Class[] { String.class }, new Object[] { "xx发大水法大水法x" });
// System.out.println(getFieldValue(u, "name"));
// }

Annotation定义类

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.TYPE})
public @interface Excel { //列名
String name() default ""; //宽度
int width() default 20; //忽略该字段
boolean skip() default false; //日期格式化
String dateFormat() default "yyyy-MM-dd HH:mm:ss"; //浮点数的精度
int precision() default -1; //四舍五入
boolean round() default true; }

使用方法

以Excel导入做示例:

如下图所示的Excel数据

在写代码前,按照Annotation的定义对实体Bean进行添加相关标签,例如下图:

示例代码:

public class ElearnSysExcelService extends CustomService{

    /**
* 导入Excel文件数据到数据库
* @param file
* @author zhanglongping
* @date 2016-11-10 下午2:10:24
*/
public static void importExcelToDB(File file){
ExcelToBean e = new ExcelToBean();
ExcelDataFormatter edf = new ExcelDataFormatter();
Map<String,String> map = new HashMap<String,String>();
map.put( "准备就绪","111");
map.put( "开始","222");
map.put( "工作","333");
map.put( "结束","444");
edf.set("state", map); try {
List<ElearnSysUser> list = e.readFromFile(edf, file, ElearnSysUser.class);
for(ElearnSysUser esu:list){
System.out.println(esu.getUserName()+"~~~"+esu.getState()+"~~~"+esu.getRealName());
}
} catch (Exception e1) {
e1.printStackTrace();
}
} public static void main(String[] args) {
ElearnSysExcelService e = new ElearnSysExcelService();
File file = new File("f://test/excel_sys_user.xlsx");
e.importExcelToDB(file);
}
}

运行结果:

可以看到,Excel中的状态数据已被转换为111,444等数据

参考文献:http://www.xdemo.org

Excel基于POI导入导出的Annotation化之路(一)的更多相关文章

  1. Java利用POI导入导出Excel中的数据

         首先谈一下今天发生的一件开心的事,本着一颗android的心我被分配到了PB组,身在曹营心在汉啊!好吧,今天要记录和分享的是Java利用POI导入导出Excel中的数据.下面POI包的下载地 ...

  2. 循序渐进开发WinForm项目(5)--Excel数据的导入导出操作

    随笔背景:在很多时候,很多入门不久的朋友都会问我:我是从其他语言转到C#开发的,有没有一些基础性的资料给我们学习学习呢,你的框架感觉一下太大了,希望有个循序渐进的教程或者视频来学习就好了. 其实也许我 ...

  3. poi 导入导出的api说明(大全)

    原文链接:http://www.cnblogs.com/qingruihappy/p/8443101.html poi 导入导出的api说明(大全) 一. POI简介 ApachePOI是Apache ...

  4. Laravel 5使用Laravel Excel实现Excel/CSV文件导入导出的功能详解

    1.简介 本文主要给大家介绍了关于Laravel 5用Laravel Excel实现Excel/CSV文件导入导出的相关内容,下面话不多说了,来一起看看详细的介绍吧. Laravel Excel 在 ...

  5. 告别硬编码,让你的POI导入导出拥抱变化

    GitHub地址 | 博客 | 中文 | English | 原文链接 为什么使用AutoExcel? Excel导入导出在软件开发中非常常见,只要你接触过开发,就一定会遇到.相信很多人会跟我一样选择 ...

  6. SQL SERVER 与ACCESS、EXCEL的数据导入导出转换

    * 说明:复制表(只复制结构,源表名:a 新表名:b)      select * into b from a where 1<>1 * 说明:拷贝表(拷贝数据,源表名:a 目标表名:b) ...

  7. SSM excel文件的导入导出

    对于excel文件的导入导出,后台接收读取和建表封存都是固定死的,所以对于excel导入时,excel文件内容必须匹配后台相关对象,不然报错. excel文件导出,用<a><a/&g ...

  8. SQL SERVER 和ACCESS、EXCEL的数据导入导出

    SQL SERVER 与ACCESS.EXCEL之间的数据转换SQL SERVER 和ACCESS的数据导入导出[日期:2007-05-06]     来源:Linux公社  作者:Linux 熟 悉 ...

  9. VB中Excel 2010的导入导出操作

    VB中Excel 2010的导入导出操作 编写人:左丘文 2015-4-11 近来这已是第二篇在讨论VB的相关问题,今天在这里,我想与大家一起分享一下在VB中如何从Excel中导入数据和导出数据到Ex ...

随机推荐

  1. 【嵌入式开发】写入开发板Linux系统-模型S3C6410

    笔者 : 万境绝尘 转载请著名出处 最终拿到板子了, 嵌入式开发正式开启. 板子型号 : 三星 S3C6410 基于ARM11, 指令集基于arm6指令集; 为毛不是 Cortext A9的板子; 烧 ...

  2. xaml的margin和css的margin对比

    css margin xaml margin 例子 1 css margin:10px 5px 15px 20px;上右下左 上外边距是 10px 右外边距是 5px 下外边距是 15px 左外边距是 ...

  3. spring整合redis客户端及缓存接口设计(转)

    一.写在前面 缓存作为系统性能优化的一大杀手锏,几乎在每个系统或多或少的用到缓存.有的使用本地内存作为缓存,有的使用本地硬盘作为缓存,有的使用缓存服务器.但是无论使用哪种缓存,接口中的方法都是差不多. ...

  4. hdoj 2121 Ice_cream’s world II 【没有最低树的根节点】

    称号:pid=2121" target="_blank">hdoj 2121 Ice_cream's world II 题意:题目是一道躶题,给n个点,m条边的有向 ...

  5. SQL SERVER 内存分配及常见内存问题(1)——简介

    原文:SQL SERVER 内存分配及常见内存问题(1)--简介 一.问题: 1.SQL Server 所占用内存数量从启动以后就不断地增加: 首先,作为成熟的产品,内存溢出的机会微乎其微.对此要了解 ...

  6. row_number()、rank()、dense_rank()、ntile()

    原文:row_number().rank().dense_rank().ntile() SQL2005中row_number()等函数的用法 2005比2000新增了几个函数,分别是row_numbe ...

  7. MySQL Study之--Mysql无法启动“mysql.host”

    MySQL Study之--Mysql无法启动"mysql.host" 系统环境: 操作系统:RedHat EL55 DB Soft:  Mysql 5.6.4-m7 通过源代码包 ...

  8. 连载:面向对象的葵花宝典:思考、技巧与实践(39) - 设计原则 vs 设计模式

    它的设计原则,和设计模式,是否该用它? ============================================================================= 在& ...

  9. SQLServer 2012异常问题(一)--故障转移群集+镜像环境导致作业执行失败

    原文:SQLServer 2012异常问题(一)--故障转移群集+镜像环境导致作业执行失败 先感谢一下我的同事们最先发现此问题,鸣谢:向飞.志刚.海云 最近在生产环境发现一个诡异的问题: 环境:WIN ...

  10. Linux内核分析(二)----内核模块简介|简单内核模块实现

    原文:Linux内核分析(二)----内核模块简介|简单内核模块实现 Linux内核分析(二) 昨天我们开始了内核的分析,网上有很多人是用用源码直接分析,这样造成的问题是,大家觉得很枯燥很难理解,从某 ...