SSM框架系列学习总结3之Spring DAO

在这里先把AOP的内容总结完毕!

SpringAOP的五种通知方式
  1. 后置通知: 执行目标对象业务方法之后执行服务代码
    2.方法正常返回通知:
    3.方法抛出异常通知:
    4.环绕通知:
    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:context="http://www.springframework.org/schema/context"

       xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.0.xsd

           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
           ">

    <!-- 注册UserDao对象 -->
    <bean id="userDao" class="com.wtu.spring.aop.before.UserDaoImpl">
    </bean>

    <!-- 配置切面 -->
    <bean id="myLog" class="com.wtu.spring.aop.before.MyLog"/>

    <!--
        aop:config: 配置代理对象
        proxy-target-class: 指底层的动态代理使用的是JDK, 还是CGLIB代理;
            true表示CGLIB代理, CGLIB代理不是说没有接口, spring会根据目标对象自动生成一个接口
        aop:pointcut: 配置切入点
        execution: 确定切入点的方法
        aop:aspect: 配置切面如何去切切入点
        pointcut-ref: 切面中的方法去切哪个目标对象中的切入点
    -->
    <aop:config proxy-target-class="true">
        <aop:pointcut expression="execution(* com.wtu.spring.aop.before.UserDaoImpl.a*(..))" id="xxx"/>
       <!-- <aop:around />
             <aop:after-returning>
             <aop:after-throwing> -->
        <aop:aspect ref="myLog">
            <aop:after method="writeConsole" pointcut-ref="xxx"/>
        </aop:aspect>
    </aop:config>

</beans>

切面对象:

public class MyLog {
    @SuppressWarnings("deprecation")
    public void writeConsole() {
        System.out.println(new Date().toLocaleString());
    }
}

目标对象, 执行核心代码:

public class UserDaoImpl implements UserDao {

    @Override
    public void addUser() {

//        if (true) {
//            throw new RuntimeException("测试一下遇到异常执行情况");
//        }

        System.out.println("添加用户...");
    }

    @Override
    public void deleteUser() {
        System.out.println("删除用户");
    }
}

测试类:

        // 启动Ioc容器
        ApplicationContext ac = new ClassPathXmlApplicationContext(
                new String[]{"com/wtu/spring/aop/before/spring3.0.xml"}
        );

        UserDao userDao = (UserDao) ac.getBean("userDao");
        userDao.addUser();

        System.out.println(userDao.getClass());
        //class com.wtu.spring.aop.before.UserDaoImpl$$EnhancerByCGLIB$$aa48c241

运行结果:
运行结果.png

SpringAOP环绕通知

环绕通知默认情况下代理对象只会调用一次服务代码,连目标对象的业务方法都不会调用。
因此, 我们需要借助一个类, 去手动调用
ProceedingJoinPoint :使用该类的一个对象作为切面中方法的形式参数传入,再通过该对象的proceed()方法实现对目标对象方法的调用.
切面:

public class MyLog {
    /**
     * 环绕通知得在切面的方法中带上一个参数, 类型是ProceedingJoinPoint
     * 通过该对象proceed方法来调用目标对象的业务方法
     */
    @SuppressWarnings("deprecation")
    public void writeConsole(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println(new Date().toLocaleString());
        pjp.proceed(); // 相当于调用目标对象的切入点方法
        System.out.println(new Date().toLocaleString());
    }
}

Spring配置:

    <!-- 
        aop:config: 配置代理对象
        proxy-target-class: 指底层的动态代理使用的是JDK, 还是CGLIB代理,
        true表示CGLIB代理, CGLIB代理不是说没有接口, spring会根据目标对象自动生成一个接口
        aop:pointcut: 配置切入点
        execution: 确定切入点的方法
        aop:aspect: 配置切面如何去切切入点
        pointcut-ref: 切面中的方法去切哪个切入点 
    -->
    <aop:config proxy-target-class="true">
        <aop:pointcut expression="execution(* com.wtu.spring.aop.around.UserDaoImpl.a*(..))" id="xxx"/>
        <aop:aspect ref="myLog">
            <aop:around method="writeConsole" pointcut-ref="xxx"/>
        </aop:aspect>
    </aop:config>

运行结果:

2018-1-21 12:47:58
增加用户...
2018-1-21 12:47:58

AOP 注解

首先是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:context="http://www.springframework.org/schema/context"

       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.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-3.0.xsd">

    <!-- 开启Spring注解的功能 -->
    <context:annotation-config/>
    <!-- 让springIOC容器自动去扫描某一个包, 创建该包下的bean对象 -->
    <context:component-scan base-package="com.wtu.spring.aop.annotation"/>

    <!--可以理解为让@Before @After 生效 -->
    <aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>

切面:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 切面
 *
 * @Author menglanyingfei
 * @Created on 2018.01.17 17:06
 */
@Component
@Aspect
public class MyLog {
    /**
     * 环绕通知得在切面的方法中带上一个参数, 类型是ProceedingJoinPoint
     * 通过该对象proceed方法来调用目标对象的业务方法
     */
    @SuppressWarnings("deprecation")
    @Around(value = "execution(* com.wtu.spring.aop.annotation.UserDaoImpl.addUser(..))")
    public void writeConsole(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println(new Date().toLocaleString());
        pjp.proceed(); // 相当于调用目标对象的切入点方法
        System.out.println(new Date().toLocaleString());
    }

    @SuppressWarnings("deprecation")
    @Before(value = "execution(* com.wtu.spring.aop.annotation.UserDaoImpl.deleteUser(..))")
    public void writeConsole() throws Throwable {
        System.out.println(new Date().toLocaleString());
    }
}

目标对象的代码:

import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Repository;

/**
 * @Author menglanyingfei
 * @Created on 2018.01.17 15:01
 */
@Repository
public class UserDaoImpl implements UserDao {

    @Override
    @Pointcut
    public void addUser() {
        System.out.println("增加用户...");
    }

    @Override
    @Pointcut
    public void deleteUser() {
        System.out.println("删除用户");
    }
}

AOP各模块图.jpeg

AOP术语.png
Pointcut.jpeg
execution.jpeg

AOP各种注解总结:
SpringAOP的注解形式:
@Aspect: 一般使用在切面的类名上面,作用是指定该类是一个切面
@PointCut:配置在目标对象的方法上面, 表示该方法是一个切入点
@Around @After @Before @After-returning @After-throwing
配置在切面的方法上面, 表示何种通知方式.

Spring DAO模块

Spring 数据访问, 因为Spring提供了对事务的支持!
所以, 我们首先来认识事务!

什么是DAO?

DAO.jpeg

事务的基本概念

事务.jpeg

将一系列对数据库的操作进行捆绑,其中所有的操作要么全部执行成功, 要么全部执行不成功。
ACID特性
原子性 Atomicity
一致性 Consistency
隔离性 Isolation
持久性 Durability

Mysql中的事务

mysql会将一条sql语句当成是一个完整的事务!
Mysql中对事务操作:
start transaction – 开启事务
commit – 提交事务
rollback – 回滚事务

JDBC中对于事务的操作

对事务的管理在同一个Connection对象中
conn.setAutoCommit(false); jdbc中开启事务
conn.commit(); 提交事务
conn.rollback(); 回滚事务

代码示例:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
 * @Author menglanyingfei
 * @Created on 2018.01.18 12:44
 */
public class TransactionTest {
    public static void main(String[] args) {
        /*
            JDBC中事务的使用
         */
        Connection conn = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql:///spring_day03",
                    "root", "lxy");
            // 开启事务
            conn.setAutoCommit(false);
            // zhang给li转账500元
            String sql = "update account set balance = balance + ? where username=?";
            PreparedStatement pstmt = conn.prepareStatement(sql);

            // 给zhang减去500
            pstmt.setInt(1, -500);
            pstmt.setString(2, "zhang");
            pstmt.executeUpdate();

//            int i = 10 / 0;

            // 给li增加500
            pstmt.setInt(1, 500);
            pstmt.setString(2, "li");
            pstmt.executeUpdate();
            // 提交事务
            conn.commit();
        } catch (Exception e) {
            // 事务回滚
            try {
                conn.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }
    }
}
数据库并发访问时引起的问题

脏读
不可重复读
虚读/幻读
脏读.jpeg

脏读.png
不可重复读.png
幻读.png

1.脏读 一个事务读取了另一个事务未提交的数据 绝对不允许存在
2.不可重复读 : 一个事务对某一条记录的两次读取结果不一致,原因是另一个事务在两次读取期间对该记录进行了修改,Oracle数据库中就有这种问题, 对应数据库update操作
3.虚读/幻读: 一个事务对某一张表的两次读取结果不一致,原因是另一个事务在两次读取期间对该表进行了insert 或者 delete操作 mysql中就有这种问题

事务隔离级别.png

针对数据库并发访问的问题, 出现了隔离级别的概念
1.serializable 串行化 数据库不支持并发访问, 隔离级别最高,效率最低 不推荐使用
2.repeatable read 可重复读, mysql默认隔离级别
3.Read Commited 读已提交的数据, Oracle的默认隔离级别
4.Read uncommited 读未提交的数据, 出现脏读, 效率是最高的 但是不推荐使用

事务一般作用在javaWeb的service层.

Spirng DAO模块之Spring管理事务

Spring框架提供了一个事务管理类,通过该类来进行事务的管理
DataSourceTransactionManager

Spring中对事务的声明全部在配置文件中:
其中包括:
配置事务管理器
配置数据源
注册事务切面
配置aop代理

<?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:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"

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

    <!-- 注册UserDaoImpl -->
    <bean id="userDao" class="com.wtu.spring.transaction.xml.UserDaoImpl"/>

    <!-- 配置c3p0数据源 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql:///spring_day03"></property>
        <property name="user" value="root"></property>
        <property name="password" value="lxy"></property>
    </bean>

    <!-- 注册事务管理器对象 -->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 注册事务切面 
        transaction-manager:需要引入一个事务管理器
    -->
    <tx:advice transaction-manager="dataSourceTransactionManager" id="xxx">
        <tx:attributes>
            <!--
                name: 将事务作用在哪些方法上面, 这个属性必须有
                isolation="DEFAULT": 表示spring事务的隔离级别, 默认跟使用的数据库一个级别, 一般省略
                propagation="REQUIRED": 表示事务的边界,当service有了事务以后, dao中就不用开启事务了
                read-only="false": 如果是true, 表示不能增删改, 只能读; 如果是false, 都可以
                timeout="-1": 事务的持续时间和使用的数据库一致
                rollback-for="": 表示事务遇到什么异常进行回滚
                no-rollback-for="": 表示事务遇到什么异常不回滚
                除了name, 其他都可以省略
             -->
            <tx:method name="*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

    <!-- 配置AOP代理 
        aop:advisor  一般是系统定义的切面
        aop:aspect   一般是自己定义的切面
    -->
    <aop:config proxy-target-class="true">
        <!-- 哪些方法需要添加事务 -->
        <aop:pointcut id="pointId"
                 expression="execution(* com.wtu.spring.transaction.xml.UserDaoImpl.*(..))"/>
        <aop:advisor advice-ref="xxx" pointcut-ref="pointId"/>
    </aop:config>
</beans>

目标对象所在类:

public class UserDaoImpl implements UserDao {
    @Override
    public void addUser() {
        System.out.println("增加用户...");
    }

    @Override
    public void deleteUser() {
        System.out.println("删除用户...");
    }
}

测试类:

public static void main(String[] args) {
        // 启动Ioc容器
        ApplicationContext ac = new ClassPathXmlApplicationContext(
                new String[]{"com/wtu/spring/transaction/xml/spring3.0.xml"}
        );

        UserDao userDao = (UserDao) ac.getBean("userDao");
        userDao.addUser();
    }

测试成功!
配置成功.png

Spring DAO模块之Spring整合JDBC

Spring Dao模块提供了一个JDBC模板,那么通过这个模板操作数据库,有点类似于QueryRunner.
数据访问.png

Spring的Dao模块提供了一个类JdbcTemplate:
该类中三个方法:
update(String sql, Object… args) 增删改
query(String sql, RowMapper rm, Object… args)
queryForObject 查询单个对象
其中的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_day03?characterEncoding=utf8"/>
        <property name="user" value="root"/>
        <property name="password" value="lxy"/>
    </bean>

    <!-- 注册JDBC模板对象  -->
    <bean id="jt" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 注册UserDao对象  -->
    <bean id="userDao" class="com.wtu.spring.dao.UserDaoImpl">
        <property name="jdbcTemplate" ref="jt"/>
    </bean>

DAO数据操作类:

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

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

/**
 * @Author menglanyingfei
 * @Created on 2018.01.17 15:01
 */

public class UserDaoImpl implements UserDao {
    /*
        Spring的Dao模块提供了JdbcTemplate
        该类中三个方法:
        update(String sql, Object... args) 增删改
        query(String sql, RowMapper rm, Object... args)
        queryForObject 查询单个对象
     */
    private JdbcTemplate jdbcTemplate;

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

    @Override
    public void addUser(Customer customer) {
        String sql = "insert into `t_customer` values(?,?,?,?,?,?,?)";
        Object[] objects = {customer.getId(), customer.getName(), customer.getGender(),
            customer.getBirthday(), customer.getCellphone(), customer.getEmail(), customer.getDescription()};

        jdbcTemplate.update(sql, objects);
    }

    @Override
    public void deleteUser(String id) {
        System.out.println("删除用户");
    }

    /*
        查询单个对象, RowMapper是个接口
     */
    @Override
    public Customer findCustomer(String id) {
        String sql = "select * from `t_customer` where cid = ?";
        Object[] objects = {id};
        return jdbcTemplate.queryForObject(sql, new RowMapper<Customer>() {
            /*
             * rs:查询结果集
             * rowNum: 表示当前结果集是第几行, 0表示第一行
             * 如果是单个对象, rowNum永远等于零
             * 下面这个方法表示循环遍历结果集, 也就是不需要我们再去写while循环
             */
            @Override
            public Customer mapRow(ResultSet rs, int i) throws SQLException {
                System.out.println("rowNum = " + i);
                //手工及解析结果集  封装Customer对象
                Customer c = new Customer();
                c.setId(rs.getString(1));
                c.setName(rs.getString(2));
                c.setGender(rs.getString(3));
                c.setBirthday(rs.getDate(4));
                c.setCellphone(rs.getString(5));
                c.setEmail(rs.getString(6));
                c.setDescription(rs.getString(7));
                return c;
            }

        }, objects);
    }

    @Override
    public List<Customer> findAllCustomer() {
        String sql = "select * from `t_customer` ";

        return jdbcTemplate.query(sql, new RowMapper<Customer>() {
            /*
             * rs:查询结果集
             * rowNum: 表示当前结果集是第几行, 0表示第一行
             * 如果是单个对象, rowNum永远等于零
             * 下面这个方法表示循环遍历结果集, 也就是不需要我们再去写while循环
             */
            @Override
            public Customer mapRow(ResultSet rs, int j) throws SQLException {
                System.out.println(j);

                //手工解析结果集  封装Customer对象
                Customer c = new Customer();
                c.setId(rs.getString(1));
                c.setName(rs.getString(2));
                c.setGender(rs.getString(3));
                c.setBirthday(rs.getDate(4));
                c.setCellphone(rs.getString(5));
                c.setEmail(rs.getString(6));
                c.setDescription(rs.getString(7));
                return c;
            }
        });
    }
}
SpringDao+事务: 通过注解形式

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:context="http://www.springframework.org/schema/context"
        xmlns:tx="http://www.springframework.org/schema/tx"

        xsi:schemaLocation="
          http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

          http://www.springframework.org/schema/aop
          http://www.springframework.org/schema/aop/spring-aop-3.0.xsd

          http://www.springframework.org/schema/tx
          http://www.springframework.org/schema/tx/spring-tx-3.0.xsd

          http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!--  注册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_day03?characterEncoding=utf8"/>
        <property name="user" value="root"/>
        <property name="password" value="lxy"/>
    </bean>

    <!-- 注册JDBC模板对象  -->
    <bean id="jt" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

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

    <!-- 开启注解 -->
    <context:annotation-config/>

    <!-- 自动扫描 -->
    <context:component-scan base-package="com.wtu.spring.dao.annotation"/>

    <!-- 开启AOP通知的注解 -->
    <aop:aspectj-autoproxy/>

    <!-- 开启事务切面的注解 -->
    <tx:annotation-driven transaction-manager="dataSourceTransactionManager"
        proxy-target-class="true"/>
</beans>

封装数据的实体类:

public class Customer {
    private String id;
    private String name;
    private String gender;
    private Date birthday;
    private String cellphone;
    private String email;
    private String description;
    // getter and setter omitted
}

dao数据操作类:

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

import javax.annotation.Resource;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 * @Author menglanyingfei
 * @Created on 2018.01.17 15:01
 */
/*
 * @Transactional加在类名上面: 表示该类中所有的方法都要加上事务
 * @Transactional:该注解一般写在service层中的实现类上
 */
//@Transactional
@Repository
public class UserDaoImpl implements UserDao {
    /*
        Spring的Dao模块提供了JdbcTemplate
        该类中3个方法:
        update(String sql, Object... args) 增删改
        query(String sql, RowMapper rm, Object... args) 查询所有
        queryForObject          查询单个对象
     */
    @Resource
    private JdbcTemplate jt;

    @Transactional
    @Override
    public void addUser(Customer c) {
        String sql = "insert into `t_customer` values(?,?,?,?,?,?,?)";
        Object[] obj = {c.getId(),c.getName(),c.getGender(),
                c.getBirthday(),c.getCellphone(),c.getEmail(),c.getDescription()};
        jt.update(sql, obj);
    }

    @Override
    public void deleteUser(String id) {
        System.out.println("删除用户");
    }

    /**
     * 查询单个对象
     * rowMapper:是个接口
     */
    @Override
    public Customer findCustomer(String id) {
        String sql = "select * from `t_customer` where cid = ?";
        Object[] obj = {id};
        return jt.queryForObject(sql, new RowMapper<Customer>(){
            /*
             * rs:查询结果集
             * rowNum:表示当前结果集是第几行  0 表示第一行
             * 如果是单个对象  rowNum永远等于零
             * 下面这个方法表示循环遍历结果集   也就是不需要我们再去写while循环
             */
            public Customer mapRow(ResultSet rs, int rowNum)
                    throws SQLException {
                //手工解析结果集  封装Customer对象
                Customer c = new Customer();
                c.setId(rs.getString(1));
                c.setName(rs.getString(2));
                c.setGender(rs.getString(3));
                c.setBirthday(rs.getDate(4));
                c.setCellphone(rs.getString(5));
                c.setEmail(rs.getString(6));
                c.setDescription(rs.getString(7));
                return c;
            }
        }, obj);
    }

    @Override
    public List<Customer> findAllCustomer() {
        String sql = "select * from `t_customer` ";

        return jt.query(sql, new RowMapper<Customer>() {
            /*
             * rs:查询结果集
             * rowNum: 表示当前结果集是第几行, 0表示第一行
             * 如果是单个对象, rowNum永远等于零
             * 下面这个方法表示循环遍历结果集, 也就是不需要我们再去写while循环
             */
            @Override
            public Customer mapRow(ResultSet rs, int j) throws SQLException {
                //手工解析结果集  封装Customer对象
                Customer c = new Customer();

                c.setId(rs.getString(1));

                c.setName(rs.getString(2));
                c.setGender(rs.getString(3));
                c.setBirthday(rs.getDate(4));
                c.setCellphone(rs.getString(5));
                c.setEmail(rs.getString(6));
                c.setDescription(rs.getString(7));

                return c;
            }
        });
    }
}

测试主类:

        // 启动IOC容器
        ApplicationContext ac = new ClassPathXmlApplicationContext(
                new String[]{"com/wtu/spring/dao/annotation/spring3.0.xml"});

        UserDao userDao = (UserDao) ac.getBean("userDaoImpl");
        Customer c = userDao.findCustomer("no4");
        System.out.println(c);

注解总结:
Spring中的注解:
1.实例化对象的注解
@Component @Repository @Controller @Service
2.依赖注入
@Resource @Autowired
3.aop的注解
@After @Before @Around @After-returnning @After-throwing
@Aspect
@Pointcut
4.事务的注解
@Tranactional

完整代码见Github地址

https://github.com/menglanyingfei/SSMLearning/tree/master/spring_day03

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值