引发这个问题的代码是我公司代码库中的一个服务,其中包含四个不同的DAO.在我看到这个服务已经与属于完全不同的服务的方法混淆之前,我没有想太多.在此服务中创建这些无根据的方法的原因仅仅是因为所需的DAO是此Service类的私有成员.
这个开发人员是不正当的,或者在大多数情况下每个服务类有多个DAO是不对的?
注意:我注意到每个Service类有多个DAO似乎是合理的,只要它们都包含在同一个数据库中.但是从多个数据库中获取DAO似乎可能会导致问题.
我有一个问题,正确处理我正在为一个项目编写的DAO库的返回.这个库可能会被其他人使用,我想要正确地使用它.我应该如何处理DAO功能的返回声明?
示例1 我有getCustomer函数应该返回String.如果查询没有返回任何结果,我应该返回null,空字符串或抛出某种异常?
示例2
我有一个函数,getCutomerList它返回ArrayList <String>类型的值.如果查询没有返回任何结果我应该返回null,一个空的ArrayList或抛出一些异常?
示例3
检测到一些SQL异常,我应该怎么做,抛出异常或执行可能发生的块的try..catch
在我的案例中适用的"好"做法或"最佳"做法是什么?
我已经看过并使用过很多基于JDBC的旧代码,这些代码通常都是以CRUD方法开始的.我的问题特别涉及检索方法或"发现者".通常我发现DAO开始时有两种方法:
通常情况下,这两个发现者是不够的.我通常最终会看到一个DAO类被反复修改以添加如下所示的finder方法:
当需要支持新的{conditions}或修改现有方法以添加新参数作为标志来修改方法内的SQL查询以支持其他条件时,会发生更多方法.
这是一种丑陋的方法,违反了开放封闭原则.每当需要支持一些新的检索条件时,看到DAO类不断修改,这一直是我的一个难得.对这个问题的研究经常指向Repository Pattern和封装条件,以便将其作为规范或查询对象进行检索,然后将它们传递给finder方法.但是,如果你有一个整个数据集的内存集合,或者你正在使用某种ORM(我正在使用旧的JDBC代码),这似乎是可行的.
我已经考虑过延迟加载整个数据集的解决方案,DAO作为内存中的集合进行管理,然后使用规范模式作为检索查询.然后我在集合上实现某种观察器,它只是在调用创建,更新或删除方法时更新数据库.但显然性能和可扩展性受到严重影响.
有什么想法吗?
感谢您到目前为止的回复.我有一个想法 - 您对使用命令/策略模式封装数据访问请求有何看法?每个单独的Concrete Command都可以表示特定类型的访问,并且可以传递给Invoker.我最终得到了许多具体的Command Command类,但是每一个都只关注一种访问,应该是非常可测试和隔离的.
public abstract class Command<R>{
public <R> execute();
public void setArguments(CommandArguments args){
//store arguments
}
}
//map based structure for storing and returning arguments
public class CommandArguments{
public String getAsString(String key);
public String getAsInt(String key);
//... others
}
//In some business class...
Command command = CommandFactory.create("SearchByName");
CommandArguments args = new CommandArguments();
args.setValue("name", name);
// others
command.setArguments(args);
List<Customer> list = command.execute();
Run Code Online (Sandbox Code Playgroud) 我总是面临一个问题,我无法真正想到封装了许多DAO方法的服务对象.
我的意思是,对于我的servlet,有时使用单个DAO方法就足够了,例如addUser(User params).
更好的做法是 - 使用服务对象封装DAO方法并仅使用服务对象,即使它实际上意味着单个服务方法调用单个dao方法或将它们的使用混合在一起(来自服务对象的一些方法和来自servlet中的dao的一些方法)上下文) - 意味着我在控制器内部自动装配了DAO和Service对象?
如果我开始在同一个地方同时使用DAO和Service对象,它会混淆逻辑吗?
我正在使用JDBC(没有Spring,Hibernate或其他任何东西)在Java中编写一些简单的DAO.
将实现DAO放在与其接口相同的包中还是将它们放在子包中更好?
例:
com.mycompany.myproject.dao.MyDao
com.mycompany.myproject.dao.MyDaoImpl
Run Code Online (Sandbox Code Playgroud)
要么
com.mycompany.myproject.dao.MyDao
com.mycompany.myproject.dao.impl.MyDaoImpl
Run Code Online (Sandbox Code Playgroud)
如果你建议子包结构,你会建议什么作为子包名?.impl?.SQL?.jdbc?
实际上,我不会有多个实现.我是否过度设计了这个?
我在数据访问对象中有一个Java方法.这个非常简单的方法将两个整数值插入数据库.
public void saveHourMin(int hour, int min) throws SQLException{
psInsert.setInt(1, hour);
psInsert.setInt(2, min);
psInsert.executeUpdate();
}
Run Code Online (Sandbox Code Playgroud)
这个方法,或者一般来说,任何DAO方法,抛出SQLException时是抛出异常,还是应该捕获并记录异常,然后通过返回代码通知用户?使用Spring的应用程序的正确方法是什么?
我知道最佳做法是同时使用service和dao层,并在服务级别添加@Transactional注释.但在我的情况下,这意味着我的大多数服务类都是为了重复DAO方法而创建的......这非常令人恼火.
例如.
public interface FooDAO {
public List<FooVO> list(int cathegoryId);
public List<FooVO> list(int cathegoryId, int ownerId);
}
@Service
@Transactional
public class FooService {
protected @Autowired FooDAO dao;
public List<FooVO> list(int cathegoryId) {
dao.list(cathegoryId);
}
public List<FooVO> list(int cathegoryId, int authorId) {
dao.list(cathegoryId, authorId)
}
}
Run Code Online (Sandbox Code Playgroud)
那是多么愚蠢?
在大多数情况下,我真的不需要花哨的服务方法,因为通常这是一个例如.导管描述和与导管相匹配的实体列表.这就是为什么我在寻找简化的解决方案.像使用泛型来避免重复DAO一样辉煌:D http://www.javablog.fr/javahibernate-dont-repeat-the-dao-with-a-genericdao.html
我找到了答案.其中我读过 @Transactional注释属于哪里? 但仍然没有找到我的答案.
所以我想知道用@Transactional注释DAO方法真是个坏主意.灵感来自http://www.baeldung.com/2011/12/26/transaction-configuration-with-jpa-and-spring-3-1/#apistrategy我找到了一个解决方案.
如果:
**更新1**
它看起来像这样:
public interface FooDAO {
@Transactional(propagation = Propagation.MANDATORY, readOnly=true)
public List<FooVO> list(int cathegoryId);
...
}
@Service
public class …Run Code Online (Sandbox Code Playgroud) 我有以下带有查询的 DAO:
@Dao
public interface BaseballCardDao {
@Query(
"SELECT * FROM baseball_cards " +
"WHERE brand LIKE :brand " +
" AND year = :year " +
" AND number LIKE :number " +
" AND player_name LIKE :playerName " +
" AND team LIKE :team"
)
LiveData<List<BaseballCard>> getBaseballCards(
String brand, int year, String number, String playerName, String team
);
}
Run Code Online (Sandbox Code Playgroud)
该String参数是在意义上的“可选”我可以通过"%%"匹配所有行,由于LIKE运营商。但我不能这样做,year因为它是一个int. 一种解决方案是添加两种不同的@Query方法,一种带int year参数,另一种不带。有没有更优雅的方法来创建带有 Room 的可选参数 …
我在PHP中使用DAO模式.我理解以这种方式分离模型所带来的好处,但我不明白的是,当表通过关联实体关联时,您应该如何构建DAO和VO?
我举个例子:
在我的数据库中我有
USERS(id,username);
USERS_POSTS(id_user(FK),id_post(FK));
POSTS(id, title);
USER_COMMENTS(id_user(Fk),id_post(FK));
COMMENTS(id, text);
Run Code Online (Sandbox Code Playgroud)
我使用相应的setter和getter 创建UserVO,PostVO,然后负责最终返回VO的SQL的UserDAO和PostDAO.对来自这些表的数据执行CRUD操作非常简单,但是当您开始考虑关联表并检索跨不同表的数据时,您开始认为使用DAO不再那么简单了......
如果您想要返回文章作者的所有评论,您将如何组织DAO模式?我不需要SQL查询我只是将此作为实际情况的一个例子...
我读到,为每个关联表提供关联DAO和Vo是个好主意.它的VO会包含什么?只有2个外键或来自两个表的所有属性?
如果逻辑具有关联实体的DAO和VO,那么如果查询"通过"多于3个表(使用2个关联实体),那么解决方案是什么?
我怀疑DAO模式会有一个名为users_posts_comments_article的对象:)))
谢谢
假设我有这个模型.(为了演示目的,我非常简单.)
class User
{
public $id;
public $email;
public $password;
public $errors = [];
public function isValid()
{
if (strpos($this->email, '@') === false) {
$this->errors['email'] = 'Please enter an email address';
}
// ...
return !$this->errors;
}
}
Run Code Online (Sandbox Code Playgroud)
让我们说我有这个DAO用于检索,添加,更新和删除用户.
class UserDAO
{
public function getUsers() { ... }
public function getUserById($id) { ... }
public function addUser(User $user) { ... }
public function updateUser(User $user) { ... }
public function deleteUser($id) { ... }
public function isEmailUnique($email) { ... } …Run Code Online (Sandbox Code Playgroud) dao ×10
java ×7
spring ×3
php ×2
android ×1
android-room ×1
annotations ×1
api-design ×1
architecture ×1
behavior ×1
finder ×1
java-ee ×1
mysql ×1
service ×1
sql ×1
transactions ×1
validation ×1