开发SSH时,往往写完PO类,设置好映射的数据库字段时,写对应的DAO的方法,再写所谓的DTO,设置好所有返回前前台的结果集,无谓就是省着写SQL了而已如果我直接在ACTION中写SQL去操作数据,查询出来的结果集直接通过封装好的JDBC方法按照字段名转换成JSON对象传递给前台,前台通过EXT去的STORE去解析对应的字段,这样完全可以省略PO DTO等等模式 如果不使用EXT,也可以传递到前台一个LIST,每条记录一个MAP,前台用过JSTL也是完全可以解析展示的。如果说没有写DAO层会造成一些复用的麻烦,也可以把所有的SQL方法写到一个DAO类中,完全也能够实现DAO操作相同数据库方法的复用个人觉得比写PO DTO啥的方便,而且HSQL写起来也不通俗 效率也低,一些复杂的SQL往往还不支持
解决方案 »
- 我就11分可用分了。好心人帮我看个问题啊。谢谢大家了
- hibernate 文件配置
- 会汇编的救命啊
- struts2 doubleselect能实现两个以上select联动么?哪位大虾实现过,帮忙给个例子
- 关于struts2查询数据库的问题
- 帮小弟介绍一下!
- Struts的<bean:write>标签如何取出指定数目的字符串呢?
- 有谁weblogic+mysql做连接池成功的吗?换其他数据库行,就是mysql不行。不想用其他数据库
- 关于struts的一个基本应用:Action类中的execute方法怎么传值给页面
- 找开源的JMS Server(非集成)。
- 请大家推荐一个压力测试工具
- 如何去掉后台错误信息(在地址栏上输入在action类中没有方法名)
后来总结了一下,
这样做可以省略不少代码,省了很多jar和框架,ssh通通不靠边了。
但是这样做,失去了mvc模式,失去了面向对象的概念,不能很好的分层,后期维护很困难,
不利于数据库移植,不灵活!我们目前是这样做的:
根据模板连接数据库生成映射文件和实体类,自己封装了一个SqlUtil类,泛型操作,dao和service就不用了,一个servlet解决所有http请求,比如:SqlUtil<User> sqlUtil = new SqlUtil<User>();
User user = new User();
user.setName("张三");
user = sqlUtil.insert(user);
Long id = user.getId();
user = sqlUtil.getById(id);
user.setAge(20);
user = sqlUtil.update(user);
user = sqlUtil.delete(user.getId());
List<User> users = sqlUtil.getDataList("select * from t_user where age >= ? order by id", new Object[] { user.getAge() });
好好运用javax.sql.DataSource这个接口和连接池,合理利用缓存(cache),其效率比hibernate或ibatis 要高的多!
我这样说,可能会有很多人不认同,没关系,这只是个人观点。
hibernate或ibatis我都用过,时间都不短,算是深有体会吧,但最终选择了jdbc,
运行效率和灵活度最终取决于设计模式!
对于不变的数据(如某种数据库有多少个正式版本,各个版本有多少种字段类型),最好的方式是枚举,写死它,无论它有多复杂。
对于有限增长的数据,应该尽量将这些数据的对象完全放进内存,比如直接描述物理设备的对象、城市对象等。
对于无限增长的数据,应该按需求将这些数据部分缓存,根据用户的行为决定缓存的内容。我现在是自己实现了内存对象库,可以通过sql直接查询内存中的对象,如果要查询在内存中就能得到满足,就不需要去查询数据库,否则则从数据库补充需要的数据到内存对象库,并将不常用的对象抛弃,数据发生更新时将内存中的对象持久化至数据库。
我是这样觉得的,ssh只是框架,框架其实是服务于业务的,那么也就是说什么样的业务决定要用什么样的框架。
如果这样看的话,其实怎么做,做成什么样,不是由框架决定的,而是由业务决定的。
所以,我们在设计系统或是产品技术框架的时候要综合考虑,技术体系的确定由方方面面决定。
例如:产品的维护、产品性能、产品的扩展性等等。所以用什么样的层次来实现都没有问题,关键有产品决定。
当然,一般ssh适合做大型的产品,模块化的需要有很强扩展性的产品,业务角度来看需要层次区分明确的产品。
并且不光是使用数据持久还有文件持久地系统,业务逻辑处理相当多的产品。
直接使用action处理数据,前台使用EXT等这样的框架是适合对业务逻辑不是很复杂或是不怎么需要业务逻辑处理的产品,直接和数据库打交道的产品特别适合使用这样的方法,不需要分那么多层。
希望这些卓见可以帮到你!
个人这么觉的的
1 首先数据库的移植的问题,除了部分通用的产品有数据库移植的需求,大部分的行业软件基本上数据库定下来就不会动了,我想估计80%的都不会动了吧
2 大型项目分这么多层,我觉得是为了后期控制项目的复杂度和规范性,毕竟那么多人在同时开发。
3 EXT是表现层 我个人觉得业务逻辑的处理还是放在后台比较好
4 另外 面向对象的思想我觉得没必要那么拘泥,起始在设计数据库表的时候,就是在做对象的设计,代码中对应表的PO类,我觉得根本上并不是对象,而是在对对象操作的定义。
你的SqlUtil通过对象的映射简化了insert update的操作 实现了hibernate的部分功能能否分享出来学习
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.log4j.Logger;
import com.zl.common.entity.EntityBean;
import com.zl.common.entity.Settled;
import com.zl.view3d.Pager;/**
* sql工具类, 经过多线程(5000个)测试, 该类线程安全,无并发,经比对,该类的运行效率比ibatis更胜一筹
* */
@SuppressWarnings("unchecked")
public final class SqlUtil<T> {
private static final Logger log = Logger.getLogger(SqlUtil.class);
private Class entityClass = null;
/**
* 构造方法
* @param entityClass
*/
public SqlUtil(Class entityClass) {
this.entityClass = entityClass;
}
/**
* 获得当前的EntityBean
* @return EntityBean
*/
public EntityBean getEntity() {
return Settled.ENTITY_MAP.get(entityClass.getName());
}
/**
* 获得数据库连接
* @return Connection
*/
public Connection getConnection() {
try {
Connection connection = Settled.dataSource.getConnection();
connection.setAutoCommit(true);
return connection;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 获得预编译语句
* @param connection 数据库连接
* @param sql sql语句
* @param args 参数列表
* @return PreparedStatement
*/
public PreparedStatement getPrepared(Connection connection, String sql, Object[] args) {
PreparedStatement prepared = null;
try {
if (null != connection && null != sql) {
prepared = connection.prepareStatement(sql);
if (null != prepared) {
if (null != args && args.length > 0) {
for (int i = 0; i < args.length; i++) {
prepared.setObject(i + 1, args[i]);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return prepared;
}
/**
* 获得结果集
* @param prepared 预编译语句
* @return ResultSet
*/
public ResultSet getResultSet(PreparedStatement prepared) {
ResultSet resultSet = null;
try {
if (null != prepared) {
resultSet = prepared.executeQuery();
}
} catch (Exception e) {
e.printStackTrace();
}
return resultSet;
}
/**
* 关闭所有连接
* @param connection 数据库连接
* @param prepared 预编译语句
* @param resultSet 结果集
*/
public void closeAll(Connection connection, PreparedStatement prepared, ResultSet resultSet) {
try {
if (null != resultSet) {
resultSet.close();
resultSet = null;
}
if (null != prepared) {
prepared.close();
prepared = null;
}
if (null != connection && !connection.isClosed()) {
connection.close();
connection = null;
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 操作数据库(增删改)
* @param sql sql语句
* @param args 参数列表
* @return Integer
*/
public Integer manage(String sql, Object[] args) {
Integer result = 0;
Connection connection = null;
PreparedStatement prepared = null;
try {
connection = getConnection();
prepared = getPrepared(connection, sql, args);
log.info(sql);
if (null != prepared) {
result = prepared.executeUpdate();
clearCacheList();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
closeAll(connection, prepared, null);
}
return result;
}
// 添加缓存
private void setCacheList(String key, List list) {
if (null != entityClass && null != list && list.size() <= 30) {
key = entityClass.getName() + "_" + key;
Settled.CACHE_LIST_ENTITY_MAP.put(key, list);
}
}
// 取出缓存
private List getCacheList(String key) {
if (null != entityClass) {
key = entityClass.getName() + "_" + key;
List list = Settled.CACHE_LIST_ENTITY_MAP.get(key);
return list;
}
return null;
}
// 根据条件清空集合缓存
private void clearCacheList() {
if (null != entityClass) {
Object []array = Settled.CACHE_LIST_ENTITY_MAP.keySet().toArray();
for (int i = 0; i < array.length; i++) {
String key = (String) array[i];
if (key.indexOf(entityClass.getName()) != -1) {
Settled.CACHE_LIST_ENTITY_MAP.remove(key);
}
}
}
}
/**
* 从数据库中获得一列值
* @param sql sql语句
* @param args 参数列表
* @return List
*/
public List<String> getTeam(String sql, Object[] args) {
List<String> result = getCacheList(sql + "_" + getArg(args));
if (null != result) {
return result;
}
result = new ArrayList<String>();
Connection connection = null;
PreparedStatement prepared = null;
ResultSet resultSet = null;
try {
connection = getConnection();
prepared = getPrepared(connection, sql, args);
log.info(sql);
resultSet = getResultSet(prepared);
if (null != resultSet) {
while (resultSet.next()) {
result.add(resultSet.getString(1));
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
closeAll(connection, prepared, resultSet);
}
setCacheList(sql + "_" + getArg(args), result);
return result;
} /**
* 从数据库中获得一个值
* @param sql sql语句
* @param args 参数列表
* @return String
*/
public String getValue(String sql, Object[] args) {
List<String> list = getTeam(sql, args);
return (list.size() > 0) ? list.get(0) : "";
} /**
* 判断真假(数据库是否有这个记录)
* @param sql sql语句必须是select count(*) from ...
* @param args 参数列表
* @return Boolean
*/
public Boolean validate(String sql, Object[] args) {
Boolean result = false;
try {
String value = getValue(sql, args);
if (!"".equals(value) && Integer.parseInt(value) > 0) {
result = true;
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 获得对象数组
* @param sql sql语句
* @param args 参数列表
* @param keys 取值的key
* @return Object[]
*/
public Object[] getArray(String sql, Object[] args, String[] keys) {
Object[] array = new Object[] {};
if (null != keys && keys.length > 0) {
array = new Object[keys.length];
Connection connection = null;
PreparedStatement prepared = null;
ResultSet resultSet = null;
try {
connection = getConnection();
prepared = getPrepared(connection, sql, args);
log.info(sql);
resultSet = getResultSet(prepared);
if (null != resultSet && resultSet.next()) {
for (int i = 0; i < keys.length; i++) {
array[i] = resultSet.getObject(keys[i]);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
closeAll(connection, prepared, resultSet);
}
}
return array;
}
/**
* 获得对象数组的集合
* @param sql sql语句
* @param args 参数列表
* @param keys 取值的key
* @return List
*/
public List<Object[]> getArrayList(String sql, Object[] args, String[] keys) {
List<Object[]> list = getCacheList(sql + "_" + getArg(args) + "_" + getArg(keys));
if (null != list) {
return list;
}
list = new ArrayList<Object[]>();
if (null != keys && keys.length > 0) {
Connection connection = null;
PreparedStatement prepared = null;
ResultSet resultSet = null;
try {
connection = getConnection();
prepared = getPrepared(connection, sql, args);
log.info(sql);
resultSet = getResultSet(prepared);
if (null != resultSet) {
while (resultSet.next()) {
Object[] array = new Object[keys.length];
for (int i = 0; i < keys.length; i++) {
array[i] = resultSet.getObject(keys[i]);
}
list.add(array);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
closeAll(connection, prepared, resultSet);
}
}
setCacheList(sql + "_" + getArg(args) + "_" + getArg(keys), list);
return list;
}
/**
* 获得表的所有字段
* @param table 表名
* @return String
*/
public String getColumns(String table) {
List<String> list = getTeam("select COLUMN_NAME from USER_TAB_COLUMNS where TABLE_NAME = ?", new Object[] { table });
String json = "[";
for (int i = 0; i < list.size(); i++) {
json += "\"" + columnLower(list.get(i)) + "\"";
if (i != list.size() - 1) {
json += ",";
}
}
json += "]";
return json;
}
/**
* 获得JSONArray格式的字符串
* @param sql sql语句
* @param args 参数列表
* @return String
*/
public String getJson(String sql, Object[] args) {
StringBuffer json = new StringBuffer("[");
Connection connection = null;
PreparedStatement prepared = null;
ResultSet resultSet = null;
try {
connection = getConnection();
prepared = getPrepared(connection, sql, args);
log.info(sql);
resultSet = getResultSet(prepared);
if (null != resultSet) {
ResultSetMetaData metaData = resultSet.getMetaData();
while (resultSet.next()) {
json.append("{");
for (int i = 1; i <= metaData.getColumnCount(); i++) {
String value = resultSet.getString(metaData.getColumnName(i));
json.append(columnLower(metaData.getColumnName(i)) + ":\"" + (null != value ? value : "") + "\"");
if (i != metaData.getColumnCount()) {
json.append(",");
}
}
json.append("},");
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
closeAll(connection, prepared, resultSet);
}
json = json.length() > 1 ? json.replace(json.length() - 1, json.length(), "") : json;
json.append("]");
return json.toString();
}
/**
* 字段转小写(驼峰命名法)
* @param value 字段
* @return String
*/
public String columnLower(String value) {
if (value.indexOf("_") != -1) {
String []arr = value.split("_");
String str = "";
for (int i = 0; i < arr.length; i++) {
if (i == 0) {
str += arr[i].toLowerCase();
} else {
String qian = arr[i].substring(0, 1).toUpperCase();
String hou = arr[i].substring(1, arr[i].length()).toLowerCase();
str += qian + hou;
}
}
return str;
}
return value.toLowerCase();
}
/**
* 封装数据
* @param sql sql语句
* @param args 参数列表
* @return List
* */
public List<T> getDataList(String sql, Object[] args) {
List list = getCacheList(sql + "_" + getArg(args));
if (null != list) {
return list;
}
list = new ArrayList();
Connection connection = null;
PreparedStatement prepared = null;
ResultSet resultSet = null;
try {
connection = getConnection();
prepared = getPrepared(connection, sql, args);
log.info(sql);
resultSet = getResultSet(prepared);
EntityBean bean = getEntity();
while (resultSet.next()) {
T object = (T) entityClass.newInstance();
for (String property : bean.getPropertyMap().keySet()) {
ReflectUtil.setPropertyValue(object, property, resultSet.getString(bean.getPropertyMap().get(property)));
}
if (null != getEntity().getIdColumn() && null != getEntity().getIdName()) {
String idValue = resultSet.getString(bean.getIdColumn());
ReflectUtil.setPropertyValue(object, bean.getIdName(), idValue);
Settled.CACHE_ID_ENTITY_MAP.put(getEntity().getClassName() + "_" + idValue, object);
}
list.add(object);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
closeAll(connection, prepared, resultSet);
}
setCacheList(sql + "_" + getArg(args), list);
return list;
}
// 把参数列表拼接成字符串
private String getArg(Object[] args) {
if (null != args && args.length > 0) {
String arg = "";
for (int i = 0; i < args.length; i++) {
if (null != args[i]) {
arg += args[i].toString() + ",";
}
}
return arg;
}
return "";
}
/**
* 查询部分实体集合
* @param sql sql语句
* @param args 参数列表
* @param num 实体的个数
* @return List
*/
public List<T> getListPart(String sql, Object[] args, int num) {
List list = getCacheList(sql + "_" + getArg(args) + "_" + num);
if (null != list) {
return list;
}
list = new ArrayList();
Connection connection = null;
PreparedStatement prepared = null;
ResultSet resultSet = null;
try {
connection = getConnection();
prepared = getPrepared(connection, sql, args);
log.info(sql);
resultSet = getResultSet(prepared);
EntityBean bean = getEntity();
int i = 0;
while (resultSet.next()) {
i++;
if (i <= num) {
T object = (T) entityClass.newInstance();
for (String property : bean.getPropertyMap().keySet()) {
ReflectUtil.setPropertyValue(object, property, resultSet.getString(bean.getPropertyMap().get(property)));
}
if (null != getEntity().getIdColumn() && null != getEntity().getIdName()) {
String idValue = resultSet.getString(bean.getIdColumn());
ReflectUtil.setPropertyValue(object, bean.getIdName(), idValue);
Settled.CACHE_ID_ENTITY_MAP.put(getEntity().getClassName() + "_" + idValue, object);
}
list.add(object);
} else {
break;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
closeAll(connection, prepared, resultSet);
}
setCacheList(sql + "_" + getArg(args) + "_" + num, list);
return list;
}
/**
* 查询单个实体
* @param sql sql语句
* @param args 参数列表
* @return Object
*/
public T getObject(String sql, Object[] args) {
List list = getDataList(sql, args);
return (list.size() > 0) ? (T) list.get(0) : null;
}
/**
* 获得表中的下一个ID的值
* @return Long
*/
public Long getNextId() {
Long result = 0l;
try {
String sql = "select max(" + getEntity().getIdColumn() + ") from " + getEntity().getTableName();
String value = getValue(sql, null);
if (null != value && !"".equals(value)) {
result = Long.parseLong(value) + 1;
} else {
result = 1l;
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 保存记录
* @param entity 实体
* @return Object
* */
public T insert(T entity) {
EntityBean bean = getEntity();
String idValue = null;
List<Object> args = new ArrayList<Object>();
String sql = "insert into " + bean.getTableName() + " (", columnSql = "", paramSql = "";;
for (String property : bean.getPropertyMap().keySet()) {
Object value = ReflectUtil.getPropertyValue(entity, property);
if (null != value) {
columnSql += bean.getPropertyMap().get(property) + ", ";
if (Settled.DATE_CLASS.equals(value.getClass().getName())) {
paramSql += "to_date('" + Settled.formatDateTime().format((Date) value) + "', 'yyyy-mm-dd hh24:mi:ss'), ";
} else {
paramSql += "?, ";
args.add(value.toString());
}
}
}
sql += (columnSql.length() > 0 ? columnSql.substring(0, columnSql.length() - 2) : columnSql);
if (EntityBean.ID_CREATE_CUSTOM.equals(bean.getIdCreate()) || EntityBean.ID_CREATE_SEQUENCE.equals(bean.getIdCreate())) {
sql += ", " + bean.getIdColumn();
idValue = (EntityBean.ID_CREATE_CUSTOM.equals(bean.getIdCreate()) ? (String) ReflectUtil.getPropertyValue(entity, bean.getIdName()) : getValue("select " + bean.getIdSequence() + ".Nextval from dual", null));
args.add(idValue);
}
sql += ") values (";
sql += (paramSql.length() > 0 ? paramSql.substring(0, paramSql.length() - 2) : paramSql);
if (EntityBean.ID_CREATE_CUSTOM.equals(bean.getIdCreate()) || EntityBean.ID_CREATE_SEQUENCE.equals(bean.getIdCreate())) {
sql += ", ?";
}
sql += ")";
manage(sql, args.toArray());
if (EntityBean.ID_CREATE_NATIVE.equals(bean.getIdCreate())) {
idValue = String.valueOf(getNextId() - 1);
}
ReflectUtil.setPropertyValue(entity, bean.getIdName(), idValue);
Settled.CACHE_ID_ENTITY_MAP.put(bean.getClassName() + "_" + idValue, entity);
return (T) entity;
}
/**
* 删除记录
* @param id 实体的ID
* @return Object
* */
public T delete(Serializable id) {
T entity = get(id);
String sql = "delete from " + getEntity().getTableName() + " where " + getEntity().getIdColumn() + " = ?";
manage(sql, new Object[]{ id });
Settled.CACHE_ID_ENTITY_MAP.remove(getEntity().getClassName() + "_" + id);
return (T) entity;
}
/**
* 修改记录
* @param entity 实体
* @return Object
* */
public T update(T entity) {
EntityBean bean = getEntity();
List<Object> args = new ArrayList<Object>();
String sql = "update " + bean.getTableName() + " set";
for (String property : bean.getPropertyMap().keySet()) {
Object value = ReflectUtil.getPropertyValue(entity, property);
if (null != value) {
if (Settled.DATE_CLASS.equals(value.getClass().getName())) {
sql += " " + bean.getPropertyMap().get(property) + " = to_date('" + Settled.formatDateTime().format((Date) value) + "', 'yyyy-mm-dd hh24:mi:ss'),";
} else {
sql += " " + bean.getPropertyMap().get(property) + " = ?,";
args.add(value.toString());
}
}
}
sql = sql.substring(0, sql.length() - 1);
sql += " where " + bean.getIdColumn() + " = ?";
String idValue = String.valueOf(ReflectUtil.getPropertyValue(entity, bean.getIdName()));
args.add(idValue);
manage(sql, args.toArray());
return resetEditCache(entity, idValue);
}
// 修改记录是更新缓存
private T resetEditCache(T entity, String idValue) {
try {
EntityBean bean = getEntity();
T object = (T) Settled.CACHE_ID_ENTITY_MAP.get(bean.getClassName() + "_" + idValue);
if (null != object) {
for (String property : bean.getPropertyMap().keySet()) {
Object value = ReflectUtil.getPropertyValue(entity, property);
if (null != value) {
Method method = object.getClass().getMethod(ReflectUtil.getMethodName(property, "set"), value.getClass());
method.invoke(object, value);
}
}
Settled.CACHE_ID_ENTITY_MAP.put(bean.getClassName() + "_" + idValue, object);
return (T) object;
}
} catch (Exception e) {
e.printStackTrace();
}
return get(idValue);
}
/**
* 根据ID获得记录
* @param id 实体的ID
* @return Object
* */
public T getById(Serializable id) {
if (null != Settled.CACHE_ID_ENTITY_MAP.get(getEntity().getClassName() + "_" + id)) {
return (T) Settled.CACHE_ID_ENTITY_MAP.get(getEntity().getClassName() + "_" + id);
}
String sql = "select * from " + getEntity().getTableName() + " where " + getEntity().getIdColumn() + " = ?";
T entity = getObject(sql, new Object[]{ id });
Settled.CACHE_ID_ENTITY_MAP.put(getEntity().getClassName() + "_" + id, entity);
return (T) entity;
}
/**
* 获得表中的所有的实体
* @return List
*/
public List<T> getBeans() {
String order = (null != getEntity().getIdColumn() ? " order by " + getEntity().getIdColumn() : "");
String sql = "select * from " + getEntity().getTableName() + order;
return getDataList(sql, null);
}
// 获得分页
private Pager<T> pagination(String numSql, Object[] args, int pageNo, int pageSize) {
try {
Pager pager = new Pager(pageNo, pageSize);
pager.setTotalCount(Integer.parseInt(getValue(numSql, args)));
return pager;
} catch (Exception e) {
e.printStackTrace();
}
return new Pager();
}
/**
* 获得分页
* @param sql 查询数据数量的sql必须是select * from 开头
* @param args 参数列表(可以为null)
* @param pageNo 当前页数
* @param pageSize 分页的基数
* @return Pager
* */
public Pager<T> getPage(String sql, Object[] args, int pageNo, int pageSize) {
args = (null == args ? new Object[] {} : args);
Pager pager = pagination(sql.replace("*", "count(*)"), args, pageNo, pageSize);
Object[] newArgs = new Object[args.length + 2];
for (int i = 0; i < args.length; i++) {
newArgs[i] = args[i];
}
sql = "select * from ( select temp.*, rownum rownumt from (" + sql + ") temp where rownum <= ?) where rownumt > ?";
newArgs[newArgs.length - 2] = pager.getSkipResults() + pageSize;
newArgs[newArgs.length - 1] = pager.getSkipResults();
pager.setList(getDataList(sql, newArgs));
return pager;
}
}
这些方法是必须泛型才能调用的,差不多每个方法需要提供两个参数: sql语句和参数列表,
基本上可以满足日常操作了,
增删改操作的事物默认设置为自动提交,如果需要手动提交,只能重写jdbc代码。
以上代码如果有不足之处,还请多多指教哈!
希望各位大侠多提宝贵意见,在下必会虚心接受!
这位同学问的很好,如果有多个数据库,只要稍微改改就好了。
首先建一个实体类:JdbcConfig:
/** 数据库类型为:oracle */
public static final String DATABASE_ORACLE = "oracle";
/** 数据库类型为:mysql */
public static final String DATABASE_MYSQL = "mysql";
/** 数据库类型为:sqlserver */
public static final String DATABASE_SQLSERVER = "sqlserver";
private static final long serialVersionUID = 1L;
private DataSource dataSource;// 数据源
private String jdbcFolder;// 实体类和表结构的映射文件目录
private Boolean showSql;// 是否显示sql语句
private String databaseType;// 数据库类型(暂时支持oracle,mysql,sqlserver三种)
private Boolean createSqlFile;// 是否生成创建表结构的sql语句(如果为true,将会在classes根目录生成sql文件)
private Map<String, EntityBean> entityMap;// 包含的EntityBean, EntityBean中包含了实体类和表的映射关系
/**set和get方法就省略了**/假如项目要连接这三个数据库,在项目启动的时候,想办法初始化三个JdbcConfig,设置为静态变量,保存在内存中。
再修改SqlUtil的代码private JdbcConfig jdbcConfig = null;
private Class entityClass = null;
private EntityBean entityBean = null;
/**
* 构造方法
* @param entityClass
*/
public SqlUtil(JdbcConfig jdbcConfig, Class entityClass) {
if (null == jdbcConfig || null == entityClass) {
//做异常处理
}
this.jdbcConfig = jdbcConfig;
this.entityClass = entityClass;
EntityBean entity = this.jdbcConfig.getEntityMap().get(entityClass.getName());
if (entity != null) {
this.entityBean = entity;
} else {
// jdbcConfig没有要包含这个entityClass,或者说表和数据库没扯上关系,做异常处理
}
}
/**
* 获得当前的EntityBean
* @return EntityBean
*/
public EntityBean getEntity() {
return entityBean;
}
/**
* 获得数据库连接
* @return Connection
*/
public Connection getConnection() {
try {
Connection connection = jdbcConfig.getDataSource().getConnection();
connection.setAutoCommit(true);
return connection;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}这样做的可以让SqlUtil根据不同的JdbcConfig获得不同的Connection,找到对应的实体和库表再操作,
insert,update和分页是SqlUtil自动生成的sql,可以写点判断语句,根据jdbcConfig.getDatabaseType()生成与数据库对应的sql,确保万无一失。这是一个简单的SqlUtil工具类,只能满足单表的增删改查,要想解决多表主外键关系的话,dao数据层还是少不了的呀,有了数据层,就要考虑注入了。只要你掌握好java反射机制,这些都是小问题。
让人头疼的是三个数据库的事物不好统一管理,所以还得研究spring
分模块还易于测试。
像MySQL的Mapper还能提供编译期检测,好处很多,利大于弊。
这里写错了,应该是:SqlUtil<User> sqlUtil = new SqlUtil<User>(User.class);
不好意思哈!
是的,到处是sql语句,自己看到也难过,别人就更加难维护了。
我们通常把sql语句写在.xml(一张表一个xml)文件中,在项目启动的时候,想办法读一下xml,把sql语句加载到Map,或者说内存中,要用的时候去Map取。但有时候需要动态拼接sql,只好根据需要再写一个util工具类.
无论数据的来源是文件 数据库 还是SOCKET接口等等
只是获取的方式不同,最终数据还是可以整理成list/map的形式返回前台
无非多封装几个方法罢了
况且这个h照样也搞不定 照样还是要自己去实现
我这里说的意思,不是说你写的sql工具有什么问题,也不是返回的map也好list也好这都没什么关系,
我是说你在action中直接去写逻辑,哪怕是简单的增删改查,这样带来的后果就是,页面严重和数据层耦合了,真是牵一发而动全身了。
虽然对我看来,无论结构体还是字符串还是实体类,基本上都是一样的,或者实现的结果都是一样的,
前台发起交易,构造出基本的数据,后台校验数据,最终操作数据库。
而且项目规模小,基本上就10-20张表。
所以,我更倾向于开发的时候更加直接高效的写代码。今天看到一个老帖,有人提出了个问题,先有实体类还是先有表。我觉得这个可能是我疑惑的根源,或者是面向对象的理解不透彻吧。上面讨论的有几点我承认,按照我的想法,
确实造成表字段修改的地方不集中,很麻烦;SQL写的到处都是很不简洁
这也是我想解决的问题,所以才想到和大家进行讨论