Spring学习3(1):Login页面之持久层

版权声明:本文real_Rickys原创文章,未经real_Rickys允许不得转载。 https://blog.csdn.net/real_Rickys/article/details/82864341

Spring学习3(1)

 maven的配置其实是不繁琐的,在学习了基本的环境配置后就可以正式对spring的业务层,持久层,展现层进行一个基本的了解。我是根据《精通Spring 4.x 企业应用开发实战一步步做的》,不过这本书所用的工具可能有一点和我所使用的不同(我的编辑器是eclipse。

基本配置

 由于是一个用户登陆页面,所以我们需要如下页面:

  1. login.jsp:用来进入登陆页面并且提交用户名密码表单到服务器。
  2. LoginController:用来判断用户是否存在以及密码是否匹配,如果不存在就重定向回login.jsp,如果存在就更新用户登陆时间以及增加用户积分,并定向到欢迎界面。
  3. main.jsp:当用户存在时,可以访问的欢迎界面。

 根据上述需求需要对数据进行设计,创建名为“sampledb”的数据库,并创建所用的两张表格,具体代码如下:

use sampledb;
create table t_user(
	user_id int auto_increment primary key,
    user_name varchar(30),
    credits int,
    password varchar(32),
    last_visit datetime,
    last_ip varchar(23)
)engine=InnoDB;

create table t_login_log(
	login_log_id int auto_increment primary key,
    user_id int,online_goodsonline_goods
    ip varchar(23),
    login_datetime datetime
)engine=innoDB;

insert into t_user(user_name, password) 
values('admin', '123456');

commit;

 这里不再给出工程创建的过程,不过给出pom.xml的内容:

...
<properties>
  	<spring.version>4.1.6.RELEASE</spring.version>
  	<servlet.version>2.5</servlet.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
    	<groupId>org.springframework</groupId>
    	<artifactId>spring-core</artifactId>
    	<version>${spring.version}</version>
    </dependency>
     <dependency>
    	<groupId>org.springframework</groupId>
    	<artifactId>spring-beans</artifactId>
    	<version>${spring.version}</version>
    </dependency>
    <dependency>
    	<groupId>mysql</groupId>
    	<artifactId>mysql-connector-java</artifactId>
    	<version>5.1.29</version>
    </dependency>
	    <dependency>
	    <groupId>commons-dbcp</groupId>
	    <artifactId>commons-dbcp</artifactId>
	    <version>1.4</version>
	</dependency>
	<dependency>
	    <groupId>javax.servlet</groupId>
	    <artifactId>servlet-api</artifactId>
	    <version>2.5</version>
	    <scope>provided</scope>
	</dependency>
	<dependency>
	    <groupId>jstl</groupId>
	    <artifactId>jstl</artifactId>
	    <version>1.2</version>
	</dependency>
  </dependencies>
  ...

需要注意的是:

  1. 这里的< version >可以去Maven Repository去自行查找,这里的版本如果本机没有maven就会自动下载。
  2. 这里在测试(maven install)时可能会出现:“No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?”错误,可以参考这个stackoverflow的回答解决,其实就是在window->reference里配置jre时要用jdk的地址而不是jre的地址。

持久层

 持久层是负责数据的访问和操作的,data access object(DAO)类被上层的业务层使用,这里使用spring jdbc作为Object-relational mapping(ORM)。

建立领域对象

 Domain Object也被称为实体类,代表了业务的状态,贯穿了展现层,业务层和持久层。它使数据库表操作以面向对象的方式进行,它不一定等同于数据库表。
 这里我们需要两个领域对象,刚好对应两张表,并且每个字段对应一个对象属性。
 那么首先在main/java/com/smart(这是我的工程路径/com/smart可以自己取)下创建一个新的package:domian,而后在其下创建User.java代码如下:

package com.smart.domain;
import java.io.Serializable;
import java.util.Date;
//领域对象为了序列化,一般要实现Serializable接口

public class User implements Serializable{
	private int userId, credits;
	private String userName, password, lastIp;
	private Date lastVisit;
	public void setCredits(int credits) {
		this.credits = credits;
	}
	public Date getLastVisit() {
		return this.lastVisit;
	}
	//剩下的方法以此类推
}

 和LoginLog.java:

package com.smart.domain;
import java.io.Serializable;
import java.util.Date;
public class LoginLog implements Serializable{
	private int LoginLogId, userId;
	private String ip;
	private Date loginDate;
}

建立Dao

 我们用Dao来控制对数据的操作,这里User的Dao需要的方法如下:

  1. getMatchCount():根据用户名和密码获取匹配的用户数
  2. findUserByUserName():根据用户名获取User object
  3. updateLoginLog():更新用户信息(积分,登陆ip等)

 那么我们首先先在domain同一级目录下创建dao目录,而后在其目录下创建UserDao.java,代码如下:

package com.smart.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.stereotype.Repository;
import com.smart.domain.User;

@Repository
public class UserDao{
	private JdbcTemplate jdbcTemplate;
	private final static String MATCH_COUNT_SQL = " SELECT count(*) FROM " +
			" t_user WHERE user_name =? and password =? ";
	private final static String UPDATE_LOGIN_INFO_SQL = " UPDATE t_user SET " + 
			" last_visit=?,last_ip=?,credits=? WHERE user_id =? ";
	@Autowired
	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}
	
	public int getMatchCount(String userName, String password) {
		return jdbcTemplate.queryForObject(MATCH_COUNT_SQL, new Object[] {userName, password}, Integer.class);
	}
	
	public User findUserByUserName(final String userName) {
		final User user = new User();
		String sqlStr = " SELECT user_id, user_name, credits from " + 
		" t_user WHERE usr_name=? ";
		jdbcTemplate.query(sqlStr, new Object[] {userName},
			new RowCallbackHandler() {
				public void processRow(ResultSet rs) throws SQLException{
					user.setUserId(rs.getInt("user_id"));
					user.setUserName(userName);
					user.setCredits(rs.getInt("credits"));
					
				}
		});
		return user;
	}
	public void updateLoginInfo(User user) {
		jdbcTemplate.update(UPDATE_LOGIN_INFO_SQL,new Object[] {user.getLastVisit(), 
				user.getLastIp(), user.getCredits(), user.getUserId()
		});
	}
}

 首先这里出现了几个疑问点:

  1. 之前在pom.xml里没有配置好的dependency,所以我们里需要再到配置文件中添加spring-jdbc, spring-context的依赖。
  2. 这里getMatchCount方法中名为queryForObject的function也要注意,因为这是3.1版本后的function,原来是queryForInt(sql, object[])
  3. 这里@Repository使用注解的方式来定义一个Bean,并使用@Autowired将spring容器中的Bean注解进来。关于具体的spring注解后面会具体介绍,这里可以知道相较于传统的Bean,Spring Bean更关注于功能本身而将链接数据库等重复的过程进行了封装。
  4. 这里jdbcTemplate.query方法签名为query(String sql, Object[] args, RowCallbackHandler),其中RowCallbackHandler这个入参是用来负责查询结果的处理回调接口,负责将查询结构从ResultSet装载到类似领域对象的对象实例中。
  5. 有一个小技巧就是在编写sql语句时,如果要分行写,尽量首位都留有空格一方sql语句出错。

 LoginLogDao的代码相对简单,仅仅是更新loginlog,代码如下:

package com.smart.dao;

import com.smart.domain.LoginLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository

public class LoginLogDao{
	private JdbcTemplate jdbcTemplate;
	@Autowired
	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}
	private final static String INSERT_LOGIN_LOG_SQL = " INSERT INTO t_login_log( " + 
			"user_id, ip, login_datetime) Values(?,?,?) ";
	public void insertLoginLog(LoginLog loginLog) {
		jdbcTemplate.update(INSERT_LOGIN_LOG_SQL, new Object[] 
				{loginLog.getUserId(), loginLog.getIp(),
					loginLog.getLoginDate()});
	}
}

在spring中装配Dao

 从上述代码中我们可以看到我们并没有写关于链接数据库的代码,这是因为这些功能被jdbcTemplate封装起来了,那么jdbcTemplate本身是需要一个Datasource来获取返回连接从而使用注入。
 首先在src/main目录下创建resources目录,而后在此目录下创建smart_context.xml文件,其中代码如下:

<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-4.0.xsd
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context-4.0.xsd
       http://www.springframework.org/schema/tx 
       http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
       <!-- 1 扫描类包,将标注spring注解的类自动转化Bean, 同时完成Bean的注入 -->
       <context:component-scan base-package="com.smart.dao"/>
       
       <!-- 2 配置数据源,即链接数据库 -->
       	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
	       	destroy-method="close" 
	       	p:driverClassName="com.mysql.jdbc.Driver"
	       	p:url="jdbc:mysql://localhost:3306/sampledb"
	       	p:username="root"
	       	p:password="rootroot"
       	/>
       	
       	<!-- 3 配置jdbc模板 -->
       	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
       		p:dataSource-ref="dataSource" />
</beans>
  1. 这里1处使用<context:component-scan>来扫描指定类包下的所有类,这样在类中定义的spring注解(@Repository, @Autowired)才能使用。
  2. 2处就是利用驱动器来链接数据库
  3. 3处是配置了jdbcTemplate Bean,将2处声明的dataSource注入jdbcTemplate,进而注入Dao中。

猜你喜欢

转载自blog.csdn.net/real_Rickys/article/details/82864341