我的漫漫程序之旅

专注于JavaWeb开发
随笔 - 39, 文章 - 310, 评论 - 411, 引用 - 0
数据加载中……

Spring2.5 jdbc Annotation 事务配置

1.对异常的处理
      spring中提供了DataAccessException,这个异常类是对现有多数据库抛出异常的封装,并可以对不同数据库抛出异常的状态码进行解释。因此,在业务层中方法声明throws DataAccessException,可以不必担心抛出我们没有捕获到的数据库操作异常,把精力放在“业务异常”上面。
 
2.模板类
      spring设计为了更好的管理异常、事务,避免业务方法中重复的try/catch块,设计出模板类,最重要的两个为JdbcTemplate,HibernateTemplate,spring的模板类都是线程安全的,由ThreadLocal进行资源管理。
 
      使用JdbcTemplate必须注入DateSource通过构造方法注入。例:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop
="http://www.springframework.org/schema/aop"
    xmlns:jee
="http://www.springframework.org/schema/jee"
    xmlns:tx
="http://www.springframework.org/schema/tx"
    xmlns:context
="http://www.springframework.org/schema/context"
    xsi:schemaLocation
="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
    default-lazy-init
="true">

    
<description>Spring公共配置文件</description>

    
<!-- 定义受环境影响易变的变量 -->
    
<bean
        
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        
<property name="systemPropertiesModeName"
            value
="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
        
<property name="ignoreResourceNotFound" value="true" />
        
<property name="locations">
            
<list>
                
<!-- 标准配置 -->
                
<value>classpath:config/application.properties</value>
                
<!-- 服务器生产环境配置 -->
                
<!-- <value>file:/var/myapp/application.server.properties</value> -->
            
</list>
        
</property>
    
</bean>

    
<context:annotation-config />

    
<!-- 使用annotation 自动注册bean,并保证@Required,@Autowired的属性被注入 -->
    
<context:component-scan
        
base-package="org.eline.dao,org.eline.service,orm.CoreJdbcSupport;" />

    
<!-- 数据源配置,使用应用内的DBCP数据库连接池 -->
    
<bean id="dataSource"
        class
="org.apache.commons.dbcp.BasicDataSource"
        destroy-method
="close">
        
<!-- Connection Info -->
        
<property name="driverClassName" value="${jdbc.driver}" />
        
<property name="url" value="${jdbc.url}" />
        
<property name="username" value="${jdbc.username}" />
        
<property name="password" value="${jdbc.password}" />

        
<!-- Connection Pooling DBCP -->
        
<property name="initialSize" value="5" />
        
<property name="maxActive" value="100" />
        
<property name="maxIdle" value="30" />
        
<property name="maxWait" value="1000" />
        
<property name="poolPreparedStatements" value="true" />
        
<property name="defaultAutoCommit" value="false" />
    
</bean>
    
<!-- 为dao操作模型设置数据源 -->
    
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        
<constructor-arg><ref bean="dataSource"/></constructor-arg>
     
</bean>
     
     
<bean id="simpleJdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
        
<constructor-arg><ref bean="dataSource"/></constructor-arg>
     
</bean>
     
    
<bean id="jdbcDaoSupport" class="org.springframework.jdbc.core.support.JdbcDaoSupport">
       
<property name="jdbcTemplate"><ref bean = "jdbcTemplate"/></property>
    
</bean>
    
<!-- 声明事务,自动管理配置数据源 -->
    
<bean id="transactionManager"
        class
="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        
<property name="dataSource">
            
<ref local="dataSource" />
        
</property>
    
</bean>

    
<!-- 用注解来实现事务管理 -->
    
<tx:annotation-driven transaction-manager="transactionManager" />

</beans>

jdbcTemplate,simpleJdbcTeplate 用法:
**
 
* 封闭Spring JDBC的核心基类
 
* 
 
* 无需关心数据库连接的开启和关闭,封闭常用CRUD方法,简化应用
 
* 
 
* @author zdw
 
* 
 
*/
@SuppressWarnings(
"unchecked")
public abstract class CoreJdbcSupport
{
    @Autowired
    
protected JdbcTemplate jdbcTemplate;
    @Autowired
    
protected SimpleJdbcTemplate simpleJdbcTemplate;

    
/**
     * 高效率的oracle分页sql
     * 
     * 
@param querySql
     *            查询语句
     * 
@param countSql
     *            统计语句
     * 
@param pageNo
     *            当前页
     * 
@param pageSize
     *            页大小
     * 
@param clazz
     *            要自动赋值的实体类
     * 
@return
     
*/

    
protected Page pageQuery(String querySql, String countSql, int pageNo,
            
int pageSize, Class clazz)
    
{
        
// 设置page信息
        Page page = new Page();
        page.setPageNo(pageNo);
        page.setPageSize(pageSize);
        
// 统计总记录数
        int size = jdbcTemplate.queryForInt(countSql);
        page.setTotalCount(size);
        List list 
= this.simpleJdbcTemplate.query(querySql,
                ParameterizedBeanPropertyRowMapper.newInstance(clazz),
                page.getLast(), page.getFirst());
        
// 设置结果集
        page.setResult(list);
        
return page;
    }


    
/**
     * 分页查询,不需要自动set值
     * 
     * 
@param querySql
     * 
@param countSql
     * 
@param pageNo
     * 
@param pageSize
     * 
@return
     
*/

    
protected Page pageQuery(String querySql, String countSql, int pageNo,
            
int pageSize)
    
{
        
// 设置page信息
        Page page = new Page();
        page.setPageNo(pageNo);
        page.setPageSize(pageSize);
        
// 统计总记录数
        int size = this.jdbcTemplate.queryForInt(countSql);
        page.setTotalCount(size);
        List list 
= this.simpleJdbcTemplate.queryForList(querySql,
                page.getLast(), page.getFirst());
        
// 设置结果集
        page.setResult(list);
        
return page;
    }


    
/***************************************************************************
     * 主要用于更新操作的自动匹配列
     * 
     * 
@param obj
     *            对象实体
     * 
     
*/

    
protected List<String> getCols(Object obj)
    
{
        List
<String> list = new ArrayList<String>();
        Class c 
= obj.getClass();
        Field fileds[] 
= c.getDeclaredFields();
        
try
        
{
            
for (int i = 0; i < fileds.length; i++)
            
{
                Field f 
= fileds[i];
                f.setAccessible(
true);
                
if (f.get(obj) != null)
                
{
                    list.add(
" " + f.getName() + "=:" + f.getName());
                }

            }

        }

        
catch (Exception e)
        
{
            e.printStackTrace();
        }

        
return list;
    }


    
/***************************************************************************
     * 主要用于更新操作的自动匹配列
     * 
     * 
@param obj
     *            对象实体
     * 
@param flag
     *            是否忽略整形值0
     * 
     
*/

    
protected List<String> getCols(Object obj, boolean flag)
    
{
        List
<String> list = new ArrayList<String>();
        Class c 
= obj.getClass();
        Field fileds[] 
= c.getDeclaredFields();
        
try
        
{
            
for (int i = 0; i < fileds.length; i++)
            
{
                Field f 
= fileds[i];
                f.setAccessible(
true);
                
if (flag)
                
{
                    
if (f.get(obj) != null)
                    
{
                        
if (Integer.valueOf(f.get(obj).toString()) != 0)
                        
{
                            list.add(
" " + f.getName() + "=:" + f.getName());
                        }

                    }

                }

                
else
                
{
                    
if (f.get(obj) != null)
                    
{
                        list.add(
" " + f.getName() + "=:" + f.getName());
                    }

                }

            }

        }

        
catch (Exception e)
        
{
            e.printStackTrace();
        }

        
return list;
    }


    
/**
     * 
     * 
@param obj
     *            要更新的对象
     * 
@param tableName
     *            表名称
     * 
@param sid
     *            标识列名称
     * 
@return
     
*/

    
protected String getUpdateSql(Object obj, String tableName, String sid)
    
{
        List
<String> cols = this.getCols(obj);
        String sql 
= StringUtils.join(new String[]
        
"update " + tableName + " set ",
                StringUtils.join(cols.toArray(), 
","),
                
" where " + sid + "=:" + sid + "" }
);
        
return sql;
    }


}


dao:
package org.eline.dao.user;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import org.eline.vo.User;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import orm.CoreJdbcSupport;
import orm.Page;
import utils.MD5Utils;

/**
 * 用户管理DAO
 * 
 * 
@author zdw
 * 
 
*/

@Repository
@SuppressWarnings(
"unchecked")
@Transactional
public class UserDao extends CoreJdbcSupport
{
    
/**
     * 用户登录的方法
     * 
     * 
@param username
     *            用户名
     * 
@param password
     *            密码
     * 
@return
     
*/

    
public int login(String username, String password)
    
{
        
// 转换成md5形式
        password = MD5Utils.getInstance().getMD5ofStr(password);
        String sql 
= "select count(userid) from usr_user where username = ? and password = ?";
        
return simpleJdbcTemplate.queryForInt(sql, username, password);
    }

    
    
    
/**
     * 添加用户的方法
     * 
     * (注意sql语句的写法和new BeanPropertySqlParameterSource(user)直接把bean转成输入参数)
     * 
     * 
@param user
     *            用户实体
     * 
@return
     
*/

    
public int save(User user)
    
{
        String sql 
= "insert into usr_user(userid,username,password) values(:userid,:username,:password)";
        
return this.simpleJdbcTemplate.update(sql,
                
new BeanPropertySqlParameterSource(user));
    }


    
/**
     * 修改用户的方法
     * 
     * 
@param user
     *            用户实体
     * 
@return
     
*/

    
public int update(User user)
    
{
        
// 获取要更新的列,null值不更新,保留原值
        String sql = this.getUpdateSql(user, "usr_user""userid");
        
return this.simpleJdbcTemplate.update(sql,
                
new BeanPropertySqlParameterSource(user));
    }


    
/**
     * 删除用户的方法
     * 
     * 
@param id
     *            要删除的用户id
     * 
@return
     
*/

    
public int delete(int userid)
    
{
        
// ? 也可写成:userid的形式
        String sql = "delete from usr_user where userid = ?";
        
return this.simpleJdbcTemplate.update(sql, userid);
    }


    
/**
     * 查询用户名是否存在
     * 
     * 
@return
     
*/

    
public boolean exist(String username)
    
{
        String sql 
= "select count(userid) from usr_user where username = ?";
        
int rows = this.simpleJdbcTemplate.queryForInt(sql, username);
        
return rows > 0 ? true : false;
    }


    
/**
     * 查询单个用户
     * 
     * 
@param userid
     *            用户id
     * 
@return
     
*/

    
public User queryOne(int userid)
    
{
        String sql 
= "select * from usr_user where userid = ?";
        
return this.simpleJdbcTemplate.queryForObject(sql,
                ParameterizedBeanPropertyRowMapper.newInstance(User.
class),
                userid);
    }


    
/**
     * 查询多个用户
     * 
     * 
@param userid
     *            用户id
     * 
@return
     
*/

    
public List<User> queryList()
    
{
        
return this.simpleJdbcTemplate.query("SELECT * from usr_user",
                ParameterizedBeanPropertyRowMapper.newInstance(User.
class));
    }


    
/**
     * oracle分页sql
     * 
     * 
@param currentNum
     *            第几页
     * 
@param pagesize
     *            页大小
     * 
@return
     
*/

    
public Page pageQuery(int pageNo, int pageSize)
    
{
        String querySql 
= "SELECT * FROM(SELECT A.*, ROWNUM RN  FROM (SELECT * FROM usr_user) A  WHERE ROWNUM <= ?) WHERE RN >= ?";
        String countSql 
= "select count(userid) from usr_user";
        
return this.pageQuery(querySql, countSql, pageNo, pageSize, User.class);
    }


    
public static void main(String[] args) throws Exception
    
{
        User user 
= new User();
        user.setUserid(
3);
        user.setUsername(
"angle");
        user.setPassword(
"admin");
        List list 
= new ArrayList();
        Class c 
= User.class;
        Field fileds[] 
= c.getDeclaredFields();
        
for (int i = 0; i < fileds.length; i++)
        
{
            Field f 
= fileds[i];
            f.setAccessible(
true);
            
if (f.get(user) != null)
            
{
                list.add(
" " + f.getName() + "=:" + f.getName());
                System.out.println(
" " + f.getName() + "=:" + f.getName());
            }

        }


    }

    
}


网上关于怎么配置和使用的大多记录不全,特在此mark一下。


posted on 2009-04-14 10:05 々上善若水々 阅读(4359) 评论(6)  编辑  收藏 所属分类: Spring

评论

# re: Spring2.5 jdbc Annotation 事务配置  回复  更多评论   

你好,请把page类发给我,谢谢。ly0318@gmail.com
2009-04-21 21:12 | ly

# re: Spring2.5 jdbc Annotation 事务配置  回复  更多评论   

@ly
已发
2009-04-22 09:34 | 々上善若水々

# re: Spring2.5 jdbc Annotation 事务配置  回复  更多评论   

写得太好了 我正在学习这方面的东西
2009-10-22 17:42 | 我爱EE

# re: Spring2.5 jdbc Annotation 事务配置  回复  更多评论   

事务倒是配置了,但哪段代码使用事务了?
2011-06-02 08:58 | 黄山

# re: Spring2.5 jdbc Annotation 事务配置  回复  更多评论   

很细致,感谢楼主的发帖了。 又学到了。
近来在做一个跨3个数据库的项目,在学怎么用这个spring jdbctemaplate 跨多数据库 ,可是总是出错。 楼主如果可以的话,指导下。 我QQ286250574 邮箱lqmoai@163.com
2011-06-17 21:56 | 今夜有点冷

# re: Spring2.5 jdbc Annotation 事务配置  回复  更多评论   

发觉回滚不了。
2011-09-03 17:03 | canca

只有注册用户登录后才能发表评论。


网站导航: