SSH框架之Spring第四篇

来源:https://www.cnblogs.com/haizai/archive/2019/09/22/11568796.html
-Advertisement-
Play Games

1.1 JdbcTemplate概述 : 它是spring框架中提供的一個對象,是對原始JdbcAPI對象的簡單封裝.spring框架為我們提供了很多的操作模板類. ORM持久化技術 模板類 JDBC org.springframework.jdbc.core.J... ...


1.1 JdbcTemplate概述 : 
        它是spring框架中提供的一個對象,是對原始JdbcAPI對象的簡單封裝.spring框架為我們提供了很多的操作模板類.
        ORM持久化技術                        模板類
        JDBC                    org.springframework.jdbc.core.JdbcTemplate.
        Hibernate3.0             org.springframework.orm.hibernate3.HibernateTemplate.
        IBatis(MyBatis)            org.springframework.orm.ibatis.SqlMapClientTemplate.
        JPA                        org.springframework.orm.jpa.JpaTemplate.
    在導包的時候需要導入spring-jdbc-4.24.RELEASF.jar,還需要導入一個spring-tx-4.2.4.RELEASE.jar(它和事務有關)

    <!-- 配置數據源 -->
        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
            <property name="url" value="jdbc:mysql:// /spring_day04"></property>
            <property name="username" value="root"></property>
            <property name="password" value="1234"></property>
        </bean>
    1.3.3.3配置spring內置數據源
        spring框架也提供了一個內置數據源,我們也可以使用spring的內置數據源,它就在spring-jdbc-4.2.4.REEASE.jar包中:
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
            <property name="url" value="jdbc:mysql:///spring_day04"></property>
            <property name="username" value="root"></property>
            <property name="password" value="1234"></property>
        </bean>
    1.3.4將資料庫連接的信息配置到屬性文件中:
        【定義屬性文件】
        jdbc.driverClass=com.mysql.jdbc.Driver
        jdbc.url=jdbc:mysql:///spring_day02
        jdbc.username=root
        jdbc.password=123
        【引入外部的屬性文件】
        一種方式:
            <!-- 引入外部屬性文件: -->
            <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
                <property name="location" value="classpath:jdbc.properties"/>
            </bean>

        二種方式:
        <context:property-placeholder location="classpath:jdbc.properties"/>

    1.4JdbcTemplate的增刪改查操作
        1.4.1前期準備
        創建資料庫:
        create database spring_day04;
        use spring_day04;
        創建表:
        create table account(
            id int primary key auto_increment,
            name varchar(40),
            money float
        )character set utf8 collate utf8_general_ci;
    1.4.2在spring配置文件中配置JdbcTemplate
        <?xml version="1.0" encoding="UTF-8"?>
        <beans xmlns="http://www.springframework.org/schema/beans"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="http://www.springframework.org/schema/beans 
                http://www.springframework.org/schema/beans/spring-beans.xsd">

            <!-- 配置一個資料庫的操作模板:JdbcTemplate -->
            <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
                <property name="dataSource" ref="dataSource"></property>
            </bean>
            
            <!-- 配置數據源 -->
            <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
            <property name="url" value="jdbc:mysql:///spring_day04"></property>
            <property name="username" value="root"></property>
            <property name="password" value="1234"></property>
        </bean>
        </beans>
    1.4.3最基本使用
        public class JdbcTemplateDemo2 {
            public static void main(String[] args) {
                //1.獲取Spring容器
                ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
                //2.根據id獲取bean對象
                JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
                //3.執行操作
                jt.execute("insert into account(name,money)values('eee',500)");
            }
        }
    1.4.4保存操作
        public class JdbcTemplateDemo3 {
            public static void main(String[] args) {

                //1.獲取Spring容器
                ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
                //2.根據id獲取bean對象
                JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
                //3.執行操作
                //保存
                jt.update("insert into account(name,money)values(?,?)","fff",5000);
            }
        }
    1.4.5更新操作
        public class JdbcTemplateDemo3 {
            public static void main(String[] args) {

                //1.獲取Spring容器
                ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
                //2.根據id獲取bean對象
                JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
                //3.執行操作
                //修改
                jt.update("update account set money = money-? where id = ?",300,6);
            }
        }
    1.4.6刪除操作
        public class JdbcTemplateDemo3 {
            public static void main(String[] args) {

                //1.獲取Spring容器
                ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
                //2.根據id獲取bean對象
                JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
                //3.執行操作
                //刪除
                jt.update("delete from account where id = ?",6);
            }
        }
    1.4.7查詢所有操作
        public class JdbcTemplateDemo3 {
            public static void main(String[] args) {

                //1.獲取Spring容器
                ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
                //2.根據id獲取bean對象
                JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
                //3.執行操作
                //查詢所有
                List<Account> accounts = jt.query("select * from account where money > ? ", 
                                                    new AccountRowMapper(), 500);
                for(Account o : accounts){
                    System.out.println(o);
                }
            }
        }

        public class AccountRowMapper implements RowMapper<Account>{
            @Override
            public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
                Account account = new Account();
                account.setId(rs.getInt("id"));
                account.setName(rs.getString("name"));
                account.setMoney(rs.getFloat("money"));
                return account;
            }
            
        }

    1.4.8查詢一個操作
        使用RowMapper的方式:常用的方式
        public class JdbcTemplateDemo3 {
            public static void main(String[] args) {

                //1.獲取Spring容器
                ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
                //2.根據id獲取bean對象
                JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
                //3.執行操作
                //查詢一個
                List<Account> as = jt.query("select * from account where id = ? ", 
                                                new AccountRowMapper(), 55);
                System.out.println(as.isEmpty()?"沒有結果":as.get(0));
            }
        }
    1.4.9查詢返回一行一列操作
        public class JdbcTemplateDemo3 {
            public static void main(String[] args) {

                //1.獲取Spring容器
                ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
                //2.根據id獲取bean對象
                JdbcTemplate jt = (JdbcTemplate) ac.getBean("jdbcTemplate");
                //3.執行操作
                //查詢返回一行一列:使用聚合函數,在不使用group by字句時,都是返回一行一列。最長用的就是分頁中獲取總記錄條數
                Integer total = jt.queryForObject("select count(*) from account where money > ? ",Integer.class,500);
                System.out.println(total);
            }
        }
applicationContext.xml
        <?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:aop="http://www.springframework.org/schema/aop"
            xmlns:tx="http://www.springframework.org/schema/tx"
            xsi:schemaLocation="http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/tx 
            http://www.springframework.org/schema/tx/spring-tx.xsd">

            <!-- 使用Spring管理連接池對象,Spring內置的連接池對象 -->
            
            <!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
                <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
                <property name="url" value="jdbc:mysql:///spring_04"/>
                <property name="username" value="root"></property>
                <property name="password" value="root"></property>
            </bean> -->
            
            <!-- 配置數據源,使用Spring整合dbcp連接,沒有導入jar包 -->
            <!-- <bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp.BasicDataSource">
                <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///spring_04"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </bean> -->
            
            <!-- 使用Spring整合c3p0的連接池,沒有採用屬性文件的方式 -->
            <!-- 
            <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
                <property name="driverClass" value="com.mysql.jdbc.Driver"/>
                <property name="jdbcUrl" value="jdbc:mysql:///spring_04"/>
                <property name="user" value="root"/>
                <property name="password" value="root"/>
            </bean> -->
            
            <!-- 使用context:property-placeholder標簽,讀取屬性文件 -->
            <context:property-placeholder location="classpath:db.properties"/>
            
            <!-- 使用Spring整合c3p0的連接池,採用屬性文件的方式 -->
            <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
                <property name="driverClass" value="${jdbc.driver}"/>
                <property name="jdbcUrl" value="${jdbc.url}"/>
                <property name="user" value="${jdbc.user}"/>
                <property name="password" value="${jdbc.password}"/>
                
            </bean>
            <!-- spring管理JbdcTemplate模板 -->
            <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
                <property name="dataSource" ref="dataSource"/>
            </bean>

        </beans>
db.properties : 屬性文件
        jdbc.driver=com.mysql.jdbc.Driver
        jdbc.url=jdbc:mysql:///spring_day04
        jdbc.user=root
        jdbc.password=root
Demo測試 :
    package com.ithiema.demo1;

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

    import javax.annotation.Resource;

    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.jdbc.core.RowMapper;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

    /**
     * Spring整合JdbcTemplate的方式入門
     * @author Administrator
     */
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class Demo11 {
        
        @Resource(name="jdbcTemplate")
        private JdbcTemplate jdbcTemplate;
        
        /**
         * 添加
         */
        @Test
        public void run1(){
            jdbcTemplate.update("insert into account values (null,?,?)", "嘿嘿",10000);
        }
        
        /**
         * 修改
         */
        @Test
        public void run2(){
            jdbcTemplate.update("update account set name = ?,money = ? where id = ?", "嘻嘻",5000,6);
        }
        
        /**
         * 刪除
         */
        @Test
        public void run3(){
            jdbcTemplate.update("delete from account where id = ?", 6);
        }
        
        /**
         * 查詢多條數據
         */
        @Test
        public void run4(){
            // sql          sql語句
            // rowMapper    提供封裝數據的介面,自己提供實現類(自己封裝數據的)
            List<Account> list = jdbcTemplate.query("select * from account", new BeanMapper());
            for (Account account : list) {
                System.out.println(account);
            }
        }    
    }

    /**
     * 自己封裝的實現類,封裝數據的
     * @author Administrator
     */
    class BeanMapper implements RowMapper<Account>{
        
        /**
         * 一行一行封裝數據的
         */
        public Account mapRow(ResultSet rs, int index) throws SQLException {
            // 創建Account對象,一個屬性一個屬性賦值,返回對象
            Account ac = new Account();
            ac.setId(rs.getInt("id"));
            ac.setName(rs.getString("name"));
            ac.setMoney(rs.getDouble("money"));
            return ac;
        }
        
    }

2,1 Spring 事務控制我們要明確的
    1: JavaEE體系進行分層開發,事務處理位於業務層,Spring提供了分層設計業務層的事務處理解決方案.
    2: Spring框架為我們提供就一組事務控制的介面.這組介面是在spring-tx-4.2.4RELEASE.jar中.
    3: spring的事務都是基於AOP的,它既可以使用編程的方式實現,也可以使用配置的方式實現
    2.2Spring中事務控制的API介紹
        2.2.1PlatformTransactionManager
        此介面是spring的事務管理器,它裡面提供了我們常用的操作事務的方法,如下圖:

        我們在開發中都是使用它的實現類,如下圖:

        真正管理事務的對象
        org.springframework.jdbc.datasource.DataSourceTransactionManager    使用Spring JDBC或iBatis 進行持久化數據時使用
        org.springframework.orm.hibernate3.HibernateTransactionManager        使用Hibernate版本進行持久化數據時使用
    2.2.2TransactionDefinition
        它是事務的定義信息對象,裡面有如下方法:

    2.2.2.1事務的隔離級別

    2.2.2.2事務的傳播行為
        REQUIRED:如果當前沒有事務,就新建一個事務,如果已經存在一個事務中,加入到這個事務中。一般的選擇(預設值)
        SUPPORTS:支持當前事務,如果當前沒有事務,就以非事務方式執行(沒有事務)
        MANDATORY:使用當前的事務,如果當前沒有事務,就拋出異常
        REQUERS_NEW:新建事務,如果當前在事務中,把當前事務掛起。
        NOT_SUPPORTED:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起
        NEVER:以非事務方式運行,如果當前存在事務,拋出異常
        NESTED:如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則執行REQUIRED類似的操作。
        2.2.2.3超時時間
        預設值是-1,沒有超時限制。如果有,以秒為單位進行設置。
        2.2.2.4是否是只讀事務
        建議查詢時設置為只讀。
        2.2.3TransactionStatus
        此介面提供的是事務具體的運行狀態,方法介紹如下圖:

    2.3基於XML的聲明式事務控制(配置方式)重點
        2.3.1環境搭建
        2.3.1.1第一步:拷貝必要的jar包到工程的lib目錄

    2.3.1.2第二步:創建spring的配置文件並導入約束
        <?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:tx="http://www.springframework.org/schema/tx"
                xsi:schemaLocation="http://www.springframework.org/schema/beans 
                        http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/tx 
                        http://www.springframework.org/schema/tx/spring-tx.xsd
                        http://www.springframework.org/schema/aop 
                        http://www.springframework.org/schema/aop/spring-aop.xsd">    
        </beans>
        2.3.1.3第三步:準備資料庫表和實體類
        創建資料庫:
        create database spring_day04;
        use spring_day04;
        創建表:
        create table account(
            id int primary key auto_increment,
            name varchar(40),
            money float
        )character set utf8 collate utf8_general_ci;
        /**
         * 賬戶的實體
         */
        public class Account implements Serializable {

            private Integer id;
            private String name;
            private Float money;
            public Integer getId() {
                return id;
            }
            public void setId(Integer id) {
                this.id = id;
            }
            public String getName() {
                return name;
            }
            public void setName(String name) {
                this.name = name;
            }
            public Float getMoney() {
                return money;
            }
            public void setMoney(Float money) {
                this.money = money;
            }
            @Override
            public String toString() {
                return "Account [id=" + id + ", name=" + name + ", money=" + money + "]";
            }
        }
        2.3.1.4第四步:編寫業務層介面和實現類
        /**
         * 賬戶的業務層介面
         */
        public interface IAccountService {
            
            /**
             * 根據id查詢賬戶信息
             * @param id
             * @return
             */
            Account findAccountById(Integer id);//
            
            /**
             * 轉賬
             * @param sourceName    轉出賬戶名稱
             * @param targeName        轉入賬戶名稱
             * @param money            轉賬金額
             */
            void transfer(String sourceName,String targeName,Float money);//增刪改
        }

        /**
         * 賬戶的業務層實現類
         */
        public class AccountServiceImpl implements IAccountService {
            
            private IAccountDao accountDao;
            
            public void setAccountDao(IAccountDao accountDao) {
                this.accountDao = accountDao;
            }

            @Override
            public Account findAccountById(Integer id) {
                return accountDao.findAccountById(id);
            }

            @Override
            public void transfer(String sourceName, String targeName, Float money) {
                //1.根據名稱查詢兩個賬戶
                Account source = accountDao.findAccountByName(sourceName);
                Account target = accountDao.findAccountByName(targeName);
                //2.修改兩個賬戶的金額
                source.setMoney(source.getMoney()-money);//轉出賬戶減錢
                target.setMoney(target.getMoney()+money);//轉入賬戶加錢
                //3.更新兩個賬戶
                accountDao.updateAccount(source);
                int i=1/0;
                accountDao.updateAccount(target);
            }
        }
        2.3.1.5第五步:編寫Dao介面和實現類
        /**
         * 賬戶的持久層介面
         */
        public interface IAccountDao {
            
            /**
             * 根據id查詢賬戶信息
             * @param id
             * @return
             */
            Account findAccountById(Integer id);

            /**
             * 根據名稱查詢賬戶信息
             * @return
             */
            Account findAccountByName(String name);
            
            /**
             * 更新賬戶信息
             * @param account
             */
            void updateAccount(Account account);
        }
        /**
         * 賬戶的持久層實現類
         * 此版本dao,只需要給它的父類註入一個數據源
         */
        public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao {

            @Override
            public Account findAccountById(Integer id) {
                List<Account> list = getJdbcTemplate().query("select * from account where id = ? ",new AccountRowMapper(),id);
                return list.isEmpty()?null:list.get(0);
            }

            @Override
            public Account findAccountByName(String name) {
                List<Account> list =  getJdbcTemplate().query("select * from account where name = ? ",new AccountRowMapper(),name);
                if(list.isEmpty()){
                    return null;
                }
                if(list.size()>1){
                    throw new RuntimeException("結果集不唯一,不是只有一個賬戶對象");
                }
                return list.get(0);
            }

            @Override
            public void updateAccount(Account account) {
                getJdbcTemplate().update("update account set money = ? where id = ? ",account.getMoney(),account.getId());
            }
        }

        /**
         * 賬戶的封裝類RowMapper的實現類
         */
        public class AccountRowMapper implements RowMapper<Account>{

            @Override
            public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
                Account account = new Account();
                account.setId(rs.getInt("id"));
                account.setName(rs.getString("name"));
                account.setMoney(rs.getFloat("money"));
                return account;
            }
        }
        2.3.1.6第六步:在配置文件中配置業務層和持久層對
        <!-- 配置service -->
        <bean id="accountService" class="com.baidu.service.impl.AccountServiceImpl">
            <property name="accountDao" ref="accountDao"></property>
        </bean>
            
        <!-- 配置dao -->
        <bean id="accountDao" class="com.baidu.dao.impl.AccountDaoImpl">
            <!-- 註入dataSource -->
            <property name="dataSource" ref="dataSource"></property>
        </bean>
            
        <!-- 配置數據源 -->
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
            <property name="url" value="jdbc:mysql:///spring_day04"></property>
            <property name="username" value="root"></property>
            <property name="password" value="1234"></property>
        </bean>
    2.3.2配置步驟
        2.3.2.1第一步:配置事務管理器
        <!-- 配置一個事務管理器 -->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <!-- 註入DataSource -->
            <property name="dataSource" ref="dataSource"></property>
        </bean>
        2.3.2.2第二步:配置事務的通知引用事務管理器
        <!-- 事務的配置 -->
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
        </tx:advice>
        2.3.2.3第三步:配置事務的屬性
        <!--在tx:advice標簽內部 配置事務的屬性 -->
        <tx:attributes>
        <!-- 指定方法名稱:是業務核心方法 
            read-only:是否是只讀事務。預設false,不只讀。
            isolation:指定事務的隔離級別。預設值是使用資料庫的預設隔離級別。 
            propagation:指定事務的傳播行為。
            timeout:指定超時時間。預設值為:-1。永不超時。
            rollback-for:用於指定一個異常,當執行產生該異常時,事務回滾。產生其他異常,事務不回滾。沒有預設值,任何異常都回滾。
            no-rollback-for:用於指定一個異常,當產生該異常時,事務不回滾,產生其他異常時,事務回滾。沒有預設值,任何異常都回滾。
            -->
            <tx:method name="*" read-only="false" propagation="REQUIRED"/>
            <tx:method name="find*" read-only="true" propagation="SUPPORTS"/>
        </tx:attributes>
        2.3.2.4第四步:配置AOP-切入點表達式
        <!-- 配置aop -->
        <aop:config>
            <!-- 配置切入點表達式 -->
            <aop:pointcut expression="execution(* com.baidu.service.impl.*.*(..))" id="pt1"/>
        </aop:config>
        2.3.2.5第五步:配置切入點表達式和事務通知的對應關係
        <!-- 在aop:config標簽內部:建立事務的通知和切入點表達式的關係 -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"/>
        2.4基於XML和註解組合使用的整合方式
        2.4.1環境搭建
        2.4.1.1第一步:拷貝必備的jar包到工程的lib目錄

        2.4.1.2第二步:創建spring的配置文件導入約束並配置掃描的包
        <?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: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.xsd
                            http://www.springframework.org/schema/tx 
                            http://www.springframework.org/schema/tx/spring-tx.xsd
                            http://www.springframework.org/schema/aop 
                            http://www.springframework.org/schema/aop/spring-aop.xsd
                            http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context.xsd">
            <!-- 配置spring要掃描的包 -->
            <context:component-scan base-package="com.baidu"></context:component-scan>
        </beans>
    2.4.1.3第三步:創建資料庫表和實體類
        和基於xml的配置相同。
        2.4.1.4第四步:創建業務層介面和實現類並使用註解讓spring管理
        業務層介面和基於xml配置的時候相同。略

        /**
         * 賬戶的業務層實現類
         */
        @Service("accountService")
        public class AccountServiceImpl implements IAccountService {
            @Autowired
            private IAccountDao accountDao;

            @Override
            public Account findAccountById(Integer id) {
                return accountDao.findAccountById(id);
            }

            @Override
            public void transfer(String sourceName, String targeName, Float money) {
                //1.根據名稱查詢兩個賬戶
                Account source = accountDao.findAccountByName(sourceName);
                Account target = accountDao.findAccountByName(targeName);
                //2.修改兩個賬戶的金額
                source.setMoney(source.getMoney()-money);//轉出賬戶減錢
                target.setMoney(target.getMoney()+money);//轉入賬戶加錢
                //3.更新兩個賬戶
                accountDao.updateAccount(source);
                int i=1/0;
                accountDao.updateAccount(target);
            }
        }
    2.4.1.5第五步:創建Dao介面和實現類並使用註解讓spring管理
        Dao層介面和AccountRowMapper與基於xml配置的時候相同。略

        @Repository("accountDao")
        public class AccountDaoImpl implements IAccountDao {

            @Autowired
            private JdbcTemplate jdbcTemplate;
            
            @Override
            public Account findAccountById(Integer id) {
                List<Account> list = jdbcTemplate.query("select * from account where id = ? ",new AccountRowMapper(),id);
                return list.isEmpty()?null:list.get(0);
            }

            @Override
            public Account findAccountByName(String name) {
                List<Account> list =  jdbcTemplate.query("select * from account where name = ? ",new AccountRowMapper(),name);
                if(list.isEmpty()){
                    return null;
                }
                if(list.size()>1){
                    throw new RuntimeException("結果集不唯一,不是只有一個賬戶對象");
                }
                return list.get(0);
            }

            @Override
            public void updateAccount(Account account) {
                jdbcTemplate.update("update account set money = ? where id = ? ",account.getMoney(),account.getId());
            }
        }
    2.4.2配置步驟
        2.4.2.1第一步:配置數據源和JdbcTemplate
        <!-- 配置數據源 -->
        <bean id="dataSource" 
                    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
            <property name="url" value="jdbc:mysql:///spring_day04"></property>
            <property name="username" value="root"></property>
            <property name="password" value="1234"></property>
        </bean>


    2.4.2.2第二步:配置事務管理器並註入數據源
        <!-- 配置JdbcTemplate -->
        <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
    2.4.2.3第三步:在業務層使用@Transactional註解
        @Service("accountService")
        @Transactional(readOnly=true,propagation=Propagation.SUPPORTS)
        public class AccountServiceImpl implements IAccountService {
            
            @Autowired
            private IAccountDao accountDao;

            @Override
            public Account findAccountById(Integer id) {
                return accountDao.findAccountById(id);
            }

            @Override
            @Transactional(readOnly=false,propagation=Propagation.REQUIRED)
            public void transfer(String sourceName, String targeName, Float money) {
                //1.根據名稱查詢兩個賬戶
                Account source = accountDao.findAccountByName(sourceName);
                Account target = accountDao.findAccountByName(targeName);
                //2.修改兩個賬戶的金額
                source.setMoney(source.getMoney()-money);//轉出賬戶減錢
                target.setMoney(target.getMoney()+money);//轉入賬戶加錢
                //3.更新兩個賬戶
                accountDao.updateAccount(source);
                //int i=1/0;
                accountDao.updateAccount(target);
            }
        }

        該註解的屬性和xml中的屬性含義一致。該註解可以出現在介面上,類上和方法上。
        出現介面上,表示該介面的所有實現類都有事務支持。
        出現在類上,表示類中所有方法有事務支持
        出現在方法上,表示方法有事務支持。
        以上三個位置的優先順序:方法>類>介面
    2.4.2.4第四步:在配置文件中開啟spring對註解事務的支持
        <!-- 開啟spring對註解事務的支持 -->
        <tx:annotation-driven transaction-manager="transactionManager"/> 
        2.5基於純註解的聲明式事務控制(配置方式)重點
        2.5.1環境搭建
        2.5.1.1第一步:拷貝必備的jar包到工程的lib目錄

        2.5.1.2第二步:創建一個類用於載入spring的配置並指定要掃描的包
        /**
         * 用於初始化spring容器的配置類
         */
        @Configuration
        @ComponentScan(basePackages="com.baidu")
        public class SpringConfiguration {

        }
    2.5.1.3第三步:創建資料庫表和實體類
        和基於xml的配置相同。略
    2.5.1.4第四步:創建業務層介面和實現類並使用註解讓spring管理
        業務層介面和基於xml配置的時候相同。略

        /**
         * 賬戶的業務層實現類
         */
        @Service("accountService")
        public class AccountServiceImpl implements IAccountService {
            @Autowired
            private IAccountDao accountDao;

            @Override
            public Account findAccountById(Integer id) {
                return accountDao.findAccountById(id);
            }

            @Override
            public void transfer(String sourceName, String targeName, Float money) {
                //1.根據名稱查詢兩個賬戶
                Account source = accountDao.findAccountByName(sourceName);
                Account target = accountDao.findAccountByName(targeName);
                //2.修改兩個賬戶的金額
                source.setMoney(source.getMoney()-money);//轉出賬戶減錢
                target.setMoney(target.getMoney()+money);//轉入賬戶加錢
                //3.更新兩個賬戶
                accountDao.updateAccount(source);
                int i=1/0;
                accountDao.updateAccount(target);
            }
        }

    2.5.1.5第五步:創建Dao介面和實現類並使用註解讓spring管理
        Dao層介面和AccountRowMapper與基於xml配置的時候相同。略

        @Repository("accountDao")
        public class AccountDaoImpl implements IAccountDao {

            @Autowired
            private JdbcTemplate jdbcTemplate;
            
            @Override
            public Account findAccountById(Integer id) {
                List<Account> list = jdbcTemplate.query("select * from account where id = ? ",new AccountRowMapper(),id);
                	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一.vue基礎 "Vue的介紹及安裝和導入" "Vue的使用" "Vue成員獲取" "Vue中的迴圈以及修改差值表達式" "vue中methods,computed,filters,watch的總結" "Vue中組件" "Vue中插槽指令" "Vue部分編譯不生效,解決Vue渲染時候會閃一下" 二. ...
  • 1、絕對定位 絕對定位指的是通過規定HTML元素在水平和垂直方向上的位置來固定元素,基於絕對定位的元素不會占據空間。 絕對定位的位置聲明是相對於已定位的並且包含關係最近的祖先元素。如果當前需要被定為的元素沒有已定位的祖先元素作為參考值,則相對於整個網頁。 position:absolute; 1 < ...
  • 水平居中(包含塊中居中)1. 定寬,左右margin為auto。(常規流塊盒、彈性項目[不用定寬]) 例子:在box1盒子上設置寬,再設置margin:auto; 得到的效果: 2. 彈性盒設置justify-content: center,讓彈性項目在主軸上居中。(普遍適應) 例子:在其父元素上設 ...
  • 一、HTMLhtyper text markup language 即超文本標記語言超文本: 就是指頁面內可以包含圖片、鏈接,甚至音樂、程式等非文字元素。標記語言: 標記(標簽)構成的語言.網頁==HTML文檔,由瀏覽器解析,用來展示的靜態網頁:靜態的資源,如xxx.html 動態網頁:html代碼... ...
  • 垂死病中驚坐起,笑問 Bug 何處來?! 1、先是大寫字母作祟 前兩天發佈了「柒留言」v2.0.0 新版本,結果...你懂的嘛,沒有 Bug 的程式不是好程式,寫不出 Bug 的程式員不是好程式員。 那個,有一兩個小 Bug 很正常的啦。 有用戶反饋,收到了留言回覆的通知,但是點進去沒有內容。怎麼會 ...
  • meta標簽:description【對網站做簡單的描述,用戶是不可見】 <meta name="description" content="測試標簽、元素"/> meta標簽:keywords【關鍵詞,為了確保搜索引擎能正確的匹配到關鍵詞是要對準網頁主題,用戶不可見】 <meta name="ke ...
  • 一 Django的視圖函數view 一個視圖函數(類),簡稱視圖,是一個簡單的Python 函數(類),它接受Web請求並且返回Web響應。 響應可以是一張網頁的HTML內容,一個重定向,一個404錯誤,一個XML文檔,或者一張圖片。 無論視圖本身包含什麼邏輯,都要返迴響應。代碼寫在哪裡也無所謂,只 ...
  • 回顧 -Hibernate框架 ORM: 對象關係映射.把資料庫表和JavaBean通過映射的配置文件映射起來, 操作JavaBean對象,通過映射的配置文件生成SQL語句,自動執行.操作資料庫. 1: 類名.hbm.xml 映射配置文件. 2: hibernate.cfg.xml 核心配置文件. ... ...
一周排行
    -Advertisement-
    Play Games
  • 1. 說明 /* Performs operations on System.String instances that contain file or directory path information. These operations are performed in a cross-pla ...
  • 視頻地址:【WebApi+Vue3從0到1搭建《許可權管理系統》系列視頻:搭建JWT系統鑒權-嗶哩嗶哩】 https://b23.tv/R6cOcDO qq群:801913255 一、在appsettings.json中設置鑒權屬性 /*jwt鑒權*/ "JwtSetting": { "Issuer" ...
  • 引言 集成測試可在包含應用支持基礎結構(如資料庫、文件系統和網路)的級別上確保應用組件功能正常。 ASP.NET Core 通過將單元測試框架與測試 Web 主機和記憶體中測試伺服器結合使用來支持集成測試。 簡介 集成測試與單元測試相比,能夠在更廣泛的級別上評估應用的組件,確認多個組件一起工作以生成預 ...
  • 在.NET Emit編程中,我們探討了運算操作指令的重要性和應用。這些指令包括各種數學運算、位操作和比較操作,能夠在動態生成的代碼中實現對數據的處理和操作。通過這些指令,開發人員可以靈活地進行算術運算、邏輯運算和比較操作,從而實現各種複雜的演算法和邏輯......本篇之後,將進入第七部分:實戰項目 ...
  • 前言 多表頭表格是一個常見的業務需求,然而WPF中卻沒有預設實現這個功能,得益於WPF強大的控制項模板設計,我們可以通過修改控制項模板的方式自己實現它。 一、需求分析 下圖為一個典型的統計表格,統計1-12月的數據。 此時我們有一個需求,需要將月份按季度劃分,以便能夠直觀地看到季度統計數據,以下為該需求 ...
  • 如何將 ASP.NET Core MVC 項目的視圖分離到另一個項目 在當下這個年代 SPA 已是主流,人們早已忘記了 MVC 以及 Razor 的故事。但是在某些場景下 SSR 還是有意想不到效果。比如某些靜態頁面,比如追求首屏載入速度的時候。最近在項目中回歸傳統效果還是不錯。 有的時候我們希望將 ...
  • System.AggregateException: 發生一個或多個錯誤。 > Microsoft.WebTools.Shared.Exceptions.WebToolsException: 生成失敗。檢查輸出視窗瞭解更多詳細信息。 內部異常堆棧跟蹤的結尾 > (內部異常 #0) Microsoft ...
  • 引言 在上一章節我們實戰了在Asp.Net Core中的項目實戰,這一章節講解一下如何測試Asp.Net Core的中間件。 TestServer 還記得我們在集成測試中提供的TestServer嗎? TestServer 是由 Microsoft.AspNetCore.TestHost 包提供的。 ...
  • 在發現結果為真的WHEN子句時,CASE表達式的真假值判斷會終止,剩餘的WHEN子句會被忽略: CASE WHEN col_1 IN ('a', 'b') THEN '第一' WHEN col_1 IN ('a') THEN '第二' ELSE '其他' END 註意: 統一各分支返回的數據類型. ...
  • 在C#編程世界中,語法的精妙之處往往體現在那些看似微小卻極具影響力的符號與結構之中。其中,“_ =” 這一組合突然出現還真不知道什麼意思。本文將深入剖析“_ =” 的含義、工作原理及其在實際編程中的廣泛應用,揭示其作為C#語法奇兵的重要角色。 一、下劃線 _:神秘的棄元符號 下劃線 _ 在C#中並非 ...