001    /*
002     * Copyright 2010 the original author or authors.
003     * 
004     *  Licensed under the Apache License, Version 2.0 (the "License");
005     *  you may not use this file except in compliance with the License.
006     *  You may obtain a copy of the License at
007     *
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     *
010     *  Unless required by applicable law or agreed to in writing, software
011     *  distributed under the License is distributed on an "AS IS" BASIS,
012     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     *  See the License for the specific language governing permissions and
014     *  limitations under the License.
015     */
016    package com.hs.mail.imap.dao;
017    
018    import org.apache.commons.lang.StringUtils;
019    import org.springframework.dao.DataAccessException;
020    import org.springframework.dao.EmptyResultDataAccessException;
021    import org.springframework.jdbc.core.RowMapper;
022    import org.springframework.jdbc.core.support.JdbcDaoSupport;
023    
024    /**
025     * Convenient super class for JDBC-based data access objects.
026     * 
027     * @author Won Chul Doh
028     * @since Feb 11, 2010
029     *
030     */
031    public abstract class AbstractDao extends JdbcDaoSupport {
032    
033            /**
034             * Query given SQL to create a prepared statement from SQL and a list of
035             * arguments to bind to the query, mapping a single result row to a Java
036             * object via a RowMapper.
037             * 
038             * @param sql
039             *            SQL query to execute
040             * @param args
041             *            arguments to bind to the query (leaving it to the
042             *            PreparedStatement to guess the corresponding SQL type)
043             * @param rowMapper
044             *            object that will map one object per row
045             * @return the single mapped object or null if the query does not return any
046             *         row
047             * @throws DataAccessException
048             *             if the query fails
049             */
050            protected Object queryForObject(String sql, Object[] args, RowMapper rowMapper) throws DataAccessException {
051                    try {
052                            return getJdbcTemplate().queryForObject(sql, args, rowMapper);
053                    } catch (EmptyResultDataAccessException ex) {
054                            return null;
055                    }
056            }
057    
058            /**
059             * Query given SQL to create a prepared statement from SQL and a list of
060             * arguments to bind to the query, resulting in a long value. The query is
061             * expected to be a single row/single column query that results in a long
062             * value.
063             * 
064             * @param sql
065             *            SQL query to execute
066             * @param args
067             *            arguments to bind to the query (leaving it to the
068             *            PreparedStatement to guess the corresponding SQL type)
069             * @return the long value, or 0 in case of SQL NULL or if the query does not
070             *         return any row
071             * @throws DataAccessException
072             *             if query fails
073             */
074            protected long queryForLong(String sql, Object[] args) throws DataAccessException {
075                    try {
076                            return getJdbcTemplate().queryForLong(sql, args);
077                    } catch (EmptyResultDataAccessException ex) {
078                            return 0;
079                    }
080            }
081    
082            /**
083             * Query given SQL to create a prepared statement from SQL and a list of
084             * arguments to bind to the query, resulting in an int value. The query is
085             * expected to be a single row/single column query that results in an int
086             * value.
087             * 
088             * @param sql
089             *            SQL query to execute
090             * @param args
091             *            arguments to bind to the query (leaving it to the
092             *            PreparedStatement to guess the corresponding SQL type)
093             * @return the int value, or 0 in case of SQL NULL or if the query does not
094             * @throws DataAccessException
095             *             if query fails
096             */
097            protected int queryForInt(String sql, Object[] args) throws DataAccessException {
098                    try {
099                            return getJdbcTemplate().queryForInt(sql, args);
100                    } catch (EmptyResultDataAccessException ex) {
101                            return 0;
102                    }
103            }
104    
105            protected static String escape(String param) {
106                    return StringUtils.replace(StringUtils.replace(param, "_", "\\_"), "%",
107                                    "\\%");
108            }
109            
110            protected static String duplicate(String[] fields, Object[] params,
111                            int start) {
112                    StringBuffer buffer = new StringBuffer("(");
113                    for (int i = 0; i < fields.length; i++) {
114                            if (i > 0)
115                                    buffer.append(",");
116                            buffer.append("?");
117                            params[i + start] = fields[i];
118                    }
119                    buffer.append(")");
120                    return buffer.toString();
121            }
122            
123    }