Spring笔记

本文探讨了在Spring框架中使用JDBC与Hibernate的性能比较,重点介绍了如何配置数据库连接池和使用jdbcTemplate。同时,详细讲解了Spring与JDBC的事务管理,包括设置MySQL的autocommit属性以及如何进行声明式事务管理。文章还列举了不同类型的事务管理器,如DataSourceTransactionManager和HibernateTransactionManager。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

msyql 完全清除表

truncate t_user;

性能比较: JDBC > hibernate(反射太多了,影响性能)

Spring 和 JDBC的使用 (相当于SqlHelper ,在没有使用hibernate的情况下)

  1. 配置数据库连接池 (单例 ),由我们的Spring管理一个全局唯一的数据库连接池
  2. 使用jdbcTemplate (和HibernateTemplate类似 )
  3. 使用c3p0
  4. applicationContext.xml
<bean id="dataSource" class=".....ComboPooledDataSource">
        <property name=""></property>
    </bean>

让Spring帮我们setter setter setter ,也可以自己通过编程new 这个DataSource

完整配置:

<

?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:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-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/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd ">


    <!-- 自动扫描与装配bean -->
    <context:component-scan base-package="cn.itcast.spring.p_jdbc"></context:component-scan>


    <!-- 加载外部的配置文件 -->
    <context:property-placeholder location="classpath:cn/itcast/spring/p_jdbc/jdbc.properties"/>


    <!-- 一、配置数据库连接池 ComboPooledDataSource -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!-- 基本的连接信息 -->
        <property name="jdbcUrl" value="${jdbcUrl}"></property>
        <property name="driverClass" value="${driverClass}"></property>
        <property name="user" value="${username}"></property>
        <property name="password" value="${password}"></property>
        <!-- 一些管理的配置 -->
        <!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
        <property name="initialPoolSize" value="3"></property>
        <!--连接池中保留的最小连接数。Default: 3 -->
        <property name="minPoolSize" value="3"></property>
        <!--连接池中保留的最大连接数。Default: 15 -->
        <property name="maxPoolSize" value="5"></property>
        <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
        <property name="acquireIncrement" value="3"></property>
        <!--最大空闲时间,1800秒内未使用则连接被丢弃,若为0则永不丢弃。Default: 0 -->
        <property name="maxIdleTime" value="1800"></property>
    </bean>



    <!-- 二、配置JdbcTemplate -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">                                 
        <property name="dataSource" ref="dataSource"></property>
    </bean>



    <!-- 三、配置声明式事务管理 -->


    <!-- 声明“事务管理器” -->
    <bean id="dsTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!-- ==== 基于注解的方式配置事务 ==== -->
    <tx:annotation-driven transaction-manager="dsTransactionManager"/>
 明显通过 注解 配置事务 比较好用 ,事务管理器也是通过Aop配置的 

    <!-- ==== 基于XML的方式配置事务 ==== -->
    <!-- 声明“通知”:
        对于以save或update或delete开头的方法,使用正常的事务,其他的方法都使用只读的事务 
        read-only:表示事务是否是只读的,默认为false。
    <tx:advice id="transactionManager" transaction-manager="dsTransactionManager">
        <tx:attributes>
            <tx:method name="save*" read-only="false"/>
            <tx:method name="update*"/>
            <tx:method name="delete*"/>
            <tx:method name="*" read-only="true"/>
        </tx:attributes>
    </tx:advice>
    -->
    <!-- 声明“切面” 
    <aop:config>
        <aop:advisor advice-ref="transactionManager" pointcut="execution(* cn.itcast.spring.p_jdbc.*Dao.*(..))"/>
    </aop:config>
    -->


</beans>

对比 Hibernate的事务管理器 ;
和 JDBC的事务管理不同的是 : JDBC的事务管理直接使用的是 dataSource事务管理器,属性注入的是dataSource, 而hibernate属性注入的是sessionFactory;

<!-- 配置事务管理器 -->

<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="txManager"/>










@Repository 

public class UserDao{
    /** 错误方式
    @Resource 
    private DataSource dataSource;
    JdbcTemplate jdbcTemplate  = new JdbcTemplate(); 错误,拿不到连接池  
    */

    // 正确方式 ,直接在xml中配置JdbcTemplate ,且关联数据源 
    @Resource
    private JdbcTemplate jdbcTemplate; // 注意此对象一定要从Spring容器获取,自己new的执行 下面save()jdbcTemplate.execute方法会报空指针异常


    public void save(User user ){

        jdbcTemplate.execute(new ConnectionCallback(){
            public Object doInConnnection(Connection con){
                String sql = "insert into t_user(name,age) values ('wanlgi','11')";
                con.prepareStatement(sql);
                /**
                String sql = "insert into t_user(name,age) values (?,?)";
                PreparedStatement ps = con.prepareStatement(sql);
                ps.setString(1,user.getName());
                ps.setString(2,user.getAge());
                */

                ps.execute();
                ps.close();
                return null;
            }


        });

    }
            jdbcTemplate. 其他 实用方法
            // jdbcTemplate.update(sql,new Object[]{user.getName(),user.getAge()});  // 更加简洁 
            // 实际上内部执行上面代码 ,但是一个参数也需要写一个数组 ,Spring没有提供可变参数 


}

完整代码:

package cn.itcast.spring.p_jdbc;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Repository
@Transactional(readOnly = true)
public class UserDao {

    @Resource
    private JdbcTemplate jdbcTemplate;

    /**
     * 保存
     * 
     * @param user
     */
    @Transactional(readOnly = false)
    public void save(final User user) {
        // jdbcTemplate.execute(new ConnectionCallback() {
        // public Object doInConnection(Connection conn) throws SQLException, DataAccessException {
        // String sql = "insert into t_user(name, age) values (?, ?)";
        // PreparedStatement ps = conn.prepareStatement(sql);
        // ps.setString(1, user.getName()); // 第1个参数的索引是1
        // ps.setInt(2, user.getAge());
        // ps.execute();
        // ps.close();
        // return null;
        // }
        // });

        String sql = "insert into t_user(name, age) values (?, ?)";
        jdbcTemplate.update(sql, new Object[] { user.getName(), user.getAge() });

        delete(1);
    }

    /**
     * 删除
     * 
     * @param id
     */
    public void delete(Integer id) {
        String sql = "delete from t_user where id=?";
        jdbcTemplate.update(sql, new Object[] { id });
    }

    /**
     * 更新
     * 
     * @param user
     */
    public void update(User user) {
        String sql = "update t_user set name=?, age=? where id=?";
        jdbcTemplate.update(sql, new Object[] { user.getName(), user.getAge(), user.getId() });
    }

    /**
     * 根据id查询一个数据
     * 
     * @param id
     * @return
     */
    public User getById(final Integer id) {
        String sql = "select name,age from t_user where id=?";
        return (User) jdbcTemplate.queryForObject(sql, new Object[] { id }, new RowMapper() {
            public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
                String name = rs.getString(1);
                int age = rs.getInt(2);
                return new User(id, name, age);
            }
        });
    }

    @Transactional(isolation = Isolation.READ_COMMITTED)
    public void testGet(int id) {
        User user = getById(id);
        System.out.println(user);

        user = getById(id);
        System.out.println(user);
    }

    /**
     * 查询总数量
     * 
     * @return
     */
    public int getCount() {
        String sql = "select count(*) from t_user";
        return jdbcTemplate.queryForInt(sql);
    }

    /**
     * 查询所有
     * 
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<User> findAll() {
        String sql = "select id,name,age from t_user";

        return jdbcTemplate.query(sql, new RowMapper() {
            public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
                int id = rs.getInt(1);
                String name = rs.getString(2);
                int age = rs.getInt(3);
                return new User(id, name, age);
            }
        });
    }

    /**
     * 查询所有(分页)
     * 
     * @param firstResult
     * @param maxResult
     * @return
     */
    public QueryResult findAll(int firstResult, int maxResult) {
        int count = jdbcTemplate.queryForInt("select count(*) from t_user");
        List list = jdbcTemplate.query(//
                "select id,name,age from t_user limit ?,?", //
                new Object[] { firstResult, maxResult }, //
                new RowMapper() {
                    public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
                        int id = rs.getInt(1);
                        String name = rs.getString(2);
                        int age = rs.getInt(3);
                        return new User(id, name, age);  // 创建此构造方法--> 同时添加默认构造方法
                    }
                });
        return new QueryResult(count, list);
    }
}


Junit测试代码:

package cn.itcast.spring.p_jdbc;

import java.util.List;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserDaoTest {

    private ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml", getClass());
    private UserDao userDao = (UserDao) ac.getBean("userDao");

    @Test
    public void testSave_1() {
        User user = new User();
        user.setName("李四");
        user.setAge(25);

        userDao.save(user);
    }

    @Test
    public void testSave_25() {
        for (int i = 1; i <= 25; i++) {
            User user = new User();
            user.setName("李四_" + i);
            user.setAge(i);

            userDao.save(user);
        }
    }

    @Test
    public void testDelete() {
        userDao.delete(1);
    }

    @Test
    public void testUpdate() {
        User user = new User();
        user.setId(2); // 模拟一条记录
        user.setName("李四222");
        user.setAge(25);

        userDao.update(user);
    }

    @Test
    public void testGetById() {
        User user = userDao.getById(2);
        System.out.println(user);
    }

    @Test
    public void testGetCount() {
        int count = userDao.getCount();
        System.out.println(count);
    }

    @Test
    public void testFindAll() {
        List<User> list = userDao.findAll();
        for (User user : list) {
            System.out.println(user);
        }
    }

    @Test
    public void testFindAllIntInt() {
        // 查询
        // QueryResult qr = userDao.findAll(0, 10); // 第1页,每页10条
        // QueryResult qr = userDao.findAll(10, 10); // 第2页,每页10条
        QueryResult qr = userDao.findAll(20, 10); // 第3页,每页10条

        // 显示结果
        System.out.println("总结果数:" + qr.getCount());
        for (User user : (List<User>) qr.getList()) {
            System.out.println(user);
        }

    }

    // 测试事务的隔离级别
    @Test
    public void testTransaction() {
        userDao.testGet(1);
    }

}

select @@autocommit;
记录:
@@autocommit
1
发现mysql 会自动提交 ; 如果我们想自己管理事务,设置为 0;

每次明确指定commit;

        rollback;

故需要在spring里配置事务管理:
——->声明式事务管理
事务管理器实现 目标
org.springframework.jdbc.datasource.DataSourceTransactionManager 在单一的JDBC Datasource中的管理事务

org.springframework.orm.hibernate3.HibernateTransactionManager 当持久化机制是hibernate时,用它来管理事务

org.springframework.jdo.JdoTransactionManager 当持久化机制是Jdo时,用它来管理事务。

org.springframework.transaction.jta.JtaTransactionManager 使用一个JTA实现来管理事务。在一个事务跨越多个资源时必须使用

org.springframework.orm.ojb.PersistenceBrokerTransactionManager 当apache的ojb用作持久化机制时,用它来管理事务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值