使用Spring进行Web应用开发(二)使用jdbc的持久层

使用mysql5.0作数据库,运行配置向导,将字符集设为utf-8,将mysql的jdbc driver包mysql-connector-java-3.1.11-bin.jar加入项目的classpath.

我们来完成一个用户User注册功能模块。

domain class: User 如下
package springapp.domain;

/**
 * User: Saro
 * Date: 2006-4-27
 * Time: 9:24:02
 */
public class User implements java.io.Serializable {

    private Long id;
    private String username;
    private String password;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
}
//………………………..
//其余field的getter/setter method省略
}

在WEB-INF下建立applicationContext.xml文件,在web.xml中添加如下配置:
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>

<!-- 于系统启动时,根据contextConfigLocation载入bean配置文件的listener-->
    <listener>
       <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

定义一个业务接口,UserService,代码如下:
package springapp;

import springapp.domain.User;

/**
 * User: Saro
 * Date: 2006-4-27
*/
public interface UserService {
    public void addUser(User user);
    public User getUserByUserName(String username);
}

因为其实现依赖dao,创建类UserJdbcDao:

package springapp.dao;

import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import springapp.domain.User;

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

/**
 * User: Saro
 * Date: 2006-4-27
*/
public class UserJdbcDao extends JdbcDaoSupport {
    public final static String INSERT_USER=
            "insert into T_User (username,password) values(?,?)";

    public final static String SELECT_USER_BYUSERNAME=
            "select id,username,password from T_User where username=?";

    public void save(final User user) {
        PreparedStatementCreator psc = new PreparedStatementCreator() {
            public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
                PreparedStatement p=con.prepareStatement(UserJdbcDao.INSERT_USER);
                p.setString(1,user.getUsername());
                p.setString(2,user.getPassword());
                return p;
            }
        };
        this.getJdbcTemplate().update(psc);
    }

    public static class UserRowMapper implements RowMapper {
        public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
            User user=new User();
            user.setId(new Long(rs.getLong(1)));
            user.setUsername(rs.getString(2));
            user.setPassword(rs.getString(3));
            return user;
        }
    }

    public User getByUsername(String username){
        List list=this.getJdbcTemplate().query(UserJdbcDao.SELECT_USER_BYUSERNAME,new String[]{username},new UserJdbcDao.UserRowMapper());
        if(list.size()==0){
            return null;
        }
        return (User)list.get(0);
    }
}

其在applicationContext.xml中定义如下:
<bean id="userDao" class="springapp.dao.UserJdbcDao" >
        <property name="dataSource" ref="dataSource" />
</bean>

UserService的实现类:
package springapp;

import springapp.domain.User;
import springapp.dao.UserJdbcDao;

/**
 * User: Saro
 * Date: 2006-4-27
*/
public class UserServiceImpl implements UserService {

    public void addUser(User user) {
        this.userDao.save(user);
    }

    public User getUserByUserName(String username) {
        return this.userDao.getByUsername(username);
    }

    private UserJdbcDao userDao;

    public void setUserDao(UserJdbcDao userDao) {
        this.userDao = userDao;
    }
}
其在applicationContext.xml中定义如下:
<bean id="userService" class="springapp.UserServiceImpl" >
        <property name="userDao" ref="userDao" />
</bean>

为了事务控制,加入如下配置:
没有的事务控制的普通bean。
<bean id=" userServiceTarget" class="springapp.UserServiceImpl" >
        <property name="userDao" ref="userDao" />
</bean>
Jdbc事务管理器
   <bean
 id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

事务代理工厂类,用于生产其方法有事务控制的代理bean。
<bean
 id="userService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager" ref="txManager"/>
        <property name="target" ref="userServiceTarget"/>
        <property name="transactionAttributes">
            <props>
                <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="*">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>

最后applicationContext.xml如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<bean
 id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <property name="driverClass" value="com.mysql.jdbc.Driver" />
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/example" />
        <property name="user" value="root" />
        <property name="password" value="1" />
        <property name="initialPoolSize" value="1" />
        <property name="minPoolSize" value="2" />
        <property name="maxPoolSize" value="5" />
        <property name="checkoutTimeout" value="5000" />
        <property name="maxIdleTime" value="1800" />
        <property name="idleConnectionTestPeriod" value="3000" />
        <property name="acquireIncrement" value="5" />
    </bean>

    <bean id="userDao" class="springapp.dao.UserJdbcDao" >
        <property name="dataSource" ref="dataSource" />
    </bean>


    <bean id="userServiceTarget" class="springapp.UserServiceImpl" >
        <property name="userDao" ref="userDao" />
    </bean>

<bean
 id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

<bean
 id="userService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager" ref="txManager"/>
        <property name="target" ref="userServiceTarget"/>
        <property name="transactionAttributes">
            <props>
                <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="*">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>

</beans>
建表T_User:
DROP TABLE IF EXISTS `example`.`t_user`;
CREATE TABLE  `example`.`t_user` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `username` varchar(45) NOT NULL default '',
  `password` varchar(45) NOT NULL default '',
  PRIMARY KEY  (`id`),
  UNIQUE KEY `Index_2` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

现在可以写一个UserSerivce的测试类了,
package springapp;

import junit.framework.TestCase;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import springapp.domain.User;

/**
 * User: Saro
 * Date: 2006-4-27
 */
public class UserServiceTest extends TestCase {

    private ApplicationContext context;

    public Object getBean(String beanName){
        if(context==null){
            context=new FileSystemXmlApplicationContext("WEB-INF/applicationContext.xml");
        }
        return context.getBean(beanName);
    }

    public UserService getUserService(){
        return (UserService)this.getBean("userService");
    }

    public void testAddUser(){
        User user=new User();
        user.setUsername("tester01");
        user.setPassword("1234");
        this.getUserService().addUser(user);
    }

    public void findUserByUserName(){
        User user=new User();
        user.setUsername("tester02");
        user.setPassword("1234");
        this.getUserService().addUser(user);
        User loadedUser=this.getUserService().getUserByUserName(user.getUsername());
        assertNotNull(loadedUser);
    }

}

SimpleFormController的生命周期:

Get生命周期

Post的生命周期

运行2个测试,顺利通过,持久层和业务层的代码已经写完。下面我们开始写web层的代码。
首先需要一个用于用户注册的Controller:

package springapp.web;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
import springapp.UserService;
import springapp.domain.User;

/**
 * User: Saro
 * Date: 2006-4-27
 */
public class RegUserController extends SimpleFormController {
   
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
//在表单绑定到command对象上时,空的表单字串作null处理
        binder.registerCustomEditor(String.class,new StringTrimmerEditor(true));
    }

    protected ModelAndView onSubmit(Object command) throws Exception {
        User user=(User)command;
        this.userService.addUser(user);
        return new ModelAndView(this.getSuccessView());
    }

    private UserService userService;

    public void setUserService(UserService userService) {
        this.userService = userService;
    }
}

为用户注册添加一个Validator,禁止输入空的用户名称。
package springapp.web;

import org.springframework.validation.Validator;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import springapp.domain.User;

/**
 * User: Saro
 * Date: 2006-4-27
 */
public class RegValidator implements Validator {
    public boolean supports(Class clazz) {
        return clazz.isAssignableFrom(User.class);
    }

    public void validate(Object obj, Errors errors) {
        User user=(User)obj;
         // required.username 在classpath根目录下的messages.properties中定义
//第4个参数为默认消息
        ValidationUtils.rejectIfEmpty(errors,"username","required.username","用户名称不能为空");
    }
}

springapp-servlet.xml中的配置:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

    <bean
 id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="exceptionMappings">
            <props>
                <prop key="org.springframework.dao.DataAccessException">/dataAccessFailure.jsp</prop>
                <prop key="org.springframework.transaction.TransactionException">/dataAccessFailure.jsp</prop>
            </props>
        </property>
    </bean>

   
    <bean
 id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename" value="messages"/>
    </bean>


 <bean
 id="urlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <value>
                index.htm = welcomeController
                reg.htm = RegUserController
            </value>
        </property>
    </bean>

    <bean id="welcomeController" class="springapp.web.WelcomeController" />

    <bean id="RegUserController" class="springapp.web.RegUserController" >
        <property name="commandName" value="addUser" />
        <property name="commandClass" value="springapp.domain.User" />
        <property name="formView" value="/reg.jsp" />
        <property name="successView" value="/end.jsp" />
        <property name="userService" ref="userService" />
        <property name="validator" >
            <bean class="springapp.web.RegValidator" />
        </property>
    </bean>
</beans>

创建jsp文件reg.jsp(用于提交用户注册表单),end.jsp(通用结果显示页面)
reg.jsp如下:
<%--
  User: Saro
  Date: 2006-4-27
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<html>
  <head><title>用户注册</title></head>
  <body>用户注册
<spring:nestedPath path="addUser" >
  <form action="" method="post"><spring:bind path="username" >
   用户名:<input type="text" value="${status.value}" name="${status.expression}" /> ${status.errorMessage}<br/>
  </spring:bind>
      <spring:bind path="password" >
   密码:<input type="text" value="${status.value}" name="${status.expression}" /> ${status.errorMessage}</spring:bind>
      <input type="submit" value="提交"/>
  </form>
</spring:nestedPath>
  </body>
</html></spring:bind>
  </body>
</html>

运行tomcat,访问网址:http://localhost:8080/reg.htm

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 2

打赏作者

Saro

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值