- 浏览: 1528679 次
- 性别:
- 来自: 厦门
博客专栏
-
Spring 3.x企业实...
浏览量:464561
文章分类
最新评论
-
JyeChou:
学习Spring必学的Java基础知识(1)----反射 -
hhzhaoheng:
...
《Spring4.x企业应用开发实战》光盘资料下载 -
renlongnian:
//assertReflectionEquals(user1, ...
单元测试系列之3:测试整合之王Unitils -
骑着蜗牛超F1:
huang_yong 写道我的经验是,只需定义三层:1.ent ...
Spring的事务管理难点剖析(2):应用分层的迷惑 -
wangyudong:
工具地址貌似更新了哦https://github.com/Wi ...
几种常用的REST webservice客户端测试工具
DAO类中查询方法的签名多种多样,大家都使用什么签名方法呢?拿出来讨论一下吧。
DAO层除了CRUD的数据操作外,另一个重要的操作就是根据查询条件执行数据查询,不同的ORM框架都允许用户动态绑定参数确定查询条件。查询条件项的数目往往是不固定的,如既可能要求以userName为条件查询User,也可能要求以userName+status等组合条件查询User。条件项数目的不定性给查询接口方法的设计造成为一定的困难,实体DAO定义带参的查询方法时,一般有5种方式,下面分别对这些方法进行介绍。
方式1:每一个条件项参数对应一个入参
查询方法中为每一个查询条件项定义一个对应的入参,如:
这种方法签名含义清晰,可读性强,内部的逻辑处理简单,但接口稳定性差。
假如这个findOrder()方法需要添加一个userName的条件,有两种重构的方式:第一,调整方法的签名,新增一个String userName入参,这种重构被认为是不健康的重构,因为它违反软件设计中经典的“开-闭原则”,此外如果条件项个数很多,方法签名将显得过于拖沓;第二,在DAO类中新增一个重载查询方法,如果查询条件项的组合数过多,DAO类的方法数目将直线上升,整个实体DAO类将显得臃肿笨重。
方式2:使用数组传递条件项参数
通过数组的方式传递查询条件项参数,由于参数类型的不一致性,要求数组类型采用Object[]:
这种方法接口可以应付查询条件项参数组合的多样性并保持接口的稳定性,开发者必须在方法内部从数组中获取参数再传递给查询引擎。缺点是方法的可读性不强,调用者往往需要通过查看接口对应的Javadoc才能正确使用。此外,在JDK 5.0以下的版本中,因为没有自动拆/解包的语法特性,调用前必须对基本类型的参数使用封装类封装,有时在方法内部还需要进行相反的过程,在使用上较为不便。不过由于Spring为支持的ORM框架都提供了类似的查询接口(如HibernateTemplate#find(String queryString, Object[] values)),所以DAO方法内部的处理相对还是比较简单的。
方式3:使用JDK 5.0的不定参数
如果在JDK 5.0中,则可以采用不定参数进行方法签名,这种方式在逻辑上和方式2并无多大的区别:
方式4:将查询条件项参数封装成对象
为了提高方法1中方法签名简洁性,增强方法2、3中方法签名的可读性,方式4提出将查询条件项参数封装成一个对象的思路,查询方法使用查询条件对象传递查询条件:
OrderQueryParam查询条件对象封装了hql查询语句可能会用到的条件项参数,在查询方法内部,开发者必须判断查询条件对象的属性并正确绑定条件项参数。由于需要为条件项参数定义一个类,因此会造成类数目的膨胀,有时甚至一个实体DAO需要对应多个查询条件参数类。另外,当需要添加一个新的条件项参数时,条件封装类还需要进行相应调整。
方式5:使用Map传递条件项参数
另一种被广泛使用的方法是采用Map传递条件项参数,键为参数名,值为参数值:
使用这种方式,接口方法签名可以在条件项发生变化的情况下保持稳定,同时通过键指定条件项参数名在一定程度上解决了接口的健壮性(当调用者指定错误参数名时容易得到错误报警)。但和方法2、3一样调用者必须通过接口Javadoc才能明白不同条件项要以什么名称进行设置。
注:以上5个查询方法签名的总结摘自于《精通Spring 2.x--企业应用开发详解》
你这种用Where的写法,会不会在安全上有问题呢,这样的话,任何一个程序员都可以操作这个表了,一下子就把数据层暴露了,虽然是select,但个人觉得为了安全,应该一个条件写一个方法~
Where where = Where.rootWhere("prop",Where.EQ,object);
多条件查询怎么搞啊? 及有 and、or
写一个CreteriaUtils将 =,>,like条件等转换为hibernate的Creteria
DAO层除了CRUD的数据操作外,另一个重要的操作就是根据查询条件执行数据查询,不同的ORM框架都允许用户动态绑定参数确定查询条件。查询条件项的数目往往是不固定的,如既可能要求以userName为条件查询User,也可能要求以userName+status等组合条件查询User。条件项数目的不定性给查询接口方法的设计造成为一定的困难,实体DAO定义带参的查询方法时,一般有5种方式,下面分别对这些方法进行介绍。
参数不稳定,同样你的语句也会不稳定啊,比如userName+status的情况,就会成为where userName=? or status=?,楼主怎么没有讨论这种情况呢?这样的话,方法中传入语句就不行了。再者,你的查找方法为什么要传入语句呢,像List findOrder(String hql,Object[] params),难道你还在DAO的外面去拼sql?而且怎么看findOrder也不是basedao里的,传入语句就没有道理了。楼主最好说清楚这里讨论的是basedao还是继承的dao
我觉得楼主讨论的更像是DAO的查询方法的参数该怎样写,既清晰又简单。根据以上分析,应该变成这样:
List findOrder(String hql,Object[] params) --> List findOrder(Object[] params)
方法里面,就可以根据情况使用hql、sql或Criteria
至于参数哪种好,我觉得除了那个参数一一写出来的,其他都还好
翻页查询我一般直接用JDBC,这样更灵活更高效,一般只对单条记录操作使用Hibernate,在实际应用中我发觉这种方式挺适用的。
这种方式主要是要写很多个条件参数的对象,我倒觉得这种方式是不太好的。
Where where = Where.rootWhere("prop",Where.EQ,object);
这种方式挺有创意的,也相当灵活,相当不错!
Hibernate似乎有类似的组件吧。。。当然了不用Hibernate就是另外一码事。。。
他的灵感来源于hibernate的Criteria
Where where = Where.rootWhere("prop",Where.EQ,object);
这种方式挺有创意的,也相当灵活,相当不错!
Hibernate似乎有类似的组件吧。。。当然了不用Hibernate就是另外一码事。。。
DAO层除了CRUD的数据操作外,另一个重要的操作就是根据查询条件执行数据查询,不同的ORM框架都允许用户动态绑定参数确定查询条件。查询条件项的数目往往是不固定的,如既可能要求以userName为条件查询User,也可能要求以userName+status等组合条件查询User。条件项数目的不定性给查询接口方法的设计造成为一定的困难,实体DAO定义带参的查询方法时,一般有5种方式,下面分别对这些方法进行介绍。
方式1:每一个条件项参数对应一个入参
查询方法中为每一个查询条件项定义一个对应的入参,如:
List findOrder(String hql,Date startTime,Date endTime,int deptId)
这种方法签名含义清晰,可读性强,内部的逻辑处理简单,但接口稳定性差。
假如这个findOrder()方法需要添加一个userName的条件,有两种重构的方式:第一,调整方法的签名,新增一个String userName入参,这种重构被认为是不健康的重构,因为它违反软件设计中经典的“开-闭原则”,此外如果条件项个数很多,方法签名将显得过于拖沓;第二,在DAO类中新增一个重载查询方法,如果查询条件项的组合数过多,DAO类的方法数目将直线上升,整个实体DAO类将显得臃肿笨重。
方式2:使用数组传递条件项参数
通过数组的方式传递查询条件项参数,由于参数类型的不一致性,要求数组类型采用Object[]:
List findOrder(String hql,Object[] params)
这种方法接口可以应付查询条件项参数组合的多样性并保持接口的稳定性,开发者必须在方法内部从数组中获取参数再传递给查询引擎。缺点是方法的可读性不强,调用者往往需要通过查看接口对应的Javadoc才能正确使用。此外,在JDK 5.0以下的版本中,因为没有自动拆/解包的语法特性,调用前必须对基本类型的参数使用封装类封装,有时在方法内部还需要进行相反的过程,在使用上较为不便。不过由于Spring为支持的ORM框架都提供了类似的查询接口(如HibernateTemplate#find(String queryString, Object[] values)),所以DAO方法内部的处理相对还是比较简单的。
方式3:使用JDK 5.0的不定参数
如果在JDK 5.0中,则可以采用不定参数进行方法签名,这种方式在逻辑上和方式2并无多大的区别:
List findOrder(String hql,Object... params)
方式4:将查询条件项参数封装成对象
为了提高方法1中方法签名简洁性,增强方法2、3中方法签名的可读性,方式4提出将查询条件项参数封装成一个对象的思路,查询方法使用查询条件对象传递查询条件:
List<Order> findOrder(String hql,OrderQueryParam param)
OrderQueryParam查询条件对象封装了hql查询语句可能会用到的条件项参数,在查询方法内部,开发者必须判断查询条件对象的属性并正确绑定条件项参数。由于需要为条件项参数定义一个类,因此会造成类数目的膨胀,有时甚至一个实体DAO需要对应多个查询条件参数类。另外,当需要添加一个新的条件项参数时,条件封装类还需要进行相应调整。
方式5:使用Map传递条件项参数
另一种被广泛使用的方法是采用Map传递条件项参数,键为参数名,值为参数值:
List<Order> findOrder(String hql,Map params)
使用这种方式,接口方法签名可以在条件项发生变化的情况下保持稳定,同时通过键指定条件项参数名在一定程度上解决了接口的健壮性(当调用者指定错误参数名时容易得到错误报警)。但和方法2、3一样调用者必须通过接口Javadoc才能明白不同条件项要以什么名称进行设置。
注:以上5个查询方法签名的总结摘自于《精通Spring 2.x--企业应用开发详解》
评论
24 楼
01071405
2008-04-02
记得以前进行java培训时候,学的就是dao,可惜工作了也就不用这个了,现在用spring,感觉以前培训的时候好幼稚
23 楼
MrLee23
2008-03-24
tianhen 写道
我们一般是写了一个分页查询的方法:
List pagedQuery(Page page, Where where);
where条件是一个条件树,可以任意进行组合完成复杂的条件查询。
List pagedQuery(Page page, Where where);
where条件是一个条件树,可以任意进行组合完成复杂的条件查询。
你这种用Where的写法,会不会在安全上有问题呢,这样的话,任何一个程序员都可以操作这个表了,一下子就把数据层暴露了,虽然是select,但个人觉得为了安全,应该一个条件写一个方法~
22 楼
realorg
2008-03-23
tianhen 写道
Where where = Where.rootWhere("prop",Where.EQ,object);
多条件查询怎么搞啊? 及有 and、or
21 楼
hajunma
2008-01-31
通过Annotation的方法确实有点创意,不错啊。
20 楼
sswh
2008-01-30
我目前的写法,只是感到不够灵活,到不够用的时候再想办法重构好了。。
@Target( { ElementType.FIELD }) @Retention(RetentionPolicy.RUNTIME) public @interface SQLQuery { /** * 与查询参数对应的SQL片段的数组<br> * 数组长度=1:此SQL片段被插入到SQL查询语句中,实际参数值添加到与?对应的位置。<br> * 数组长度=2:此SQL片段被插入到SQL查询语句中,实际参数类型应该是Boolean,<br> * 当实参=true,插入第一个SQL片段,实参=false,插入第二个SQL片段 * * @return */ String[] value() default {}; } public class QueryBuilder { // 生成的SQL语句 StringBuilder sql = new StringBuilder(); // sql中与‘?’匹配的参数 List<Object> params = new ArrayList<Object>(); /** * 构建查询语句<br> * * 例子:QueryBuilder builder = new QueryBuilder();<br> * builder.setSql(buf);<br> * builder.setParams(params);<br> * builder.build(QueryArgs.class, args); * * @param clazz * 用注解标识的查询参数类 * @param args * 查询参数对象,可以是查询参数类的实例,<br> * 也可以仅仅是一个map,只要符合OGNL读取数据的方式。 * @return */ public StringBuilder build(Class<?> clazz, Object args) { // 如果没有传递实际参数,则忽略此次构建 if (args == null) return sql; for (Field field : clazz.getDeclaredFields()) { SQLQuery query = field.getAnnotation(SQLQuery.class); // 非查询字段,跳到下一个 if (query == null) continue; try { Object value = Ognl.getValue(field.getName(), args); // 查询字段空缺的,跳到下一个 if (value == null || (value instanceof String && StringUtils.isEmpty(value.toString()))) continue; // query.value().length所表示的含义参考SQLQuery注解 if (query.value().length == 1) { sql.append(query.value()[0]); params.add(value); } else if (query.value().length >= 2) sql.append(Boolean.valueOf(value.toString()) ? query.value()[0] : query.value()[1]); // query.value().length==0,跳到下一个 } catch (Exception e) { log.warn("处理查询参数失败,该参数被忽略:" + field.getName()); continue; } } return sql; } //省略其他部分。。。。 } public class QueryArgs { // 受理码 @SQLQuery(" and a.acceptCode=?") String acceptCode; // 项目类型 @SQLQuery(" and a.definition.id=?") Long definitionId; // 申请人姓名,模糊查询 @SQLQuery(" and a.proposer.name like '%'+?+'%'") String proposerName; // 受理时间范围1 @SQLQuery(" and a.acceptTime >= ?") Date beginTime; // 受理时间范围2 @SQLQuery(" and a.acceptTime <= ?") Date endTime; // 是否已经办结,如果未指定,则包括全部项目 @SQLQuery( { " and a.finishedTime is not null", " and a.finishedTime is null" }) Boolean m_finished; // 假想的finished参数,供页面使用, // 因为struts2将0长度字符串传入Boolean的时候,转成了false,下面是为解决这个问题 public void setFinished(String finished) { m_finished = StringUtils.isEmpty(finished) ? null : Boolean.valueOf(finished); } // 承办单位id @SQLQuery(" and a.definition.department.id=?") Long departmentId; //省略若干getter、setter。。。 }
19 楼
sswh
2008-01-30
我目前的写法,只是感到不够灵活,到不够用的时候再想办法重构好了。。
@Target( { ElementType.FIELD }) @Retention(RetentionPolicy.RUNTIME) public @interface SQLQuery { /** * 与查询参数对应的SQL片段的数组<br> * 数组长度=1:此SQL片段被插入到SQL查询语句中,实际参数值添加到与?对应的位置。<br> * 数组长度=2:此SQL片段被插入到SQL查询语句中,实际参数类型应该是Boolean,<br> * 当实参=true,插入第一个SQL片段,实参=false,插入第二个SQL片段 * * @return */ String[] value() default {}; } public class QueryBuilder { // 生成的SQL语句 StringBuilder sql = new StringBuilder(); // sql中与‘?’匹配的参数 List<Object> params = new ArrayList<Object>(); /** * 构建查询语句<br> * * 例子:QueryBuilder builder = new QueryBuilder();<br> * builder.setSql(buf);<br> * builder.setParams(params);<br> * builder.build(QueryArgs.class, args); * * @param clazz * 用注解标识的查询参数类 * @param args * 查询参数对象,可以是查询参数类的实例,<br> * 也可以仅仅是一个map,只要符合OGNL读取数据的方式。 * @return */ public StringBuilder build(Class<?> clazz, Object args) { // 如果没有传递实际参数,则忽略此次构建 if (args == null) return sql; for (Field field : clazz.getDeclaredFields()) { SQLQuery query = field.getAnnotation(SQLQuery.class); // 非查询字段,跳到下一个 if (query == null) continue; try { Object value = Ognl.getValue(field.getName(), args); // 查询字段空缺的,跳到下一个 if (value == null || (value instanceof String && StringUtils.isEmpty(value.toString()))) continue; // query.value().length所表示的含义参考SQLQuery注解 if (query.value().length == 1) { sql.append(query.value()[0]); params.add(value); } else if (query.value().length >= 2) sql.append(Boolean.valueOf(value.toString()) ? query.value()[0] : query.value()[1]); // query.value().length==0,跳到下一个 } catch (Exception e) { log.warn("处理查询参数失败,该参数被忽略:" + field.getName()); continue; } } return sql; } //省略其他部分。。。。 } public class QueryArgs { // 受理码 @SQLQuery(" and a.acceptCode=?") String acceptCode; // 项目类型 @SQLQuery(" and a.definition.id=?") Long definitionId; // 申请人姓名,模糊查询 @SQLQuery(" and a.proposer.name like '%'+?+'%'") String proposerName; // 受理时间范围1 @SQLQuery(" and a.acceptTime >= ?") Date beginTime; // 受理时间范围2 @SQLQuery(" and a.acceptTime <= ?") Date endTime; // 是否已经办结,如果未指定,则包括全部项目 @SQLQuery( { " and a.finishedTime is not null", " and a.finishedTime is null" }) Boolean m_finished; // 假想的finished参数,供页面使用, // 因为struts2将0长度字符串传入Boolean的时候,转成了false,下面是为解决这个问题 public void setFinished(String finished) { m_finished = StringUtils.isEmpty(finished) ? null : Boolean.valueOf(finished); } // 承办单位id @SQLQuery(" and a.definition.department.id=?") Long departmentId; //省略若干getter、setter。。。 }
18 楼
泡泡
2008-01-28
List<Order> orderList = new service.queryList(Order.class,new HashMap(){{ put("type.name","=新订单"); put("createdDate","bewteen 2008-01-01 and 2008-01-30"); put("orderBy.name","=张三"); }});
写一个CreteriaUtils将 =,>,like条件等转换为hibernate的Creteria
17 楼
Clayz
2008-01-27
我一般都是用的最后一种,用Criteria感觉和自己手工写没有多大区别。
只是想问问这个Where是如何设计的,不知可否讲解一下呢。
只是想问问这个Where是如何设计的,不知可否讲解一下呢。
16 楼
spiritfrog
2008-01-26
stamen 写道
DAO层除了CRUD的数据操作外,另一个重要的操作就是根据查询条件执行数据查询,不同的ORM框架都允许用户动态绑定参数确定查询条件。查询条件项的数目往往是不固定的,如既可能要求以userName为条件查询User,也可能要求以userName+status等组合条件查询User。条件项数目的不定性给查询接口方法的设计造成为一定的困难,实体DAO定义带参的查询方法时,一般有5种方式,下面分别对这些方法进行介绍。
参数不稳定,同样你的语句也会不稳定啊,比如userName+status的情况,就会成为where userName=? or status=?,楼主怎么没有讨论这种情况呢?这样的话,方法中传入语句就不行了。再者,你的查找方法为什么要传入语句呢,像List findOrder(String hql,Object[] params),难道你还在DAO的外面去拼sql?而且怎么看findOrder也不是basedao里的,传入语句就没有道理了。楼主最好说清楚这里讨论的是basedao还是继承的dao
我觉得楼主讨论的更像是DAO的查询方法的参数该怎样写,既清晰又简单。根据以上分析,应该变成这样:
List findOrder(String hql,Object[] params) --> List findOrder(Object[] params)
方法里面,就可以根据情况使用hql、sql或Criteria
至于参数哪种好,我觉得除了那个参数一一写出来的,其他都还好
15 楼
hajunma
2008-01-21
b051 写道
要说查询条件的对象化, 那肯定是4.
1,2,3没有什么区别, 5只是在namedparam比较有用. 问题是有的, 但我如果写dao的话, 还是会用3.
要说内存占用和工作效率, 多半应该是3好于4.
我认为真正的dao是没有业务逻辑,只是怎么和数据库对话而已. 在已经有了hibernate/jpa/jdbctemplate的情况下, 这种东西实在没必要人去做. 除非数据库压根没可能对象化.
撇开dao不谈, 要说查询的方式, 我喜欢这样的方式:
public interface PersonAccess {
@Finder(query="from Person where firstName = :firstName")
Person find(@Named("firstName") String name);
}
翻页:
public interface PersonAccess {
@Finder(query="from Person")
List<Person> listAll(@FirstResult int first, @MaxResults int max);
}
接口已经完全说明怎么查询了,其实现的单例动态生成就可以了.asm+guice/cglib.
(http://www.wideplay.com/dynamicfinders)
1,2,3没有什么区别, 5只是在namedparam比较有用. 问题是有的, 但我如果写dao的话, 还是会用3.
要说内存占用和工作效率, 多半应该是3好于4.
我认为真正的dao是没有业务逻辑,只是怎么和数据库对话而已. 在已经有了hibernate/jpa/jdbctemplate的情况下, 这种东西实在没必要人去做. 除非数据库压根没可能对象化.
撇开dao不谈, 要说查询的方式, 我喜欢这样的方式:
public interface PersonAccess {
@Finder(query="from Person where firstName = :firstName")
Person find(@Named("firstName") String name);
}
翻页:
public interface PersonAccess {
@Finder(query="from Person")
List<Person> listAll(@FirstResult int first, @MaxResults int max);
}
接口已经完全说明怎么查询了,其实现的单例动态生成就可以了.asm+guice/cglib.
(http://www.wideplay.com/dynamicfinders)
翻页查询我一般直接用JDBC,这样更灵活更高效,一般只对单条记录操作使用Hibernate,在实际应用中我发觉这种方式挺适用的。
14 楼
b051
2008-01-16
要说查询条件的对象化, 那肯定是4.
1,2,3没有什么区别, 5只是在namedparam比较有用. 问题是有的, 但我如果写dao的话, 还是会用3.
要说内存占用和工作效率, 多半应该是3好于4.
我认为真正的dao是没有业务逻辑,只是怎么和数据库对话而已. 在已经有了hibernate/jpa/jdbctemplate的情况下, 这种东西实在没必要人去做. 除非数据库压根没可能对象化.
撇开dao不谈, 要说查询的方式, 我喜欢这样的方式:
public interface PersonAccess {
@Finder(query="from Person where firstName = :firstName")
Person find(@Named("firstName") String name);
}
翻页:
public interface PersonAccess {
@Finder(query="from Person")
List<Person> listAll(@FirstResult int first, @MaxResults int max);
}
接口已经完全说明怎么查询了,其实现的单例动态生成就可以了.asm+guice/cglib.
(http://www.wideplay.com/dynamicfinders)
1,2,3没有什么区别, 5只是在namedparam比较有用. 问题是有的, 但我如果写dao的话, 还是会用3.
要说内存占用和工作效率, 多半应该是3好于4.
我认为真正的dao是没有业务逻辑,只是怎么和数据库对话而已. 在已经有了hibernate/jpa/jdbctemplate的情况下, 这种东西实在没必要人去做. 除非数据库压根没可能对象化.
撇开dao不谈, 要说查询的方式, 我喜欢这样的方式:
public interface PersonAccess {
@Finder(query="from Person where firstName = :firstName")
Person find(@Named("firstName") String name);
}
翻页:
public interface PersonAccess {
@Finder(query="from Person")
List<Person> listAll(@FirstResult int first, @MaxResults int max);
}
接口已经完全说明怎么查询了,其实现的单例动态生成就可以了.asm+guice/cglib.
(http://www.wideplay.com/dynamicfinders)
13 楼
whilew
2008-01-15
暂时来看大家用4的可能性比较大,但是此种方案对于动态灵活性可能有待提高,此种方式对于代码中重复性代码会较多
12 楼
stamen
2008-01-12
joyfun 写道
ibatis用的就是方法4 查询条件当对象传入 这样挺好的
这种方式主要是要写很多个条件参数的对象,我倒觉得这种方式是不太好的。
11 楼
lxrw
2008-01-11
恩 学习了.
10 楼
joyfun
2008-01-10
ibatis用的就是方法4 查询条件当对象传入 这样挺好的
9 楼
icream
2008-01-10
我觉得上面的5种方式都不够优雅
不过也没发现有什么好的方式~~~
除非自己实现一套类似与hibernate的Criteria
不过也没发现有什么好的方式~~~
除非自己实现一套类似与hibernate的Criteria
8 楼
icream
2008-01-10
EXvision 写道
stamen 写道
tianhen 写道
Where where = Where.rootWhere("prop",Where.EQ,object);
这种方式挺有创意的,也相当灵活,相当不错!
Hibernate似乎有类似的组件吧。。。当然了不用Hibernate就是另外一码事。。。
他的灵感来源于hibernate的Criteria
7 楼
rasonyang
2008-01-08
Criteria更好.
and(
eq("thisDN",750),
gt("size",5)
or(
eq("otherDN",110),
like("name","%Rason%")
)
)
and(
eq("thisDN",750),
gt("size",5)
or(
eq("otherDN",110),
like("name","%Rason%")
)
)
6 楼
EXvision
2008-01-08
stamen 写道
tianhen 写道
Where where = Where.rootWhere("prop",Where.EQ,object);
这种方式挺有创意的,也相当灵活,相当不错!
Hibernate似乎有类似的组件吧。。。当然了不用Hibernate就是另外一码事。。。
5 楼
e3002
2008-01-04
没明白啊,能否给个例子?
发表评论
-
一个常见的Spring IOC疑难症状
2013-07-25 14:14 5070Case 请看下面的IOC实例: 1)Aa ... -
mybatis3.1分页自动添加总数
2013-07-08 21:11 22863问题 1.mybatis默认分页是内存分页的,谁用谁崩溃啊! ... -
学习Spring必学的Java基础知识(9)----HTTP请求报文
2012-06-09 16:02 13956引述要学习Spring框架的技术内幕,必须事先掌握一些基本的J ... -
学习Spring必学的Java基础知识(4)----XML基础知识
2012-05-12 15:33 8563引述要学习Spring框架的 ... -
学习Spring必学的Java基础知识(3)----PropertyEditor
2012-05-12 15:13 16853引述要学习Spring框架的 ... -
学习Spring必学的Java基础知识(2)----动态代理
2012-05-02 13:03 9730引述要学习Spring框架的 ... -
学习Spring必学的Java基础知识(1)----反射
2012-04-25 13:57 89828引述要学习Spring框架的技术内幕,必须事先掌握一些基本的J ... -
透透彻彻IoC(你没有理由不懂!)
2012-04-18 11:01 94231引述:IoC(控制反转:I ... -
单元测试系列之5:使用unitils测试Service层
2012-04-14 10:48 18477引述:Spring 的测试框架为我们提供一个强大的测试环境,解 ... -
如何用Spring读取JAR中的文件
2012-04-13 17:22 18407使用如下方式读取JAR中的文件出错 类路径下 ... -
单元测试系列之3:测试整合之王Unitils
2012-04-09 14:11 15689引述:程序测试对保障应用程序正确性而言,其重要性怎么样强调都不 ... -
单元测试系列之1:开发测试的那些事儿
2012-03-28 12:52 10021引述:程序测试对保障应用程序正确性而言,其重要性怎 ... -
单元测试的那些事儿
2012-03-28 12:48 2------------------------------- ... -
Spring 3.0的新功能
2012-03-26 09:30 71992009年9月发布Spring ... -
Spring的事务管理难点剖析(7):数据连接泄漏
2012-03-07 10:53 6857底层连接资源的访问问题 对于应用开发者来说,数据连接泄 ... -
Spring的事务管理难点剖析(6):特殊方法成漏网之鱼
2012-03-07 09:28 4545哪些方法不能实施Spring ... -
Spring的事务管理难点剖析(5):联合军种作战的混乱
2012-03-07 09:10 7891Spring事务管理器的应对 Spring抽象的DA ... -
Spring的事务管理难点剖析(4):多线程的困惑
2012-03-06 17:30 16929Spring通过单实例化Bean简化多线程问题 由于 ... -
Spring的事务管理难点剖析(3):事务方法嵌套调用的迷茫
2012-03-06 17:23 10610Spring事务传播机制回顾 ... -
Spring的事务管理难点剖析(2):应用分层的迷惑
2012-03-06 16:59 5122Web、Service及DAO三 ...
相关推荐
在Java开发领域,一个完整的应用通常分为多个层次,如表现层、业务逻辑层和服务层,以及数据访问层等。...通过这样的练习,开发者能够更好地理解和掌握Java SE在实际项目中的应用,提升其软件开发能力。
在实际项目中,"mybatis持久化dao生成工具"结合版本控制系统如Git,能够更好地追踪代码变更,便于团队协作。同时,结合持续集成/持续部署(CI/CD)流程,可以确保代码生成的质量和一致性。总之,这样的工具对于大型...
在Java开发中,数据库操作是不可或缺的一部分,而编写与之对应的实体类、DAO(Data Access Object)层以及各种查询方法通常是一项耗时的工作。"java-生成单表完全动态查询"这一技术就是为了简化这一过程,它能自动...
在Java开发中,数据访问对象(DAO)层是应用程序与数据库交互的重要部分。它负责将业务逻辑与数据存储分离,提供了一种抽象层,使得代码更易于维护和...通过理解这一过程,开发者可以更好地管理和优化他们的Java应用。
Struts的核心是MVC设计模式的应用,能够帮助开发者更好地组织代码结构,分离业务逻辑、展示逻辑与控制逻辑。 - **Spring**: Spring框架是一个开源的轻量级控制反转(IoC)和面向切面编程(AOP)容器。Spring提供了一种...
MyBatis 是一个流行的 Java 框架,用于简化数据库操作。它是一个半 ORM(对象关系映射)框架,其主要功能是将 Java 对象映射到数据库记录...每个 Dao 方法对应一个唯一的 MappedStatement,所以方法签名必须是唯一的。
1. **易用性**:Spring Data JPA通过方法签名的查询方式降低了学习曲线,而MyBatis需要编写SQL和映射文件。 2. **灵活性**:MyBatis在SQL定制方面更自由,适合处理复杂查询;Spring Data JPA则更适合简单的CRUD操作...
1. **接口的概念**:接口是一种抽象类型,它包含一组方法签名,但不提供具体的实现。在Java或C#等面向对象的语言中,接口用于定义对象必须实现的方法。这种方式可以确保不同的类遵循统一的规范,从而实现更好的协作...
- **探索Spring的异常处理机制**:Spring框架为处理各种常见的数据库异常提供了一套完整的机制,理解这些机制有助于更好地处理应用中的错误情况。 - **研究Spring的配置与注入机制**:理解如何通过Spring的依赖注入...
SpringData是Spring框架的一个重要模块,它为Java开发者提供了便捷的数据访问层的实现,涵盖了...通过深入研究和实践这些代码,开发者可以更好地掌握SpringData在实际项目中的应用,提升数据访问层的设计和实现能力。
虽然上述过程可以通过手动编写代码实现,但在实际开发中,我们通常会借助自动化工具,如Apache的Maven插件或Gradle插件,它们能更好地集成到现有项目构建流程中。例如,使用`maven-compiler-plugin`配合Freemarker,...
MyBatis是一个优秀的Java持久层框架,它支持定制化SQL、存储过程以及高级映射。在MyBatis中,映射数据库表是实现数据访问的关键步骤...理解并熟练掌握这些概念和机制,将有助于你更好地利用MyBatis进行数据访问和管理。
- **性能:**一般来说,MyBatis比Hibernate的性能更好,因为它允许进行更精细的SQL优化。 - **学习曲线:**Hibernate的学习曲线比MyBatis要陡峭,因为Hibernate更加强调抽象和封装。 **6. #{}和${}的区别是什么?**...
- **方法重载**:在MyBatis中不支持方法重载,因为调用接口方法时使用的是全限定类名+方法名作为key,无法区分相同的方法签名。 #### 10、Mybatis是如何进行分页的?分页插件的原理是什么? - **分页方式**:可以...
Spring Data JPA是Spring框架的一个模块,用于简化Java Persistence API(JPA)的使用,它提供了数据访问的抽象层,让开发者能够...记得不断探索和学习Spring Data JPA的更多高级功能,以便在实际项目中更好地利用它。
### JDBC学习文档精要 #### 一、JDBC概述与应用场景 **1.1 JDBC概念** JDBC(Java Database Connectivity)是一种用于执行SQL语句的标准Java...这将有助于开发者更好地理解和使用JDBC,从而提高开发效率和软件质量。
- **学习曲线**:Hibernate的学习曲线相对平缓,而MyBatis需要一定的SQL基础才能更好地利用其特性。 #### 二、MyBatis核心概念 1. **#{}和${}的区别:** - **#{}**是预编译处理,可以防止SQL注入攻击;而**${}**...
综上所述,Room为Android开发者提供了便利且强大的数据库操作工具,通过理解其基本概念和源码,能更好地在项目中运用,提升开发效率和代码质量。在实际开发中,结合Room与其他Jetpack组件,如LiveData和ViewModel,...
MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。...通过不断学习和实践,开发者可以更好地利用MyBatis解决各种数据访问问题。
更好的错误处理和几个重,机制来帮助获取数据无论如何你。 ?在通用和其他方法获得的数据,得到最好的利用您的CD / DVD - ROM驱动器的使用。 ?在小学和中学使用的文件系统获得的数据和/或使用的文件系统可能被忽略或'...