我的目的是实现下Hibernate中增删改查、缓存的核心功能。虽然基本功能实现了,但可能还有好多Bug,欢迎点评拍砖,没准能在一片谩骂声中取得意想不到的进步,:)

// DatabaseAccess.java

 package com.dsp.core;

 import java.io.IOException;
import java.util.*; /**
* 数据库访问操作类
* @author dsp
*/
public class DatabaseAccess {
// 数据库辅助帮助类实例
private DatabaseHelper databaseHelper = new DatabaseHelper();
// DatabaseAccess类的泛型帮助类实例
private GenericityHelper genericityHelper = new GenericityHelper(); /**
* 向数据库添加object
* @param object 待添加的对象
* @return 若成功向数据库添加object,则返回数据库中object对应记录的id号,否则,返回-1
*/
@SuppressWarnings("unchecked")
public synchronized int add(Object object) {
// object为空
if(null == object)
return -1; List<String> columns = genericityHelper.getAllFieldNames(object);
Map<String, Object> columnToValues = genericityHelper.getFieldValues(columns, object); /*
* 拼接带占位符的SQL语句
*/
String className = genericityHelper.getClassName(object).toLowerCase();
String sql_0 = "insert into " + className + "(";
for(int index = 0; index < columns.size(); ++index) {
sql_0 += columns.get(index) + ",";
}
String sql_1 = sql_0.substring(0, sql_0.length() - 1) + ") values(";
// 设置占位符
for(int index = 0; index < columns.size(); ++index) {
sql_1 += "?,";
}
String sql_2 = sql_1.substring(0, sql_1.length() - 1);
sql_2 += ");"; /*
* 设置相应参数
*/
List<Object> params = new LinkedList<Object>();
for(int index = 0; index < columns.size(); ++index) {
String fieldName = columns.get(index);
if("id".equals(fieldName))
params.add(index, 0);
else
params.add(index, columnToValues.get(fieldName));
} // 执行插入
int result = databaseHelper.singleTableUpdate(sql_2, params, object.getClass()); // 若插入成功
if(result > 0) {
String tableName = genericityHelper.getClassName(object);
List<Object> targetList = (List<Object>) databaseHelper.getCachedData(tableName, object.getClass());
Object lastObject = targetList.get(targetList.size() - 1);
Object value = genericityHelper.getSpecifiedFieldValue("id", lastObject);
int id = Integer.parseInt(value.toString());
return id;
} else {
return -1;
}
} /**
* 从数据库中删除object
* @param object 待删除的对象
* @return 成功删除,返回true;否则返回false
*/
public synchronized boolean delete(Object object) {
// 对象为空
if(null == object)
return false; /*
* 拼接带占位符的SQL语句
*/
String className = genericityHelper.getClassName(object);
List<String> columns = genericityHelper.getAllFieldNames(object);
Map<String, Object> columnToValues = genericityHelper.getFieldValues(columns, object);
String sql = "delete from " + className + " where id = " + columnToValues.get("id") + ";"; // 执行删除操作
int result = databaseHelper.singleTableUpdate(sql, null, object.getClass());
if(result > 0)
return true;
else
return false;
} /**
* 更新数据库中德object对象
* @param object 要更新的对象
* @return 成功返回true,否则返回false
*/
public synchronized boolean update(Object object) {
// 对象为空
if(null == object)
return false; String className = genericityHelper.getClassName(object);
String sql_0 = "update " + className + " set "; List<Object> params = new ArrayList<Object>();
List<String> columns = genericityHelper.getAllFieldNames(object);
Map<String, Object> columnToValues = genericityHelper.getFieldValues(columns, object); /*
* 拼接带占位符的SQL语句
*/
for(int index = 0; index < columns.size(); ++index) {
String field = columns.get(index).toString();
if(field.equals("id"))
continue;
sql_0 += field + "=?,";
params.add(columnToValues.get(field));
} String sql_1 = sql_0.substring(0, sql_0.length() - 1) + " where id=?;";
params.add(columnToValues.get("id")); // 执行更新操作
int result = databaseHelper.singleTableUpdate(sql_1, params, object.getClass());
if(result <= 0)
return false;
else
return true;
} /**
* 从数据库中查询出所有的clazz记录,得到clazz记录的一份副本(深拷贝),使用时要求对应的Java Bean实现Serializable接口
* @param clazz 数据库表名映射的Java Bean反射实例
* @return 查询到的记录的链表
* @throws IOException
* @throws ClassNotFoundException
*/
@SuppressWarnings("unchecked")
public synchronized List<?> getAll(Class<?> clazz) {
List<?> resultsList = null;
try {
String className = genericityHelper.getClassName(clazz);
List<Object> tempResults = (List<Object>) databaseHelper.getCachedData(className, clazz);
resultsList = genericityHelper.deepClone(tempResults);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return resultsList;
} }

// DatabaseHelper.java

 package com.dsp.core;

 import java.lang.reflect.Method;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import com.dsp.util.Log; /**
* 数据库JDBC操作辅助帮助类
* @author dsp
*/
public class DatabaseHelper {
// 已缓存了的数据链表
private static Map<String, List<Object>> cachedData = new HashMap<String, List<Object>>(); // JDBC连接
private Connection connection;
// 预编译对象
private PreparedStatement pstmt; /**
* 静态块,用来加载驱动
*/
static{
try {
Class.forName(LoadDBConfigFile.getInstance().getProperty("driverClassName"));
} catch (ClassNotFoundException e) {
e.printStackTrace();
Log.log.error(e.toString());
}
} /**
* 获取连接
*/
private Connection getConnection() {
try {
// 手动创建JDBC连接
connection = DriverManager.getConnection(LoadDBConfigFile.getInstance().getProperty("url"), LoadDBConfigFile.getInstance().getProperty("username"), LoadDBConfigFile.getInstance().getProperty("password"));
if(connection == null) {
System.out.println("Error!!!Failed to connect database!");
System.exit(-1);
}
} catch (Exception e) {
Log.log.error(e.toString());
}
return connection;
} /**
* 关闭所有与JDBC相关的连接
* 顺序:先进后出
*/
private void closeAllConnections(Connection connection, PreparedStatement pstmt, ResultSet resultSet) {
if(pstmt != null) {
try {
pstmt.close();
} catch (SQLException e) {
Log.log.error(e.toString());
}
}
if(connection != null) {
try {
connection.close();
} catch (SQLException e) {
Log.log.error(e.toString());
}
}
} /**
* 填充PreparedStatement对象的sql语句中的占位符
* @param pstmt PreparedStatement对象
* @param params 填充PreparedStatement对象中sql语句占位符的参数链表
* #######################################################################
* 参数化查询(Parameterized Query 或 Parameterized Statement)是指在设计与
* 数据库链接并访问数据时,在需要填入数值或数据的地方,使用参数 (Parameter) 来给值,
* 这个方法目前已被视为最有效可预防SQL注入攻击(SQL Injection) 的攻击手法的防御方式。
*/
private void replacePlaceholder(PreparedStatement pstmt, List<Object> params) {
if((pstmt != null) && (params != null) && (params.size() > 0)) {
for(int index = 0; index < params.size(); ++index) {
Object obj = params.get(index);
try {
if(obj == null) {
// 若为null。//待优化处,减少拼接的SQL语句长度
pstmt.setNull(index + 1, Types.INTEGER);
} else if("java.util.Date".equals(obj.getClass().getName())) {
pstmt.setDate(index + 1, new java.sql.Date(((java.util.Date) params.get(index)).getTime()));
} else if("java.lang.Double".equals(obj.getClass().getName())) {
pstmt.setDouble(index + 1, (Double) params.get(index));
} else if("java.lang.Integer".equals(obj.getClass().getName())) {
pstmt.setInt(index + 1, (Integer) params.get(index));
} else if("java.lang.Boolean".equals(obj.getClass().getName())) {
pstmt.setBoolean(index + 1, (Boolean) params.get(index));
} else if("javax.sql.rowset.serial.SerialBlob".equals(obj.getClass().getName())) {
pstmt.setBlob(index + 1, (Blob) params.get(index));
} else {
pstmt.setString(index+1, (String)params.get(index));
}
} catch (SQLException e) {
Log.log.error(e.toString());
}
}
}
} /**
* 打印输出SQL语句。
* 若成功,则是刚执行过的SQL语句;
* 失败则是致使数据库系统抛出异常的非法语句。
* @param pstmt 预编译SQL语句对象
*/
private void printExecutedSQL(PreparedStatement pstmt) {
String executedSQL = pstmt.toString();
System.out.println("====>" + executedSQL);
} /**
* 该表的数据是否已缓存
* @param tableName 表明
* @return 已缓存:true 否则返回 false
*/
private boolean isCached(String tableName) {
List<Object> tempList = cachedData.get(tableName);
if(tempList == null) {
return false;
}
return true;
} /**
* 根据键名获取对应已缓存的数据
* @param classNameOrTableName 取数据用的键名
* @return 缓存的数据链表
*/
public List<?> getCachedData(String classNameOrTableName, Class<?> clazz) {
if(isCached(classNameOrTableName)) {
return cachedData.get(classNameOrTableName);
} else {
// 若数据不在缓存中,则向数据库发送查询请求
String sql = "select * from " + classNameOrTableName + ";";
return this.singleTableQuery(sql, null, clazz);
}
} /**
* 对单表进行更新操作
* @param sql 带占位符的SQL语句
* @param params 用户填充SQL语句中的占位符的参数
* @return 执行结果:>0 成功 <=0 失败
*/
public synchronized int singleTableUpdate(String sql, List<Object> params, Class<?> clazz) {
connection = getConnection();
int result = 0;
try {
// 预编译对象
pstmt = connection.prepareStatement(sql);
replacePlaceholder(pstmt, params);
result = pstmt.executeUpdate();
// 放在此处是出于打印的语句与数据库实际操作的顺序一致性
printExecutedSQL(pstmt); // 更新缓存
String className = new GenericityHelper().getClassName(clazz);
String querySQL = "select * from " + className + ";";
this.singleTableQuery(querySQL, null, clazz);
} catch (SQLException e) {
try {
// 出错则打印SQL语句并回滚
printExecutedSQL(pstmt);
connection.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
// 记录异常
e.printStackTrace();
Log.log.error(e.toString());
} finally {
closeAllConnections(connection, pstmt, null);
}
return result;
} /**
*
* @param sql 查询语句语句,可以含有占位符
* @param params 填充占位符的参数集
* @param clazz 泛型类型所对应的反射对象
* @param <T> 泛型:即你要得到的集合中存的对象的类型
* @return 存储查询到的所有对象链表
*/
@SuppressWarnings({ "unchecked" })
private synchronized <T> List<Object> singleTableQuery(String sql, List<Object> params, Class<T> clazz) {
// 若clazz为空
if(null == clazz) {
return null;
} /*
* 最新数据还未缓存,所以执行查询,检出数据库中的数据
*/
List<T> resultList = new ArrayList<T>();
connection = getConnection();
ResultSet resultSet = null; try {
// 预编译SQL语句对象
pstmt = connection.prepareStatement(sql);
replacePlaceholder(pstmt, params);
resultSet = pstmt.executeQuery(); ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
String[] columnNames = new String[resultSetMetaData.getColumnCount()]; for(int index = 0; index < columnNames.length; ++index) {
columnNames[index] = resultSetMetaData.getColumnName(index + 1);
} while(resultSet.next()) {
T temp = (T) clazz.newInstance();
for(int index = 0; index < columnNames.length; ++index) {
String targetMethdName = "set" + columnNames[index];
Method[] methods = clazz.getMethods();
if((methods != null) && (methods.length > 0)) {
for(Method method : methods) {
String tempMethodName = method.getName();
if(targetMethdName.equalsIgnoreCase(tempMethodName)) {
Object tempObject = resultSet.getObject(columnNames[index]);
if(tempObject != null) {
String columnTypeName = tempObject.getClass().getName();
if("java.lang.Integer".equals(columnTypeName)) {
method.invoke(temp, resultSet.getInt(columnNames[index]));
} else if("java.sql.Date".equals(columnTypeName)) {
method.invoke(temp, resultSet.getDate(columnNames[index]));
} else if("java.lang.Double".equals(columnTypeName)) {
method.invoke(temp, resultSet.getDouble(columnNames[index]));
} else if("java.lang.Boolean".equals(columnTypeName)) {
method.invoke(temp, resultSet.getBoolean(columnNames[index]));
} else {
method.invoke(temp, resultSet.getString(columnNames[index]));
}
}
break;
}
}
}
}
resultList.add(temp);
}
} catch (Exception e) {
e.printStackTrace();
Log.log.equals(e.toString());
} finally {
printExecutedSQL(pstmt);
closeAllConnections(connection, pstmt, resultSet);
} // 缓存最新数据
String tableName = new GenericityHelper().getClassName(clazz);
cachedData.remove(tableName);
cachedData.put(tableName, (List<Object>) resultList); return (List<Object>) resultList;
} }

// GenericityHelper.java

 package com.dsp.core;

 import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import com.dsp.util.Log; /**
* DatabaseAccess类的辅助帮助类
* 声明:
* 本来这个类的所有方法完全可安置到DatabaseAccess类中,从数据耦合
* 这个层面上来讲,DatabaseAccess类有太多的数据处理需要此类中的方法;
* 但考虑到代码都放到一个类中就显得代码有点冗长了,可以适时调整代码位置。
* @author dsp
*/
public class GenericityHelper {
/**
* 获取对象object的简短类名
* @param object 待操作的对象
* @return object对象所对应的类名
*/
public String getClassName(Object object) {
Class<?> clazz = getReflectClass(object);
String classFullName = getClassFullName(clazz);
return classFullName.substring(classFullName.lastIndexOf(".") + 1).toLowerCase();
} /**
* 重载方法
* 获取对象object的简短类名
* @param clazz 反射类实例
* @return 反射类实例所对应的类名
*/
public String getClassName(Class<?> clazz) {
String classFullName = getClassFullName(clazz);
return classFullName.substring(classFullName.lastIndexOf(".") + 1).toLowerCase();
} /**
* 获取对象所有的的字段名
* @param object 操作的对象
* @return object所有的字段名
*/
public List<String> getAllFieldNames(Object object) {
Class<?> clazz = getReflectClass(object);
Field[] fields = clazz.getDeclaredFields();
List<String> columns = new ArrayList<String>();
for(int index = 0; index < fields.length; ++index) {
columns.add(index, fields[index].getName().toString());
}
return columns;
} /**
* 获取所有字段对应的值:键值对
* @param columns 所有的字段名
* @param object 值来源对象
* @return object所有的字段对应的值
*/
public Map<String, Object> getFieldValues(List<String> columns, Object object) {
Map<String, Object> columnToValues = new HashMap<String, Object>();
for(int index = 0; index < columns.size(); ++index) {
String fieldName = columns.get(index).toString();
columnToValues.put(fieldName, getSpecifiedFieldValue(fieldName, object));
}
return columnToValues;
} /**
* 根据类字段名获取该字段对应的值
* @param fieldName 字段名
* @param object 数据源对象
* @return object中fieldName字段对应的值
*/
public Object getSpecifiedFieldValue(String fieldName, Object object) {
List<String> methodNames = generateMethodNames(fieldName);
Method targetMethod = getExistedMethod(methodNames, getReflectClass(object));
Object value = getValueBySpecifiedMethod(targetMethod, object);
return dataCastType(value);
} /**
* 获取对象object的反射类实例
* @param object 操作对象
* @return object对象的反射类实例
*/
private Class<? extends Object> getReflectClass(Object object) {
return object.getClass();
} /**
* 获取反射类实例的类全名
* @param clazz 反射类实例
* @return clazz的类全名
*/
private String getClassFullName(Class<?> clazz) {
return clazz.getName();
} /**
* 获取object对象的指定函数返回的值
* @param targetMethod 指定的函数
* @param object 操作的对象
* @return object对象的targetMethod函数返回的值
*/
private Object getValueBySpecifiedMethod(Method targetMethod, Object object) {
Object value = null;
try {
value = targetMethod.invoke(object, new Object[] {});
} catch (IllegalAccessException e) {
e.printStackTrace();
Log.log.error(e.toString());
} catch (InvocationTargetException e) {
e.printStackTrace();
Log.log.error(e.toString());
}
return value;
} /**
* 数据转换
* @param value 待转换的值
* @return 转换后的值
*/
private Object dataCastType(Object value) {
if(value instanceof Timestamp)
value = Timestamp.valueOf(value.toString());
return value;
} /**
* 判断methodName是否是对象中存在的函数名
* @param methodName 待校验的可能的函数名
* @param clazz 反射类实例
* @return 若methodName是clazz中的函数名,返回true,否则返回false
*/
private boolean isExistedMethodName(String methodName, Class<?> clazz) {
Method[] methods = clazz.getMethods();
for(Method method : methods) {
if(method.getName().equals(methodName))
return true;
}
return false;
} /**
* 根据可能的函数名字检索clazz对象存在的函数
* @param methodNames 函数名字链表
* @param clazz 反射类实例
* @return 在clazz对象中根据函数名字检索到的函数
*/
private Method getExistedMethod(List<String> methodNames, Class<?> clazz) {
for(String methodName : methodNames) {
if(isExistedMethodName(methodName, clazz)) {
try {
Method targetMethod = clazz.getMethod(methodName, new Class[] {});
if(targetMethod != null) {
return targetMethod;
}
} catch (NoSuchMethodException | SecurityException e) {
e.printStackTrace();
Log.log.error(e.toString());
}
}
}
return null;
} /**
* 根据字段名生成可能的目标函数名
* @param fieldName 字段名
* @return 根据fieldName生成的所有可能的目标函数名,将其存放在链表中
*/
private List<String> generateMethodNames(String fieldName) {
List<String> methodNames = new ArrayList<String>();
String firstLetter = fieldName.substring(0, 1).toUpperCase();
String postfix = firstLetter + fieldName.substring(1); /*
* IDE自动生成的getter函数前缀不一定都是"get"
*/
// 方法是”getXyz()“
String methodPrefixGet = "get" + postfix;
methodNames.add(methodPrefixGet);
// 方法名是“isXyz()”
String methodPrefixIs = "is" + postfix;
methodNames.add(methodPrefixIs); return methodNames;
} /**
* 深拷贝List<Object>,要求Object已实现Serializable接口
* @param sourceList 源List
* @return 源List的一份副本
* @throws IOException
* @throws ClassNotFoundException
*/
@SuppressWarnings("unchecked")
public List<Object> deepClone(List<Object> sourceList) throws IOException, ClassNotFoundException {
ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutStream = new ObjectOutputStream(byteOutStream);
objectOutStream.writeObject(sourceList); ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteOutStream.toByteArray());
ObjectInputStream objectInputStream =new ObjectInputStream(byteInputStream);
List<Object> destList = (List<Object>) objectInputStream.readObject();
return destList;
} }

// LoadDBConfigFile.java

 package com.dsp.core;

 import java.io.IOException;
import java.io.InputStream;
import java.util.Properties; import com.dsp.util.Log; /**
* 加载数据库配置文件
* @author dsp
*/
public class LoadDBConfigFile extends Properties {
private static final long serialVersionUID = 1907772550710288554L; private static LoadDBConfigFile instance = null; /**
* 对外提供一个工厂方法
* @return LoadDBConfigFile的全局唯一实例
*/
public synchronized static LoadDBConfigFile getInstance() {
if(instance != null) {
return instance;
} else {
instance = new LoadDBConfigFile();
return instance;
}
} /**
* 单例模式的核心:构造方法私有化
*/
private LoadDBConfigFile() {
// db.properties文件保存有基本的配置信息
// 通过类的反射实例找到并加载classpath路径下的指定资源文件,并将其生成一个输入流;
InputStream inputStream = this.getClass().getResourceAsStream("/db.properties");
try {
// 将输入流中的信息加载到类的当前对象中
this.load(inputStream);
} catch (IOException e) {
Log.log.error(e.toString());
} finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
Log.log.error(e.toString());
}
}
} }

// Log.java

 package com.dsp.util;

 import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator; public class Log { public static Logger log; static {
PropertyConfigurator.configure("/log4j.properties");
log = Logger.getLogger(Log.class);
log.debug("debug");
log.error("error");
} }

// db.properties

  1. driverClassName=com.mysql.jdbc.Driver
  2. url=jdbc\:mysql\://127.0.0.1\:3306/retina
  3. username=root
  4. password=123456

// log4j.properties

  1. log4j.appender.stdout=org.apache.log4j.ConsoleAppender
  2. log4j.appender.stdout.Target=System.out
  3. log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
  4. log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %m%n
  5. log4j.appender.file=org.apache.log4j.FileAppender
  6. log4j.appender.file.File=retina.log
  7. log4j.appender.file.layout=org.apache.log4j.PatternLayout
  8. log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %l %m%n
  9. log4j.rootLogger=WARN,stdout,file

// DatabaseAccessTester.java    测试代码

 import com.dsp.bean.MovieType;
import com.dsp.core.DatabaseAccess;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.List; /**
* Created by dsp on 14-3-9.
*/
public class DataBaseAccessTester {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
// MovieType movieType = new MovieType();
// movieType.setId(6);
// movieType.setName("101010");
// new DatabaseAccess().add(movieType);
//
DatabaseAccess databaseAccess = new DatabaseAccess();
// List<MovieType> movieTypes = (List<MovieType>) databaseAccess.getAll(MovieType.class);
// for(MovieType movieType_ : movieTypes) {
// System.out.println(movieType_);
// }
//
// System.out.println("#############################################################");
//
// MovieType movieType_1 = new MovieType();
// movieType_1.setId(8);
// movieType_1.setName("888");
// new DatabaseAccess().update(movieType_1);
//
// System.out.println("#############################################################");
//
// List<MovieType> movieTypes_1 = (List<MovieType>) databaseAccess.getAll(MovieType.class);
// for(MovieType movieType_2 : movieTypes_1) {
// System.out.println(movieType_2);
// }
//
// System.out.println("#############################################################");
// System.out.println("#############################################################");
//
// MovieType movieType_2 = new MovieType();
// movieType_2.setId(9);
// movieType_2.setName("dsp");
// new DatabaseAccess().update(movieType_2);
//
// System.out.println("#############################################################"); // List<MovieType> movieTypes_22 = (List<MovieType>) databaseAccess.getAll(MovieType.class);
// movieTypes_22.remove(0);
// movieTypes_22.remove(3);
// movieTypes_22.add(new MovieType());
// for(MovieType movieType_22 : movieTypes_22) {
// System.out.println(movieType_22);
// }
//
// System.out.println("###############################################################");
//
// List<MovieType> movieTypeList_23 = (List<MovieType>) new DatabaseHelper().getCachedData("movietype", MovieType.class);
// for(MovieType movieType_22 : movieTypeList_23) {
// System.out.println(movieType_22);
// }
//
// System.out.println("#########################");
// System.out.println(movieTypes_22 == movieTypeList_23); // ##################################################################################
} }

^_^ ~

SimplifiedHibernate:简化了的Hibernate的更多相关文章

  1. 02.Hibernate映射基础

    前言:Hibernate的核心功能是根据数据库到实体类的映射,自动从数据库绑定数据到实体类.使我们操作实体类(Java对象)就能对数据库进行增.删.查.改,而不用调用JDBC API使数据操作变得简单 ...

  2. java之Hibernate框架实现数据库操作

    之前我们用一个java类连接MySQL数据库实现了数据库的增删改查操作---------MySQL篇: 但是数据库种类之多,除了MySQL,还有Access.Oracle.DB2等等,而且每种数据库语 ...

  3. Hibernate Tools插件的使用

            Hibernate Tools是由JBoss推出的一个Eclipse综合开发工具插件,该插件可以简化ORM框架Hibernate,以及JBoss Seam,EJB3等的开发工作.Hib ...

  4. hibernate之单表映射

    目录 第一章 Hibernate初识 1-1 课程介绍 1-2 什么是ORM 1-3 Hibnerate简介 1-4 开发前的准备 1-5 编写第一个Hibernate例子 1-6 创建hiberna ...

  5. Hibernate初探之单表映射——Hibernate概念及插件的安装

    什么是ORM ORM(Object/Relationship Mapping):对象/关系映射 为什么要有ORM? 利用面向对象思想编写的数据库应用程序最终都是把对象信息保存在关系型数据库中,于是要编 ...

  6. Spring基础4

    一.Spring的JDBC模板 Spring对持久层也提供了解决方案,ORM模块和JDBC模板 提高简化JDBC或Hibernate的模板 二.JDBC模板使用入门 1)引入jar包:Spring开发 ...

  7. Spring从认识到细化了解

    目录 Spring的介绍 基本运行环境搭建 IoC 介绍: 示例使用: 使用说明: 使用注意: Bean的实例化方式 Bean的作用范围的配置: 补充: DI: 属性注入: 补充: IoC的注解方式: ...

  8. SSH框架简化(struts2+spring+hibernate)

    目的: 通过对ssh框架有了基础性的学习,本文主要是使用注解的方式来简化ssh框架的代码编写. 注意事项: 1.运行环境:Windows 8-64位,Eclipse(开发工具),jdk1.8.0_91 ...

  9. hibernate使用注解简化开发

    简述 在编写hibernate的时候,需要将实体类映射到数据库中的表.通常需要一个配置文件(hibernate.cfg.xml),一个实体类(XX.Java),还有一个映射文件(XX.hbm.xml) ...

随机推荐

  1. InnoDB Master Thread I/O Rate详解

    一.innodb 在刷盘时要面对的问题: 1.对于innodb 的master thread 这个线程来说,它会在后台执行许多的任务,这些任务大多数都是与IO操作相关的, 比如“刷新脏页到磁盘”.“合 ...

  2. 编程中的幂等性 — HTTP幂等性

    幂等(idempotent.idempotence)是一个数学与计算机学概念,常见于抽象代数中. 在编程中.一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同.幂等函数,或幂等方法, ...

  3. springcloud Ribbon自定义负载均衡插件

    现在我们通过插件的方式添加新的一种策略. package com.zhuyang.config; import org.springframework.beans.factory.annotation ...

  4. Socket tips: 同意socket发送UDP Broadcast

    假设创建一个UDP Socket: socketHandle = socket(serverAddr->ai_family, serverAddr->ai_socktype, server ...

  5. News summary on C# and .NET

    (keep updating...) Roslyn http://blogs.msdn.com/b/ericlippert/archive/2012/06/05/announcing-microsof ...

  6. centos升级glibc动态库

    glibc是gnu发布的libc库,即c运行库,glibc是linux系统中最底层的api,几乎其它任何运行库都会依赖于glibc.glibc除了封装linux操作系统所提供的系统服务外,它本身也提供 ...

  7. jQuery 复选框全选/取消全选/反选

    jQuery实现的复选框全选/取消全选/反选及获得选择的值. 完整代码: <!DOCTYPE html> <html> <head> <script type ...

  8. ModelSim之tcl自动化仿真

    摘要: ModelSim的tcl最大的优势就在于它可以让整个仿真自动运行,免除每次进行各种用户界面控制操作的麻烦.用tcl就可以自动完成建库.映射库到物理目录.编译源代码.启动仿真器.运行仿真等一系列 ...

  9. onethink迁移

    修改applicattion下面的Common跟User里面的config.php文件两个

  10. JVM ,Java paper

    http://files.cnblogs.com/files/WCFGROUP/IntroductiontoCompilerConstructioninaJavaWorld.pdf A Fast Wr ...