JavaWeb——Spring 的操作数据库的 DAO模式

JavaWeb——Spring 系列

四、Spring AOP的 DAO

1、DAO 介绍

  • DAO,Data Access Object,顾名思义适用于操作数据库的。Spring 的 DAO 是 O/R Mapping 技术的一种实现。
  • Spring DAO 提供了如下几种抽象类:
  • 1)jdbcDaoSupport:JDBC DAO 抽象类,当设置好数据源之后,通过子类可以获得 jdbcTemplate 来访问数据库。
  • 2)HibernateDaoSupport:Hibernate DAO 抽象类,同样的配置号 Hibernate SessionFactory 后,通过子类可以获得 Hibernate 实现。
  • 3)jdoDaoSupport:JDO DAO 抽象类,同样需要配置 PersistenceManagerFactory,通过子类可以获得 jdoTemplate。

2、Spring DAO 简单实例

  • 首相建立一个 User 类,代码如下:
    //IntelliJ IDEA
    //Sprin01
    //User
    //2020/1/15
    // Author:御承扬
    //E-mail:[email protected]
    
    package com.myCode.DAOCode;
    
    public class User {
        private Integer id;
        private String name;
        private Integer age;
        private String sex;
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    
        public String getSex() {
            return sex;
        }
    }
    
  • 根据 User 的属性,在 MySQL 的是当数据库建立一个 user 表。
  • 新建一个接口抽象类和一个实现类,代码如下:
    package com.myCode.DAOCode;
    
    public interface UserDAOImpl {
        public void insertUser(User user);
    }
    
    package com.myCode.DAOCode;
    
    import javax.sql.DataSource;
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    public class UserDAO implements UserDAOImpl {
        private DataSource dataSource;
    
        public DataSource getDataSource() {
            return dataSource;
        }
    
        public void setDataSource(DataSource dataSource) {
            this.dataSource = dataSource;
        }
    
        @Override
        public void insertUser(User user) {
            String name = user.getName();
            Integer age = user.getAge();
            String sex = user.getSex();
            Connection conn = null;
            Statement stmt = null;
            try {
                conn = dataSource.getConnection();
                stmt = conn.createStatement();
                stmt.execute(String.format("INSERT INTO user(name,age,sex)VALUES( '%s',%d,'%s')", name, age, sex));
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                if(stmt!=null){
                    try{
                        stmt.close();
                    }catch (SQLException e){
                        e.printStackTrace();
                    }
                }
                if(conn != null){
                    try{
                        conn.close();
                    }catch (SQLException e){
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
  • 接着在 ApplicationContext.xml 中配置:
     <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8"/>
        <property name="username" value="root"/>
        <property name="password" value="******"/>
    </bean>
    <bean id="userDAO" class="com.myCode.DAOCode.UserDAO">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
  • 最后建立一个 Manager 类
    package com.myCode.DAOCode;
    
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.beans.factory.xml.XmlBeanFactory;
    import org.springframework.core.io.ClassPathResource;
    import org.springframework.core.io.Resource;
    
    public class DAOManager {
        public static void main(String[] args) {
            Resource resource = new ClassPathResource("applicationContext.xml");
            BeanFactory factory = new XmlBeanFactory(resource);
            User user = new User();
            user.setName("张三");
            user.setAge(20);
            user.setSex("男");
            UserDAO userDAO = (UserDAO)factory.getBean("userDAO");
            userDAO.insertUser(user);
            System.out.println("添加数据成功!!!");
        }
    }
    

3、基于 AOP的DAO 模式的 Spring 事务

  • Spring 的事务基于 AOP 实现的,由于 Spring 的 AOP 是以方法为单位的,所以 Spring 的事务属性就是对事务应用到方法上的策略描述。
  • 事务的管理分为:编程式事务管理和声明式事务管理。

3.1、编程式事务管理

  • Spring 中通过 PlatformTransactionManager 接口的事务管理器或 TransactionTemplate 实现编程式事务管理;后者更为符合 Spring 的模板模式。
  • 示例
  • 首先新建一个 TransactionExample,其代码如下:
    package com.myCode.DAOCode.transaction;
    import org.springframework.jdbc.datasource.DataSourceUtils;
    import org.springframework.transaction.PlatformTransactionManager;
    import org.springframework.transaction.TransactionStatus;
    import org.springframework.transaction.support.TransactionCallback;
    import org.springframework.transaction.support.TransactionTemplate;
    
    import javax.annotation.Resource;
    import javax.sql.DataSource;
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    @Resource(name = "transactionManager")
    public class TransactionExample {
        DataSource dataSource;  //注入数据源
        PlatformTransactionManager transactionManager; //注入事务管理器
        TransactionTemplate transactionTemplate; //注入TransactionTemplate 模板
    
        public void setDataSource(DataSource dataSource) {
            this.dataSource = dataSource;
        }
    
        public DataSource getDataSource() {
            return dataSource;
        }
    
        public void setTransactionManager(PlatformTransactionManager transactionManager) {
            this.transactionManager = transactionManager;
        }
    
        public PlatformTransactionManager getTransactionManager() {
            return transactionManager;
        }
    
        public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
            this.transactionTemplate = transactionTemplate;
        }
    
        public TransactionTemplate getTransactionTemplate() {
            return transactionTemplate;
        }
        public void transactionOperation(){
            transactionTemplate.execute(new TransactionCallback() {
                @Override
                public Object doInTransaction(TransactionStatus transactionStatus) {
                    Connection conn = DataSourceUtils.getConnection(dataSource);//获得数据库连接
                    try{
                        Statement stmt = conn.createStatement();
                        stmt.execute("insert into user(name,age,sex) values('小强',26,'男')");
                        int a=0;    //制造异常测试事务是否配置成功
                        a=9/a;
                        stmt.execute("insert into user(name,age,sex) values('Tonny',24,'女')");
                        System.out.println("执行成功");
                    }catch (Exception e){
                        transactionManager.rollback(transactionStatus);
                        System.out.println("操作执行失败,事务回滚!");
                        System.out.println("原因:"+e.getMessage());
                    }
                    return null;
                }
            });
        }
    }
    
  • 接着进行配置,配置代码如下:
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8"/>
        <property name="username" value="root"/>
        <property name="password" value="********"/>
    </bean>
    <!--定义 TransactionTemplate模板-->
    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="transactionManager"/>
        <property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"/>
    </bean>
    <!-- 定义事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!-- 为TransactionExample注入数据源 、事务管理器、TransactionTemplate模板-->
    <bean id="transactionExample"
          class="com.myCode.DAOCode.transaction.TransactionExample">
        <property name="dataSource" ref="dataSource"/>
        <property name="transactionManager" ref="transactionManager"/>
        <property name="transactionTemplate" ref="transactionTemplate"/>
    </bean>
    
  • 在建立一个 Manager类:
    package com.myCode.DAOCode.manager;
    
    import com.myCode.DAOCode.transaction.TransactionExample;
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class TransactionManage {
        public static void main(String[] args) {
            BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
            TransactionExample example = (TransactionExample)factory.getBean("transactionExample");
            example.transactionOperation();
        }
    }
    

3.2、声明式事务管理

  • Spring 用 TransactionProxyFactoryBean 完成声明式事务管理,示例如下:
  • 首先建立一个事务类,用于向 user 表插入数据,代码如下:
    package com.myCode.DAOCode.DAO;
    import com.myCode.DAOCode.bean.User;
    import org.springframework.jdbc.core.support.JdbcDaoSupport;
    
    public class AddDAO extends JdbcDaoSupport{
        public void addUser(User user){
            String sql = String.format("insert into user(name,age,sex) values('%s',%d,'%s')",user.getName(),user.getAge(),user.getSex());
            try{
                assert getJdbcTemplate() != null;
                getJdbcTemplate().execute(sql);
            }catch (Exception e){
                System.out.println("执行失败,原因:"+e.getMessage());
            }
        }
    }
    
  • 在 applicationContext.xml 文件中进行相关配置,如下:
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8"/>
        <property name="username" value="root"/>
        <property name="password" value="*******"/>
    </bean>
    <!-- 定义TransactionProxy -->
    <bean id="transactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager" ref="transactionManager"/>
        <property name="target">
            <bean class="com.myCode.DAOCode.DAO.AddDAO">
                <property name="dataSource" ref="dataSource"/>
            </bean>
        </property>
        <property name="proxyTargetClass" value="true"/>
        <property name="transactionAttributes">
            <props>
                <prop key="add*">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>
    
  • 创建一个 Manager 类应用刚刚的配置
    package com.myCode.DAOCode.manager;
    
    import com.myCode.DAOCode.DAO.AddDAO;
    import com.myCode.DAOCode.bean.User;
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class ProxyManager {
        public static void main(String[] args) {
            BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
            AddDAO addDAO = (AddDAO)factory.getBean("transactionProxy");
            User user = new User();
            user.setName("秋月白");
            user.setAge(27);
            user.setSex("未知");
            addDAO.addUser(user);
        }
    }
    

上一篇
下一篇

发布了146 篇原创文章 · 获赞 15 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_42896653/article/details/104007821