培训第2个月的第15天----项目解析(2)

                昨天我学习了一个项目的登陆页面是如何校验的,例如用js或者jq。但是这方面的知识我真的实在是太薄弱了,实在不知道我可以总结出什么,所以昨天就没写博客总结。

               今天老师则是讲了项目的登陆功能(看了项目觉得自己差的太多了,很多类和方法都闻所未闻),项目是挺古老的项目了,用的是struts和 ibatis框架。因为之前学过Mybatis,所以现在看一下Mytatis的前身ibatis还是可以看的懂一些的。由于项目比较大,所以每一个类的方法都比较多,看起来很乱,所以我就从新建了一个项目,只把登陆所需要的东西放到里面,这也是我今天要总结的:用struts和 ibatis框架实现登陆功能。

一.web.xml

                不管你用什么框架,什么技术,每一个项目都会有一个web.xml文件 ,这是毋庸置疑的。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="WebApp_ID" version="2.5">
	<filter>
		<filter-name>struts2</filter-name>
		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<welcome-file-list>
		<welcome-file>login.jsp</welcome-file>
		<welcome-file>index.jsp</welcome-file>
		<welcome-file>index.html</welcome-file>
	</welcome-file-list>
</web-app>

                 在这个文件中,我导入了必要的约束,配置了一个过滤器(struts框架提供给我们的)和其对应的过滤器映射。当我们发送请求时,过滤器会将我们的请求过滤掉(这里会过滤掉所有请求),然后分发给对应的Action来处理请求。这个过滤器还会自动去加载一个在src目录下的struts.xml的文件。

                  我还配置了项目的欢迎页面,用来在访问项目时,自动跳转的页面。

二.struts.xml文件

                  配置完了项目的web.xml,那么接下来就需要配置struts框架的核心配置文件了。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
	<package name="custom-default" extends="struts-default">
		<!-- 默认走的拦截器 -->		
		<action name="loginAction" class="com.java.action.LoginAction">
			<result name="success"></result>
		</action>	
		
		
	</package>
</struts>

                 在这里我也是简单的配置了一下(最简单的那种,只满足登陆功能的需求),我们导入相应的约束,并在struts标签中配置了一个action映射,用来处理用户登陆的请求。在这里我并没有声明执行哪一个拦截器栈,所以它会默认执行 默认的lan'拦截器栈。

三.Sql-Map-Config.xml

                 ibatis框架的核心配置文件的命名与其他框架有所不同,但是它的核心与Mybatis确是差不多的,只不过Mybatis使用sqlSession来操作数据库,而ibatis使用sqlMapClient(类似于Mybatis中的sqlSessionFactory)来操作数据库。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
    "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
 
<!-- 该文件类似于Mybatis的核心配置文件 -->
<sqlMapConfig>
     <!-- 从外部引入文件(去这个文件去寻找资源) -->
     <properties resource="com/java/ibatis/database.properties" />
     
    <!-- 配置事务管理器 -->
    <transactionManager type="JDBC">
          <!-- 配置数据源 -->
          <dataSource type="SIMPLE">
          		<property name="JDBC.Driver" value="${driver}"></property>
          		<property name="JDBC.ConnectionURL" value="${url}" />
          		<property name="JDBC.Username" value="${username}" />
			    <property name="JDBC.Password" value="${password}" />
			    <property name="JDBC.DefaultAutoCommit" value="true" />
          </dataSource>
    </transactionManager>
    
    <!-- 配置所要操作数据的sql语句 -->
    <sqlMap resource="com/java/Mapper/t_limit_emp.xml"></sqlMap>
</sqlMapConfig>

                   这里要注意,Mybatis使用Mapper来“实现”接口,而在ibatis中却不这样做。但是我们依然要在ibatis核心配置文件中pe配置事务管理器,事务管理器(我们)所要操作的数据库(数据源)。这里我们会以引入文件的方式来引入查询所要返回的结果集,而不是定义一个Mapper映射来定义结果集。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap>
	<resultMap class="com.java.bean.T_limit_Emp" id="T_limit_Emp">
		<!-- 管理员表ID管理员表 -->
		<result column="id" property="id" />
		<!-- 帐号帐号 -->
		<result column="userName" property="userName" />
		<!-- 密码密码 -->
		<result column="password" property="password" />
		<!-- 中文姓名 -->
		<result column="trueName" property="trueName" />
		<!-- 操作时间默认getdate -->
		<result column="operateTime" property="operateTime" />
		<!-- 操作人最后操作了该数据的人 -->
		<result column="operator" property="operator" />
		<!-- 有效/无效有效状态-YesNo常用代码 -->
		<result column="valid" property="valid" />
	</resultMap>
	

	
	<!-- 管理员登录 -->
	<select id="adminLogin" parameterClass="com.java.bean.T_limit_Emp" resultMap="T_limit_Emp">
		select * from t_limit_Emp where userName=#userName# and password=#password# and valid=1
	</select>
	
	<select id="selectAdressbyName" parameterClass="java.lang.String" resultClass="java.lang.String">
		select d.url from T_limit_Emp
		a,T_limit_EmpRole b ,T_limit_Right c ,T_limit_RightPage d ,T_limit_RoleRight e,T_limit_Role f
		where a.id=b.empId and f.id=b.roleId and e.rightId=c.id and e.roleId=f.id and d.rightId=c.id and userName=#userName#
	</select>

</sqlMap>

                 我们在sqlMap标签中,定义了resultMap结果集,给这个结果集声明了一个ID标识,用于在其他地方引用这个结果集。并且也想Mybatis一样,声明了映射类(用来指定返回的结果集是什么类型的),这一点好像和Hibernate有点相似。在声明完结果集,我们还要在当前文件中定义所要查询的sql语句,在标签中定义传入参数的类型和返回的结果集ID标识,这里还需要定义一个属于sql语句的ID标识,用来在需要的时候通过id来引用这个sql语句。

                  不仅如此,我们还在ibatis核心配置文件以<properties>标签引入了一个properties类型的文件,并在配置数据源的时候以${ key }的形势来获取文件中的value值。


driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/officesystem?useUnicode=true&characterEncoding=UTF-8
username=root
password=root

四.Controller层

             配置完我们登陆功能所需要的配置文件后,我们就可以开始着手写我们的controller了。在项目中,为了代码规范,现定义了一个baseAction ,在我们写action时候,只需要继承这个baseAction就可以了。

package com.java.action;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

//基本的action抽象类
//抽象类实现接口?为甚什么用泛型
public abstract class BaseAction<T> extends ActionSupport implements ModelDriven<T>{
	
    //最基本的action抽象方法
	public abstract String execute();
	
	//模型驱动所需方法
	
}

               这里有一个疑问,为什么在实现了ModelDriven<T>接口后,BaseAction也要定义泛型了呢?

              下面我们来看一下LoginAction的代码:

package com.java.action;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.java.bean.T_limit_Emp;
import com.java.service.EmpInterface;

public class LoginAction extends BaseAction<T_limit_Emp> {
	//创建一个对象,用于模型驱动
	private T_limit_Emp t_limit_Emp=new T_limit_Emp();
	@Override
	public T_limit_Emp getModel() {
		// TODO Auto-generated method stub
		return t_limit_Emp;
	}
	
	

	@Override
	public String execute() {
		//创建一个service层对象
		EmpInterface empInterface = new EmpInterface();
		//得到查询的结果
		T_limit_Emp emp = empInterface.adminLogin(t_limit_Emp);
		System.out.println(emp);
		//当用户存在时
		if(empInterface!=null) {
			List<String> list = empInterface.selectAdressbyName(emp.getUserName());
			//将list集合放入set集合
			Set<String> set=new HashSet<String>(list);
			set.add("frame/main.jsp");
			set.add("frame/top.jsp");
			set.add("frame/menu.jsp");
			//将set集合封装到实体类的属性
			emp.setPageSet(set); 
		}
		
		
		return null;
	}

}

                  在这个类中,我们首先创建了一个对象,这个对象就是我们模型驱动所要使用的对象。然后我们在execute()方法里些一些业务。如果   模型驱动中的模型中,没有前台页面传递过来的name属性值的属性,那么这个name属性值所对应的value在后台就会接收不到,但是并不会报出异常。

                   比如,我们new了一个service层的对象,并用这个对象调用了adminLogin()方法,方法所需要的参数的就是模型所封装的对象。用这个对象来进行查询,返回一个emp对象。

                    接下来就是根据这个emp进行一些其他的操作了,这里我就不在多说。

五.service层

                

package com.java.service;

import java.util.List;

import com.java.bean.T_limit_Emp;
import com.java.dao.T_limit_EmpDao;
import com.java.dao.T_limit_EmpRoleDao;

public class EmpInterface {
    //封装两个dao层的对象
	private T_limit_EmpDao t_limit_EmpDao = new T_limit_EmpDao();
	private T_limit_EmpRoleDao t_limit_EmpRoleDao = new T_limit_EmpRoleDao();
	
	//用dao层对象来调用方法
	public T_limit_Emp adminLogin(T_limit_Emp emp){
		T_limit_Emp t_limit_Emp_return=t_limit_EmpDao.adminLogin(emp);
		return t_limit_Emp_return;
	}

	public List<String> selectAdressbyName(String userName) {
		List<String> list =t_limit_EmpDao.selectAdressbyName(userName);
		return list;
	}
}

                  在service层中,自然而然的肯定会封装dao层的对象,这里我们封装了两个dao层的对象。然后通过dao层的对象继续调用方法,返回值仍然是一个emp对象。

   六.dao层

                  在我的印象中,dao层就是用来写查询数据库的sql语句的。这里也不例外,但是这里 “写” 的方式确实有点与众不同。

package com.java.dao;

import java.util.List;

import com.java.bean.T_limit_Emp;
import com.java.ibatis.SqlMapConn;

public class T_limit_EmpDao {
    //封装一个用于操作数据库的对象
	private SqlMapConn sqlMapConn=new SqlMapConn();

	public T_limit_Emp adminLogin(T_limit_Emp emp) {
		
		return (T_limit_Emp)sqlMapConn.getObject("adminLogin", emp);
	}

	public List selectAdressbyName(String username) {
		List<String> list=sqlMapConn.select("selectAdressbyName", username);
		return list;
	}
	
}

                  这里首先创建了一个操作数据库的类qlMapConn,然后通过这个类的对象方法来操作数据库。sqlMapConn对象调用的方法和之前的有所不同,这里的方法不仅要传递查询时所需要的参数,还需要添加一个 “引用” ,这个引用用来指用查询数据库的sql语句。

                  查询数据库的sql语句定义在了SqlMapConn对象当中,我们来看一下SqlMapConn类:

package com.java.ibatis;

import java.io.IOException;
import java.io.Reader;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
import com.java.bean.T_limit_Emp;

//该类中封装了用于操作数据库的对象,和操作数据库的方法
public class SqlMapConn {
    //声明一个操作数据库的对象,为什么人家可以变为finall类型?
	private static SqlMapClient sqlMapClient;
	//用静态代码块给属性赋值,静态代码块中属性只能是静态的。
	static {
		//声明ibatis的核心配置文件所在路径
		String url="com/java/ibatis/Sql-Map-Config.xml";
		try {
			//将资源变成输入流
			Reader reader=Resources.getResourceAsReader(url);
			//用流创建一个操作数据库的对象
			sqlMapClient=SqlMapClientBuilder.buildSqlMapClient(reader);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	//定义一个通用的查询数据的方法
	public List select(String reflexion,Object obj) {
		List<String> list=null;
		  try {
			 list=sqlMapClient.queryForList(reflexion, obj);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return list;
		
	}
	
    //查询一个数据的方法
	public Object getObject(String reflexion,Object obj) {
		Object obj_return=null;
		try {
			obj_return=(T_limit_Emp)sqlMapClient.queryForObject(reflexion, obj);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return obj_return;
	}
}

                 在这个类中,定义了操作数据库的方法和操作数据库的sql语句,可以说,这个类就是操作数据库的最 “底层” 的类,而sqlMapClient则是操作数据库的对象。

                  这里的sql语句存放在ibatis的核心配置文件中。

七.总结

                  总的来说,其实并不需要惧怕登陆的代码,只不过是controller层接收参数,通过service层业务处理,在通过dao层来查询数据库,将查询到的结果返回controller层处理。就是MVC模式的3层逐层调用,只不过不同框架的语法不同,例如Mybatis和ibatis的语法结构就不太一样。

猜你喜欢

转载自blog.csdn.net/qq_41160264/article/details/82466795
今日推荐