Spring基础入门(三)

一、Spring的jdbcTemplate操作#

(1)Spring是一站式框架,对于javaee三层,每一层都有解决技术。

  • web层:springMVC
  • service:spring的ioc
  • dao层:spring的jdbcTemplate

(2)Spring使用jdbcTemplate对dao层进行封装,jdbcTemplate使用和dbutils使用很相似,都数据库进行crud操作。

1.jdbcTemplate的crud操作##

1.1导入所需jar包###

IDEA会自动下载所需要的Spring包,但是数据库驱动需要自己导入。

1.2增加###

@Test
public void fun1() {

    //设置数据库信息
    DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
    driverManagerDataSource.setDriverClassName("com.mysql.jdbc.Driver");
    driverManagerDataSource.setUrl("jdbc:mysql:///test");
    driverManagerDataSource.setUsername("root");
    driverManagerDataSource.setPassword("123");

    //创建jdbcTemplate对象,设置数据源
    JdbcTemplate jdbcTemplate = new JdbcTemplate(driverManagerDataSource);
    String sql = "insert into stu values(?,?,?)";
    Object[] params = {22, "bob", 40};
    jdbcTemplate.update(sql, params);

}

没有什么需要讲解的,只要创建jdbcTemplate对象,然后调用update方法即可实现。

1.3删除###

/*删除*/
@Test
public void fun2() {
    DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
    driverManagerDataSource.setDriverClassName("com.mysql.jdbc.Driver");
    driverManagerDataSource.setUrl("jdbc:mysql:///test");
    driverManagerDataSource.setUsername("root");
    driverManagerDataSource.setPassword("123");
    JdbcTemplate jdbcTemplate = new JdbcTemplate(driverManagerDataSource);
    String sql = "delete from stu where id = ?";
    jdbcTemplate.update(sql, 20);

}

1.4修改###

/*修改*/
@Test
public void fun3() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName("com.mysql.jdbc.Driver");
    dataSource.setUrl("jdbc:mysql:///test");
    dataSource.setUsername("root");
    dataSource.setPassword("123");

    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
    String sql = "update stu set name = ? where id = ?";
    jdbcTemplate.update(sql, "lele", 13);
}

1.5查询###

1.5.1查询返回某一值####

/*查询返回值*/
@Test
public void fun5() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName("com.mysql.jdbc.Driver");
    dataSource.setUrl("jdbc:mysql:///test");
    dataSource.setUsername("root");
    dataSource.setPassword("123");

    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
    String sql = "select count(*) from stu";
    int count = jdbcTemplate.queryForObject(sql, Integer.class);
    System.out.println(count);
}

1.5.2查询返回对象####

如果学习了原始的JDBC操作就可知道,使用原始的JDBC进行查询,我们使用preparedStatement进行查询,之后将结果放入resultSet结果集中,最后遍历结果集,最后使用getString()获取结果集中的值。

/*使用JDBC实现查询*/
@Test
public void Jdbc() {
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    ResultSet resultSet = null;
    try {
        Class.forName("com.mysql.jdbc.Driver");
        connection = DriverManager.getConnection("jdbc:mysql:///test", "root", "123");
        //String sql = "select * from stu where id = ?";
        String sql1 = "select * from stu";
        preparedStatement = connection.prepareStatement(sql1);
        //preparedStatement.setString(1, "13");
        resultSet = preparedStatement.executeQuery();
        while (resultSet.next()) {
            String id = resultSet.getString("id");
            String name = resultSet.getString("name");
            String age = resultSet.getString("age");
            User user = new User();
            user.setId(id);
            user.setName(name);
            user.setAge(age);
            System.out.println(user);
        }

    } catch (SQLException e) {
        throw new RuntimeException(e);
    } catch (ClassNotFoundException e) {
        throw new RuntimeException(e);
    } finally {
        try {
            resultSet.close();
            preparedStatement.close();
            connection.close();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

    }
}

在jdbcTemplate中使用如下方法实现

但是其中要传入一个rowMapper对象,这个参数需要自己写类实现接口,并且自己做数据封装。

class MyRowMapper implements RowMapper<User> {
    @Override
    public User mapRow(ResultSet resultSet, int i) throws SQLException {
        String id = resultSet.getString("id");
        String name = resultSet.getString("name");
        String age = resultSet.getString("age");
        User user = new User();
        user.setId(id);
        user.setName(name);
        user.setAge(age);
        return user;
    }
}

/*查询某一对象*/
@Test
public void fun6() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName("com.mysql.jdbc.Driver");
    dataSource.setUrl("jdbc:mysql:///test");
    dataSource.setUsername("root");
    dataSource.setPassword("123");
    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
    String sql = "select * from stu where id = ?";
    User user = jdbcTemplate.queryForObject(sql, new MyRowMapper(), 13);
    System.out.println(user);
}

1.5.3查询List集合####

查询集合不再使用queryForObject(),而是使用query(),这里也需要传入rowMapper对象。

    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
    String sql = "select * from stu";
    List<User> list = jdbcTemplate.query(sql, new MyRowMapper());
    System.out.println(list);

二、Spring配置连接池和dao使用jdbcTemplate#

1.Spring配置c3p0连接池##

1.导入c3p0和依赖jar包

2.在配置文件中进行配置

<bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
    <property name="jdbcUrl" value="jdbc:mysql:///test"></property>
    <property name="user" value="root"></property>
    <property name="password" value="123"></property>
</bean>

2.dao使用jdbcTemplate##

1.创建service和dao,配置service和dao对象,在service注入dao对象

<!--创建service和dao对象-->
<bean id="userDao" class="test.spring.c3p0.UserDao">
    <property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<bean id="userService" class="test.spring.c3p0.UserService">
<!--将dao注入service-->
    <property name="userDao" ref="userDao"></property>
</bean>

2.创建jdbcTemplate对象,把模板对象注入到dao里面

spring-config.xml

<!--创建JdbcTemplate对象-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--传入datasource-->
        <property name="dataSource" ref="datasource"></property>
    </bean>

userDao.java

public class UserDao {
    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
    public void add() {
        String sql = "insert into stu values(?,?,?)";
        Object[] values = {22, "kl", 45};
        jdbcTemplate.update(sql , values);
        System.out.println("add success...");
    }
}

userService.java

    public class UserService {
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    public void add()
    {
        System.out.println("userService success..");
        userDao.add();
    }
}

三、Spring事务管理#

1.spring事务管理两种方式##

第一种 编程式事务管理(不用)

第二种 声明式事务管理

  • 基于xml配置文件实现
  • 基于注解实现

2.搭建转账环境##

1.创建数据库表,添加数据

2.创建service和dao类,完成注入关系

<!--创建OrderService和OrderDao对象-->
<bean id="orderDao" class="test.spring.transaction.anno.OrderDao">
    <property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<bean id="orderService" class="test.spring.transaction.anno.OrderService">
    <property name="orderDao" ref="orderDao"></property>
</bean>

<!--创建JdbcTemplate对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <!--传入datasource-->
    <property name="dataSource" ref="datasource"></property>
</bean>

3.执行转账操作,zhangsan-100,,李四+100.

    public class OrderService {
    private OrderDao orderDao;

    public void setOrderDao(OrderDao orderDao) {
        this.orderDao = orderDao;
    }

    public void account() {
        orderDao.lessMoney();
        orderDao.addMoney();
    }
}

public class OrderDao {
    private JdbcTemplate jdbcTemplate;

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

    public void lessMoney() {
        String sql = "update account set balance=balance-? where name=?";
        jdbcTemplate.update(sql, 100, "zhangsan");
    }

    public void addMoney() {
        String sql = "update account set balance=balance+? where name=?";
        jdbcTemplate.update(sql, 100, "lisi");
    }
}

成功运行,并且数据库中也进行了更新。

但是此时,如果程序在运行过程中出现异常,比如我们将在account()中加入如下语句。

public void account() {
    orderDao.lessMoney();
    int i = 1/0;
    orderDao.addMoney();
}

这就会抛出一个非常常见的异常

这时查询数据库,发现zhangsan少了100,但是lisi并没有增加,这100元就这样没了。

所以我们需要在这里引入事务控制。

声明式事务管理(xml配置)##

首先配置事务管理器

<!--配置事务管理器-->
<bean id="transactionManager2" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="datasource"></property>
</bean>

这里使用aop的思想进行事务操作

<!--配置事务增强-->
<tx:advice id="txadvice" transaction-manager="transactionManager">
    <!--事务操作-->
    <tx:attributes>
        <tx:method name="account*" propagation="REQUIRED"/>
    </tx:attributes>
</tx:advice>

最后配置切面

<!--配置切面-->
<aop:config>
    <!--配置切入点-->
    <aop:pointcut id="pointcut2"
                  expression="execution(* test.spring.transaction.xml.OrderService.account(..))"></aop:pointcut>
    <!--配置切面-->
    <aop:advisor advice-ref="txadvice" pointcut-ref="pointcut2"></aop:advisor>
</aop:config>

这样再次运行程序,虽然出现异常,但是zhangsan和lisi的余额并没有改变。

声明式事务管理(注解方式)##

使用注解方式进行事务管理,只需要在配置完事务管理器后开启事务注解即可实现,不再通过配置切面完成。

<!--开启事务注解-->
<tx:annotation-driven transaction-manager="transactionManager2"></tx:annotation-driven>

之后,只要在service中声明如下注解即可实现

本节的Demo已上传github,如有需要请下载###

https://github.com/LELE-QAQ/TestSpring_2

posted @ 2019-03-25 22:16  灵图  阅读(167)  评论(0)    收藏  举报