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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,928评论 6 509
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,748评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,282评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,065评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,101评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,855评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,521评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,414评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,931评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,053评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,191评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,873评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,529评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,074评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,188评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,491评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,173评论 2 357

推荐阅读更多精彩内容