当前位置:编程学习 > JAVA >>

使用springJdbc遇到的问题

使用spring jdbc的时候遇到个问题。。

我想通过这种方法进行批量插入。。
但是baseDao.update(sql, params);每执行一次就自动提交了。。
我也发现了问题所在。。我所设置的Connection和baseDao.update使用的Connection不是同一个。。
spring不是默认把connection放入ThreadLocal么。。
即一个线程中使用同一个connection..为啥我设置的connection还不是同一个
望前辈指教.

你们怎么用spring做批量插入的?
加事物我也可以实现的。

但是我想用原始的setAutoCommit(false)啊。。
难道spring不支持么 --------------------编程问答-------------------- baseDao代码看看啊? --------------------编程问答-------------------- “我所设置的Connection和baseDao.update使用的Connection不是同一个。。”
你都知道原因,还不知道怎么改?

直接把DataSourceUtils.getConnection(baseDao.getDataSource()) 抽出来放在一个变量里面,然后设置自动提交和批量update时都使用这个变量不就行了 --------------------编程问答--------------------
引用 1 楼 oh_Maxy 的回复:
baseDao代码看看啊?

代码如下:

package insert;

import java.text.ParseException;

import javax.annotation.Resource;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

@Component("baseDao")
public class BaseDao {

@Resource
    private JdbcTemplate jdbcTemplate;
@Autowired
@Qualifier("dataSource")
    private DataSource dataSource;

    // 查最大数字
    public int findMaxNum(String sql) {
        return getJdbcTemplate().queryForInt(sql);
    }

    // 查最大g_id,应用从900000开始,游戏从1000000开始
    public int findMaxGid(String sql,int game_type) {
//        if(game_type==33){
//            sql=sql+" where g_id between 900000 and 999999";
//        }else if(game_type==34){
//            sql=sql+" where g_id > 999999";
//        }
        return getJdbcTemplate().queryForInt(sql);
    }
    
    public void update(String sql, Object[] params) {
     getJdbcTemplate().update(sql, params);
    }

    public String findMaxNumAsString(String sql) {
        return getJdbcTemplate().queryForObject(sql, new Object[] {}, java.lang.String.class);
    }

    // 查游戏对应的tag_id
//    public int findTagId(String tagName) {
//        return jdbcT.queryForInt("select t1.tag_id from t_game_tag t1 join t_parameter_app t2 on t1.tag_name=t2.id where t2.name ='" + tagName + "' and t1.tag_id between 1300 and 1315");
//    }


    public static void main(String[] args) throws ParseException {
     System.out.println(new BaseDao().getJdbcTemplate());
     System.out.println(new BaseDao().getDataSource());
     System.out.println(new BaseDao().getDataSource());
    }

public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}

public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

public DataSource getDataSource() {
return dataSource;
}

public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}


}

--------------------编程问答--------------------
/**
 * 一个事务中多次更新数据,合理有效的控制事务。如果一个线程中只更新一次数据,就没必要调用这个方法了
 * @param sqlArgs map中的key就是sql语句,map中的value就是参数列表
 * 比如:map.put("delete from table where id = ?", new Object[] { 1l });
 * @return
 */
public Integer updateMoreData(Map<String, Object[]>... sqlArgs) {
Integer result = 0;
if (null != sqlArgs && sqlArgs.length > 0) {
Connection connection = null;
PreparedStatement prepared = null;
try {
connection = getConnNotCommit();
for (int i = 0; i < sqlArgs.length; i++) {
Map<String, Object[]> map = sqlArgs[i];
Object []arr = map.keySet().toArray();
for (int j = 0; j < arr.length; j++) {
prepared = getPrepared(connection, (String) arr[j], (Object[]) map.get(arr[j]));
log.info((String) arr[j]);
result += prepared.executeUpdate();
}
}
clearCacheList();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
prepared.close();
prepared = null;
connection.commit();
connection.close();
connection = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
return result;
}
--------------------编程问答-------------------- if(line=="")屌爆了!! --------------------编程问答-------------------- Dao中,对JdbcTemplate的使用有问题,俺自己写了个样例,LZ参考下呗?

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;


/**
 * BatchSqlUpdate方式实现数据库批量操作
 */
public class TestJdbcTemplate
{
    /**
     * 核心sql处理器
     */
    private JdbcTemplate jdbcTemplate = null;
    
    /**
     * 初始化JdbcTemplate
     */
    public TestJdbcTemplate(){
        BasicDataSource ds = new BasicDataSource();
        ds.setUrl("jdbc.url");//带入真实的jdbc.url
        ds.setDriverClassName("jdbc.driver");//带入真实的jdbc.driver驱动
        ds.setUsername("jdbc.user");//带入真实的数据库登录名
        ds.setPassword("jdbc.pass");//带入真实的数据库登录密码
        
        jdbcTemplate = new JdbcTemplate(ds);
        
    }
    
    /**
     * 测试样例
     */
    public static void main(String[] args)
    {
        TestJdbcTemplate testJdbcTemplate = new TestJdbcTemplate();
        
        //初始化10个Bean
        List<TestBean> testBeans = new ArrayList<TestBean>(10);
        TestBean testBean;
        for(int i=0;i<10;i++)
        {
            testBean = new TestBean();
            testBean.setAddress("address"+i);
            testBean.setPhone("phone"+i);
            testBean.setName("name"+i);
            testBean.setRole("role"+i);
            testBeans.add(testBean);
        }

        //sql写死的四个参数(数据库需事先创建一个test表,四个字段均为String)
        String sql = "insert into test (address, phone, name, role) values (?, ?, ?, ?)";
        int[] updatedRows = testJdbcTemplate.insertNewBeans(sql,testBeans);
        for (int row : updatedRows)
        {
            System.out.println("updatedRows:" + row);
        }
    }
    
    /**
     * 批量操作实现方法
     * @param sql       
     * @param testBeans
     * @return
     */
    public int[] insertNewBeans(String sql,final List<TestBean> testBeans)
    {
        return jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter(){
            
            public int getBatchSize() {
                return testBeans.size();
            }
        
            /**
             * 目前sql写死的,如果要更灵活的处理,需要进行改造
             */
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                TestBean testBean = testBeans.get(i);
                ps.setString(1,testBean.getAddress());
                ps.setString(2,testBean.getPhone());
                ps.setString(3,testBean.getName());
                ps.setString(4,testBean.getRole());
            }});
    }

}

/**
 * 数据库test表的实体类Bean
 *
 */
class TestBean
{
    private String address;
    private String phone;
    private String name;
    private String role;
    
    public String getAddress()
    {
        return address;
    }
    
    public void setAddress(String address)
    {
        this.address = address;
    }
    
    public String getPhone()
    {
        return phone;
    }
    
    public void setPhone(String phone)
    {
        this.phone = phone;
    }
    
    public String getName()
    {
        return name;
    }
    
    public void setName(String name)
    {
        this.name = name;
    }
    
    public String getRole()
    {
        return role;
    }
    
    public void setRole(String role)
    {
        this.role = role;
    }
    
}


另外,推荐一个博文:http://blog.csdn.net/s464036801/article/details/8942411
这里对Spring的数据库操作类,分析的很到位。 --------------------编程问答--------------------
引用 6 楼 oh_Maxy 的回复:
Dao中,对JdbcTemplate的使用有问题,俺自己写了个样例,LZ参考下呗?
另外,推荐一个博文:http://blog.csdn.net/s464036801/article/details/8942411
这里对Spring的数据库操作类,分析的很到位。


试了下。。插入1w条数据时手动终止控制台。。
数据还是进入数据库了。。
现在还是只能通过加事物方式来解决。。。 --------------------编程问答-------------------- connection未绑定到当前线程中,解决方法:
一、在web.xml文件中加入
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name> flushMode </param-name>
<param-value>AUTO </param-value>
</init-param>
</filter>

二、在spring配置中使用TransactionInterceptor声明事务
这两种方法可以为每个线程绑定一个connection。
这样,你在执行插入操作时,只需要开启事务,设置提交方式即可。
另外,如果使用hibernate+spring,在配置sessionFactory的时候好像可以配置批量处理。
补充:Java ,  Web 开发
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,