Space4J: MySqlUserDAO x Space4JUserDAO

3 respostas
saoj

Criei novos DAOs para a aplicaçao MyBooks usando o Space4J. Agora além de mysql o mybooks suporta também space4j, bastando para tal trocar as implementações dos DAOs (que são injetadas via IoC) no ApplicationManager.

A questão aqui é fazer um comparativo entre o approach usando banco de dados e o approach usando o Space4J. Também seria legal comparar com Hibernate ou JPA.

O objetivo é trocar idéias para chegar a uma conclusão se prevalência vale a pena ou não…

  • MySql:
package org.mybooks.dao.mysql;

import java.util.*;
import java.sql.*;

import org.mybooks.dao.*;
import org.mybooks.bean.*;

public class MySQLUserDAO implements UserDAO {
    
    private Connection conn = null;
    
    public MySQLUserDAO() { }
    
    public MySQLUserDAO(Connection conn) {
        this.conn = conn;
    }
    
    public void setConnection(Connection conn) {
        this.conn = conn;
    }
    
    public User loadById(int id) throws Exception {
        PreparedStatement stmt = null;
        ResultSet rset = null;
        try {
            stmt = conn.prepareStatement("select * from users where id = ?");
            stmt.setInt(1, id);
            rset = stmt.executeQuery();
            if (rset.next()) {
                User user = new User();
                user.setId(id);
                user.setUsername(rset.getString("username"));
                user.setPassword(rset.getString("password"));
                user.setName(rset.getString("name"));
                user.setEmail(rset.getString("email"));
                return user;
            }
        } finally {
            if (rset != null) try { rset.close(); } catch(Exception e) { }
            if (stmt != null) try { stmt.close(); } catch(Exception e) { }
        }
        return null;
    }
                
    public int insert(User user) throws Exception {
        PreparedStatement stmt = null;
        ResultSet rset = null;
        try {
            stmt = conn.prepareStatement("insert into users(username, password, name, email) values(?, ?, ?, ?)");
            stmt.setString(1, user.getUsername());
            stmt.setString(2, user.getPassword());
            stmt.setString(3, user.getName());
            stmt.setString(4, user.getEmail());
            stmt.executeUpdate();
            stmt.close();
            
            stmt = conn.prepareStatement("select last_insert_id() from users");
            rset = stmt.executeQuery();
            if (rset.next()) {
                int id = rset.getInt(1);
                user.setId(id);
                return id;
            }
        } finally {
            if (rset != null) try { rset.close(); } catch(Exception e) { }
            if (stmt != null) try { stmt.close(); } catch(Exception e) { }
        }            
        return -1; // should never be called...
    }
        
    public void update(User user) throws Exception {
        PreparedStatement stmt = null;
        try {
            stmt = conn.prepareStatement("update users set username = ?, password = ?, name = ?, email = ? where id = ?");
            stmt.setString(1, user.getUsername());
            stmt.setString(2, user.getPassword());
            stmt.setString(3, user.getName());
            stmt.setString(4, user.getEmail());
            stmt.setInt(5, user.getId());
            stmt.executeUpdate();
        } finally {
            if (stmt != null) try { stmt.close(); } catch(Exception e) { }
        }
    }
    
    public void delete(User user) throws Exception {
        PreparedStatement stmt = null;
        try {
            stmt = conn.prepareStatement("delete from users where id = ?");
            stmt.setInt(1, user.getId());
            stmt.executeUpdate();
        } finally {
            if (stmt != null) try { stmt.close(); } catch(Exception e) { }
        }
    }
    
    public User loadByUsername(String username) throws Exception {
        PreparedStatement stmt = null;
        ResultSet rset = null;
        try {
            stmt = conn.prepareStatement("select id from users where username = ?");
            stmt.setString(1, username);
            rset = stmt.executeQuery();
            int id = -1;
            if (rset.next()) {
                id = rset.getInt(1);
            }
            rset.close();
            stmt.close();
            
            if (id &gt 0) {
                return loadById(id);
            }
        } finally {
            if (rset != null) try { rset.close(); } catch(Exception e) { }
            if (stmt != null) try { stmt.close(); } catch(Exception e) { }
        }
        return null;
    }
                
    public User loadByEmail(String email) throws Exception {
        PreparedStatement stmt = null;
        ResultSet rset = null;
        try {
            stmt = conn.prepareStatement("select id from users where email = ?");
            stmt.setString(1, email);
            rset = stmt.executeQuery();
            int id = -1;
            if (rset.next()) {
                id = rset.getInt(1);
            }
            rset.close();
            stmt.close();
            
            if (id &gt 0) {
                return loadById(id);
            }
        } finally {
            if (rset != null) try { rset.close(); } catch(Exception e) { }
            if (stmt != null) try { stmt.close(); } catch(Exception e) { }
        }            
        return null;
    }
    
    public List searchUsersByName(List keywords, boolean and) throws Exception {
        return searchUsersByName(keywords, and, -1);
    }
    
    public List searchUsersByName(List keywords, boolean and, int max) throws Exception {
        Statement stmt = null;
        ResultSet rset = null;
        try {
            
            StringBuffer sb = null;
            
            if (keywords == null || keywords.size() == 0) {
                sb = new StringBuffer("select id from users order by name");
            } else {
                sb = new StringBuffer(50 + 40 * keywords.size());
                sb.append("select id from users where");
                
                Iterator iter = keywords.iterator();
                int index = 0;
                while(iter.hasNext()) {
                    String token = (String) iter.next();
                    if (index++ != 0) sb.append(and ? " and" : " or");
                    sb.append(" lower(name) like '%").append(token.toLowerCase()).append("%'");
                }
                
                sb.append(" order by name");
                
                if (max &gt 0) {
                    sb.append(" limit ").append(max);
                }
            }
            
            stmt = conn.createStatement();
            rset = stmt.executeQuery(sb.toString());
            List ids = new LinkedList();
            while(rset.next()) {
                ids.add(new Integer(rset.getInt(1)));
            }
            rset.close();
            stmt.close();
            
            List users = new ArrayList(ids.size());
            Iterator iter = ids.iterator();
            while(iter.hasNext()) {
                Integer id = (Integer) iter.next();
                User user = loadById(id.intValue());
                users.add(user);
            }
            return users;
        } finally {
            if (rset != null) try { rset.close(); } catch(Exception e) { }
            if (stmt != null) try { stmt.close(); } catch(Exception e) { }
        }
    }    
}
  • Space4J:
package org.mybooks.dao.space4j;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.mybooks.bean.User;
import org.mybooks.dao.UserDAO;
import org.space4j.Space;
import org.space4j.Space4J;
import org.space4j.command.CreateMapCmd;
import org.space4j.command.PutCmd;
import org.space4j.command.RemoveCmd;
import org.space4j.indexing.Index;
import org.space4j.indexing.IndexManager;
import org.space4j.indexing.Key;

public class Space4JUserDAO implements UserDAO {
	
	private static final String MAP_USERS = "users";
	
	private static final String INDX_USERNAME = "indx_username";
	
	private static final String INDX_EMAIL = "indx_email";
    
    private Space4J space4j = null;
    
    public Space4JUserDAO() { }
    
    public Space4JUserDAO(Space4J space4j) {
        this.space4j = space4j;
    }
    
    public void setSpace4j(Space4J space4j) {
    	
    	this.space4j = space4j;
    	
    	Space space = space4j.getSpace();
    	
    	if (!space.check(MAP_USERS)) {
    		
    		try {
    		
    			space4j.exec(new CreateMapCmd<Integer, User>(MAP_USERS));
    			
    		} catch(Exception e) {
    			
    			e.printStackTrace();
    			
    			throw new RuntimeException("Cannot create map: " + MAP_USERS, e);
    		}
    		
    	}
    	
    	IndexManager im = space4j.getIndexManager();

    	// create index by username...
        if (!im.checkIndex(INDX_USERNAME)) {
        	
        	Index indx = new Index(INDX_USERNAME, MAP_USERS, Index.TYPE.REGULAR, User.class, "username");
        	
        	try {
        	
        		im.createIndex(indx, space4j);
        		
        	} catch(Exception e) {
        		
        		e.printStackTrace();
        		
        		throw new RuntimeException("Cannot create index: " + INDX_USERNAME, e);
        	
        	}
            
        }
        
        if (!im.checkIndex(INDX_EMAIL)) {

        	Index indx = new Index(INDX_EMAIL, MAP_USERS, Index.TYPE.REGULAR, User.class, "email");
        	
        	try {
        	
        		im.createIndex(indx, space4j);
        		
        	} catch(Exception e) {
        		
        		e.printStackTrace();
        		
        		throw new RuntimeException("Cannot create index: " + INDX_EMAIL, e);
        	}
        	
        }

    }
    
    public User loadById(int id) throws Exception {
    	
    	Space space = space4j.getSpace();
    	
    	Map map = (Map) space.get("users");
    	
    	if (map == null) return null;
    	
    	return (User) map.get(id);
    	
    }
                
    public int insert(User user) throws Exception {
    	
    	int id = space4j.getNextSeq("users_id_seq"); // will create if sequence does not exist...
    	
    	user.setId(id);
    	
    	int x = space4j.exec(new PutCmd(MAP_USERS, id, user));
    	
    	return x;
    }
        
    public void update(User user) throws Exception {
    	
    	space4j.exec(new PutCmd(MAP_USERS, user.getId(), user));
    	
    }
    
    public void delete(User user) throws Exception {
    	
    	space4j.exec(new RemoveCmd(MAP_USERS, user.getId()));

    }
    
    public User loadByUsername(String username) throws Exception {
    	
    	IndexManager im = space4j.getIndexManager();
    	
    	Index index = im.getIndex(INDX_USERNAME);
    	
    	Map map = (Map) index.getMap();
    	
    	return (User) map.get(username);
    	
    }
                
    public User loadByEmail(String email) throws Exception {
    	
    	IndexManager im = space4j.getIndexManager();
    	
    	Index index = im.getIndex(INDX_USERNAME);
    	
    	Map map = (Map) index.getMap();
    	
    	return (User) map.get(email);
        
    }
    
    public List searchUsersByName(List keywords, boolean and) throws Exception {
        return searchUsersByName(keywords, and, -1);
    }
    
    /*
     * How to index something like this: name like '%carlos%' ????
     * 
     * Is it a full table scan?
     * 
     * Doing a full table scan using space4j...
     */
    public List searchUsersByName(List keywords, boolean and, int max) throws Exception {
    	
    	Space space = space4j.getSpace();
    	
    	if (!space.check(MAP_USERS) || max == 0) new ArrayList(0);
    	
    	Iterator iter = space.getSafeIterator(MAP_USERS);
    	
    	Map<String, User> sorted = new TreeMap<String, User>();
    	
    	while(iter.hasNext()) {
    		
    		User u = (User) iter.next();
    		
    		String name = u.getName().toLowerCase();
    		
    		boolean matches = true;
    		
    		if ((keywords == null || keywords.size() == 0)) {
    			
    			matches = true; // list everything...
    			
    		} else if (and) { // AND LOGIC
    			
    			Iterator iter2 = keywords.iterator();
    			
    			while(iter2.hasNext()) {
    				
    				String keyword = ((String) iter2.next()).toLowerCase();
    				
    				if (name.indexOf(keyword) == -1) {
    					
    					matches = false;
    					
    					break;
    				}
    			}
    			
    		} else { // OR LOGIC
    			
    			Iterator iter2 = keywords.iterator();
    			
    			matches = false;
    			
    			while(iter2.hasNext()) {
    				
    				String keyword = ((String) iter2.next()).toLowerCase();
    				
    				if (name.indexOf(keyword) != -1) {
    					
    					matches = true;
    					
    					break;
    				}
    			}
    		}
    		
    		// check max...
    		
    		if (matches) {
    			
    			sorted.put(name, u);
    			
    			if (max &gt 0 && sorted.size() == max) break;
    			
    		}
    	}
    	
    	List<User> results = new ArrayList<User>(sorted.size());
    	
    	Iterator<User> iter3 = sorted.values().iterator();
    	
    	while(iter3.hasNext()) {
    		
    		results.add(iter3.next());
    		
    	}
    	
    	return results;
    }    
}

3 Respostas

pcalcado

Impressão minha ou o controle de transação está no DAO? Uma transação é fisicamente diferente no Space4J mas o conceito é o mesmo, não?

saoj

Não está no DAO não. Onde vc viu isso?

saoj

Vc diz pegar a sequence e inserir o objeto (duas operações).

Acho que isso aí não precisa estar numa transaçao…

Até porque sequence não tem rollback…

Criado 28 de fevereiro de 2007
Ultima resposta 28 de fev. de 2007
Respostas 3
Participantes 2