学习《Spring 3.x 企业应用开发实战》Day-1
Day-1 记录自己学习spring的笔记
提要:根据《Spring 3.x 企业应用开发实战》开头一个用户登录的例子,按照上面敲的。
1.项目分层
dao:持久层
domain:领域对象(个人理解为数据表映射成一个Java类)
service:业务层
web:展现层
2.构建数据表
2.1 数据库采用MySql 5.x 版本
2.2 建立两个数据表 user 和 user_log 表 user 用来存放用户信息,user_log用来存放user登录信息
2.3 user:
user_log:
3.编写UserDao、LoginLogDao类
3.1 UserDao
1 package com.zwy.dao; 2 3 import java.sql.ResultSet; 4 import java.sql.SQLException; 5 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.jdbc.core.JdbcTemplate; 8 import org.springframework.jdbc.core.RowCallbackHandler; 9 import org.springframework.stereotype.Repository; 10 11 import com.zwy.domain.User; 12 13 /** 14 * 通过@Repository注解定义一个DAO 15 * */ 16 @Repository 17 public class UserDao { 18 @Autowired//自动注入JdbcTemplate 19 private JdbcTemplate jdbcTemplate; 20 21 /** 22 * 查询用户是否存在 23 * */ 24 public int getMacthCount(String username,String password){ 25 String sql="SELECT COUNT(*) FROM user WHERE user_name=? and password=? "; 26 return jdbcTemplate.queryForInt(sql, username,password); 27 } 28 /** 29 * 根据username找到相应的user 记录(对象) 30 * */ 31 public User findUserByUserName(final String username){ 32 String sql="SELECT id,user_name,credits FROM user WHERE user_name=?"; 33 final User user=new User(); 34 jdbcTemplate.query(sql, new Object[]{username}, new RowCallbackHandler() { 35 public void processRow(ResultSet reSet) throws SQLException { 36 user.setId(reSet.getInt("id")); 37 user.setUserName(reSet.getString("user_name")); 38 user.setCredits(reSet.getInt("credits")); 39 } 40 }); 41 return user; 42 } 43 /** 44 * 根据useid更新相应的user (对象)在数据库中的记录 45 * 更新积分,登录IP,登录时间 46 * */ 47 public void updateLoginInfo(User user){ 48 String sql="UPDATE user SET credits=?,last_ip=?,last_time=?" 49 +" WHERE id=?"; 50 jdbcTemplate.update(sql, user.getCredits(),user.getLastIp(),user.getLastTime(),user.getId()); 51 } 52 }
3.2 LoginLogDao类
package com.zwy.dao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import com.zwy.domain.UserLog; @Repository public class LoginLogDao { @Autowired private JdbcTemplate jdbcTemplate; /** * 插入一条登录记录 * */ public void insertLoginLog(UserLog user){ String sql="INSERT INTO user_log(user_id,ip,log_time)" +" VALUES (?,?,?)"; jdbcTemplate.update(sql,user.getUserId(),user.getIp(),user.getLogTime()); } }
省略了domain 实体类的代码
4.业务层UserService的代码
通过业务层组织持久化层的DAO完成业务逻辑操作
package com.zwy.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.zwy.dao.LoginLogDao; import com.zwy.dao.UserDao; import com.zwy.domain.User; import com.zwy.domain.UserLog; @Service public class UserService { @Autowired private UserDao userDao; @Autowired private LoginLogDao loginLogDao; /** * 登录业务 * */ public boolean userLogin(String username,String password){ int count=userDao.getMacthCount(username, password); return count>0; } /** * 根据username找到User对象 * */ public User finUserByUserName(String username){ User user=userDao.findUserByUserName(username); return user; } /** * 成功登录,更新user的积分并添加到user_log * */ public void successLoginLog(User user){ if(user!=null){ user.setCredits(5+user.getCredits()); UserLog userLog=new UserLog(); userLog.setUserId(user.getId()); userLog.setIp(user.getLastIp()); userLog.setLogTime(user.getLastTime()); userDao.updateLoginInfo(user); loginLogDao.insertLoginLog(userLog); } } }
5.配置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:p="http://www.springframework.org/schema/p" 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-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/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <!--1. 扫描类包,把标注spring注解的类自动转化成bean,同时完成bean的注入 --> <context:component-scan base-package="com.zwy.dao"/> <context:component-scan base-package="com.zwy.service" /> <!-- 2.定义一个使用DBCP的数据源 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="com.mysql.jdbc.Driver" p:url="jdbc:mysql://192.168.1.106:3306/spring" p:username="root" p:password="123456" /> <!-- 3.定义Spring-JDBC模板bean--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" p:dataSource-ref="dataSource" /> <!--4.配置事务管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource" /> <!--5.配置AOP,让service包下的方法处于增强事务中--> <aop:config proxy-target-class="true"> <aop:pointcut expression=" execution(* com.zwy.service..*(..))" id="serviceMethod"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/> </aop:config> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*"/> </tx:attributes> </tx:advice> </beans>
6.在Junit4下测试Service的方法
package com.zwy.service; import java.util.Date; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.zwy.domain.User; @RunWith(SpringJUnit4ClassRunner.class)//1.基于junit4的spring测试框架 @ContextConfiguration(locations={"/applicationContext.xml"})//2.启动spring容器 public class TestService { @Autowired private UserService userService; @org.junit.Test public void userLogin(){ boolean b1=userService.userLogin("admin", "123456"); boolean b2=userService.userLogin("admin", "1111"); System.out.println(b1+","+b2); } @org.junit.Test public void findUser(){ User user=userService.finUserByUserName("admin"); System.out.println(user); } @Test public void successLog(){ User user=userService.finUserByUserName("admin"); user.setLastIp("192.168.1.101"); user.setLastTime(new Date()); userService.successLoginLog(user); } }
7.编写Web层,用到SpringMVC框架
ModelAndView 是这个包下的org.springframework.web.servlet.ModelAndView;不要搞成其他包下相同名字的类
package com.zwy.web; import java.util.Date; import javax.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.zwy.domain.User; import com.zwy.service.UserService; //标注成为springMVC controller @Controller public class LoginController { @Autowired private UserService userService; //来自处理index.html @RequestMapping(value="/index.html") public String loginPage(){ return "login"; } //来自处理loginCheck.html的请求 @RequestMapping(value="/loginCheck.html") public ModelAndView loginCheck(HttpServletRequest request,LoginCommod loginCommod){ boolean isLogin=userService.userLogin(loginCommod.getUsername(), loginCommod.getPassword()); if(isLogin){ User user=userService.finUserByUserName(loginCommod.getUsername()); user.setLastIp(request.getRemoteAddr()); user.setLastTime(new Date()); userService.successLoginLog(user); request.getSession().setAttribute("user", user); return new ModelAndView("main"); }else { //参数1:逻辑视图名 参数2:数据模型 ---参数3:数据对象 //request会以(数据模型,数据对象)的形势返回。 return new ModelAndView("login", "error", "用户名或者密码错误!"); } } }
1 package com.zwy.web; 2 //封装了form表单提交的信息 3 public class LoginCommod { 4 private String username; 5 private String password; 6 public String getUsername() { 7 return username; 8 } 9 public void setUsername(String username) { 10 this.username = username; 11 } 12 public String getPassword() { 13 return password; 14 } 15 public void setPassword(String password) { 16 this.password = password; 17 } 18 19 }
8配置web.xml
web容器自动启动Spring容器
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 3 <!--1. 从类路径下加载spring配置文件,classpath关键字特指类路径下加载 --> 4 <context-param> 5 <param-name>contextConfigLocation</param-name> 6 <param-value>classpath:applicationContext.xml</param-value> 7 </context-param> 8 <!-- 2.负责启动spring容器监听器,它将引用1处的上下文参数获得spring配置文件地址 --> 9 <listener> 10 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 11 </listener> 12 <!-- spring MVC主控制的servlet --> 13 <servlet> 14 <!-- spring MVC的配置文件的名字 serviletName-servlet.xml --> 15 <servlet-name>zwy</servlet-name> 16 <servlet-class> org.springframework.web.servlet.DispatcherServlet</servlet-class> 17 <!-- 18 1)load-on-startup元素标记容器是否在启动的时候就加载这个servlet(实例化并调用其init()方法)。 19 2)正数的值越小,该servlet的优先级越高,应用启动时就越先加载。 20 --> 21 <load-on-startup>2</load-on-startup> 22 </servlet> 23 <!-- spring MVC处理的URL --> 24 <servlet-mapping> 25 <servlet-name>zwy</servlet-name> 26 <url-pattern>*.html</url-pattern> 27 </servlet-mapping> 28 <welcome-file-list> 29 <welcome-file>index.jsp</welcome-file> 30 </welcome-file-list> 31 </web-app>
9.配置zwy-servlet.xml
放在WEB-INF目录下,放在src目录下报错
<?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:p="http://www.springframework.org/schema/p" 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 "> <!-- 1.扫描web包,应用Spring注解 --> <context:component-scan base-package="com.zwy.web" /> <!-- 2.配置视图解析器,将ModelAndView及字符串解析为具体的页面 prefix指定在视图名所添加的前缀 suffix指定在视图名后添加的后缀 InternalResourceViewResolver:通过在逻辑视图名前后加后缀 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:viewClass="org.springframework.web.servlet.view.JstlView" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" /> </beans>
**注意 加入log4j日志框架,否则Spring框架会报错