整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

基于Java Web的陕西旅游网站的设计与实现-计算机毕业设计源码

、研究的背景和意义

研究背景:本文主要是基于旅游业是我国现阶段发展的重要产业,旅游可以推动经济上的发展,通过深入的对当前旅游行业的研究,也随着网络技术的发展,传统的旅游方式游客已经无法满足,游客不再满足于单一路线的线路,无法进行更多的选择,每天日常的行程安排丧失了一定的自由选择,这就导致降低了游客的期望,也减少了消费的欲望。所以旅游网站的建设就显得尤为重要,游客可以通过网站来提前感受到各地的景色,为自己制定出一个贴合自己的路线,多元化的去选择。带给游客一种全新的体验。

研究意义:旅游业是现代服务业的重要组成部分,国家为了促进旅游业的改革发展,也相继出台了相关政策。促进旅游业的发展,对于扩就业、增收入,推动一些中西部的贫困地区的发展有着重要的作用,也可以促进国家经济的平稳增加。旅游业的发展也是为了能够满足人们日益增长的物质和文化上的需要,在如今这个互联网发展飞速的时代,现阶段越来越多的人想要走出家门去欣赏外面的风景,通过旅游让自己精神和身体上的放松。人们可以通过上网来了解更多特色的地方,人们也对于旅游文化的要求越来越高,因此很多具有特色的和历史悠久的地方成为了人们的选择对象。而且随着网络的发展,更多的偏远地区也有了一定的发展机会,一些不为人知的地方反而会成为热门,每个地方凭借着自己的特色来引起人们的关注,所以人们需要一个专业的平台去了解自己喜欢的文化。云旅游是可以扩大景区的知名度,增进当地民俗文化的发展,实现文化的对外输出,另外云旅游这也是突破了时间与空间的限制,人们坐在家中就可以通过网络来了解到其他地方的景色。走信息化的道路来推动旅游业的发展是一个很明智的选择。相信随着旅游网站系统功能的越来越成熟,结合着大数据技术的发展前景,为游客制定出更为舒适,更合理的旅游路线,让游客更享受这段旅程。同时也随着大众们的旅游需求越来越高,我们的旅游网上市场也会发展的越来越快,旅游网站的建设也成为了一个重要的问题。

二、研究的目的和内容

研究目的:基于Java Web开发的旅游网站,开发该系统的主要目的,为游客的出行旅游提供便利,吸引游客为游客制定一系列服务功能,包括路线的选择,景点的信息,酒店预订信息,论坛交互等。

研究内容:本文主要基于陕西旅游的网站一体化服务,所开发的面向于游客的旅游管理系统。描述了该旅游系统的开发背景,首先从旅游需求分析开始,之后进行系统的总体架构设计,详细设计与所能实现的功能和测试环节。

三、研究的方法和步骤

研究方法:

1. 数量研究法:通过网络在线旅游时游客数量比较出主要线路趋势,更全面的体现出游客对于旅游线路选择的方向;

2.个案研究法:研究省内或省外游客,加以专门调查分析,全面了解省内游客及省外游客对于出省旅游的心思,再加以总结,会更透彻认识到其中的关系;

3.数据分析法:收集旅游游客对于旅游网站相关看法,进行数据分析,准确分析旅游网站发展前景。

4.文献研究法:研究目的或课题,调查旅游网站相关文献来获得资料,从而多方面面地、正确地了解所要掌握的信息。

研究步骤:

1.准备建设网站相关技术,例:spring MVC、Mybatis框架、html、css、jQuery、Ajax和BootStrap等前端技术;

2.准备工作:收集相关旅游网站的资料,了解该模式运营的利害关系,明白旅游网站的发展趋势;

3.首页页面设计,然后根据需求分析现有系统所需功能,对功能板块划分;

4.实现现有板块前后台功能;

5.进行归纳测试总结:系统功能实现以后,再次对功能板块进行测试,最后再对测试结果进行总结得出结论。

四、拟解决的关键问题

1.了解旅游系统游客的需求,按照需求制定相关的功能;

2.对前后台功能进行细致区分,让管理员和游客分别管理或使用相应功能;

3.根据数据分析游客更偏向的旅游景点,为游客制定出更加贴合个人的出行方案;

4.对之前的板块功能进行测试,之后对测试的结果进行总结之后得出结论。

本系统在长时间服务于用户的环境下会有大量的数据生成,至此怎样管理这些数据也是一个不容小觑的问题,对数据信息管理得当会提升客户的满意度。在系统开始时,进行需求分析,根据需求分析和实际开发相结合,分析出相应所需数据,接着设计出数据库表,这些数据库表要能体现出彼此之间的关系。在对本网站各个功能进行合理分析后,设计出合格的数据库。

景点表存储陕西旅游网站的景点信息,包括主键编号,基本信息等字段,在数据库系统中,景点表是自动创建和维护的,通过查询景点信息表了解数据库内部的结构、统计信息、性能瓶颈等相关信息,景点信息表中的数据可以通过SQL语句进行查询和修改,通过系统界面修或者删除数据。

用Springboot和Mybatis完成了一个列表页面的制作。主要代码如下:

1、MyBatis映射文件

<select id="findAll" resultType="com.gl.entity.User">
SELECT * FROM user
</select>


2、接口

@Repository
//必须是接口
public interface UserMapper {
User Sel(int id);

List<User> findAll();
}


3、Service

@Service
public class UserService {
@Autowired
UserMapper userMapper;

public User Sel(int id) {
return userMapper.Sel(id);
}

public List<User> findAll() {
return userMapper.findAll();
}
}


4、Controller

@GetMapping("/users")
public String list(Model model) {
List<User> users = userService.findAll();
model.addAttribute("users", users);
return "userlist";
}


5、Html使用thymeleaf模板引擎

合Mybatis是本项目中的一个难点。

实现功能:

1 动态绑定用户输入参数

2 Mybatis的resultType动态绑定返回实体类。

3 在spring中的接口注入

4 xml版本的mapper注入。

关于Mybatis的优秀文章给大家推荐两个:

1、手写简化版mybatis

https://my.oschina.net/liughDevelop/blog/1631006

2、Mybatis源码解读-设计模式总结

http://www.crazyant.net/2022.html

手写板大致思路如下:

https://my.oschina.net/liughDevelop/blog/1631006

这里的Myconfiguration和我的JDBCUtils类似。

实现思路:

首先用XmlBuilderMapper类读取mapper.xml(我是在initBean中指定要读取的配置文件,并没有写成在xml中配置动态的读取xml。)文件,获取MapperInfo对象保存信息。

用户用MysqlSession的getMapper方法,返回一个代理对象,用这个代理对象来执行MySqlSession定义的selectOne方法来查询,Mybaits中的SqlSession中定义了大量的方法,我这里简化只有一个selectOne方法。

然后这个方法调用executor执行器来解析sql,传入参数,执行数据库操作。最后返回结果。将返回结果封装成对象。

动态代理一般有两种,一种是jdk一种是cglib动态代理,本项目采用是jdk动态代理实现。

XmlBuilderMapper.class

package spring.mybatis;

import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import spring.constants.Constants;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName XmlBuilder
* @Description
* @Data 2018/7/8
* @Author xiao liang
*/
@Slf4j
public class XmlBuilderMapper {
 public List<MapperInfo> buildMapper(String xmlMapperPath){
 //实例化mapperInfo的链表,每一条sql对应一个MapperInfo对象
 List<MapperInfo> mapperInfoList = new ArrayList<>();
 MapperInfo mapperInfo = new MapperInfo();
 // 创建saxReader对象
 SAXReader reader = new SAXReader();
 // 通过read方法读取一个文件 转换成Document对象
 Document document = null;

 String pathName = Constants.PATH + xmlMapperPath;
 try {
 document = reader.read(new File(pathName));
 } catch (DocumentException e) {
 log.error("文件没有找到,{}", pathName);
 }
 //获取根节点元素
 Element node = document.getRootElement();
 mapperInfo.setInterfaceName(node.attributeValue("namespace"));
 //获取所有的bean
 List<Element> elementsList = node.elements();
 for (Element element :
 elementsList) {
 if ("select".equals(element.getName())){
 mapperInfo.setMethodName(element.attributeValue("id"));
 mapperInfo.setResultClassName(element.attributeValue("resultType"));
 mapperInfo.setSqlContent(element.getText());
 }
 mapperInfoList.add(mapperInfo);
 }
 return mapperInfoList;
 }
}

然后介绍一下MapperInfo对象

package spring.mybatis;

import lombok.Data;
/**
* @ClassName MapperInfo
* @Description 用来封装读取mapper.xml文件后的信息
* @Data 2018/7/8
* @Author xiao liang
*/
@Data
public class MapperInfo {
 //namespace命名空间
 private String interfaceName;
 //sql内容
 private String sqlContent;
 //对应的方法名
 private String methodName;
 //返回值的class名
 private String resultClassName;
}

JDBCUtils工具类我在开篇就介绍了,也没什么新内容,不贴在这里了

其实关键点就是动态代理和执行器

MySqlSession(动态代理部分)

package spring.mybatis;

import java.lang.reflect.Proxy;
/**
* @ClassName MySqlSession
* @Description
* @Data 2018/7/8
* @Author xiao liang
*/
public class MySqlSession {
 public <T> T selectOne(MapperInfo mapperInfo ,Object[] paremeters){
 MyExecutor myexecutor = new MyExecutor();
 return myexecutor.query(mapperInfo,paremeters);
 }
 
 public <T> T getMapper(Class<?> aClass,String mybatisXmlName){
 return (T) Proxy.newProxyInstance(aClass.getClassLoader(),new Class[]{aClass},new MyMapperProxy(this,mybatisXmlName));
 }
}

MyMapperProxy(jdk动态代理的实现) 代理之后执行的还是sqlSession中的方法

package spring.mybatis;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.List;
/**
* @ClassName MyMapperProxy
* @Description
* @Data 2018/7/8
* @Author xiao liang
*/
public class MyMapperProxy implements InvocationHandler {
 private MySqlSession mySqlSession;
 private String mybatisXmlName;
 //mybatisXmlName传入的要读取的xml文件名
 public MyMapperProxy(MySqlSession mySqlSession , String mybatisXmlName){
 this.mySqlSession = mySqlSession;
 this.mybatisXmlName = mybatisXmlName;
 }
 @Override
 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
 XmlBuilderMapper xmlBuilderMapper = new XmlBuilderMapper();
 List<MapperInfo> mapperInfoList = xmlBuilderMapper.buildMapper(mybatisXmlName);
 //如果存在sql,开始执行方法
 if (mapperInfoList != null && mapperInfoList.size() != 0){
 for (MapperInfo mapperInfo :
 mapperInfoList) {
 if (!method.getDeclaringClass().getName().equals(mapperInfo.getInterfaceName())){
 return null;
 }
 if (method.getName().equals(mapperInfo.getMethodName())){
 //其实最后执行的mySqlSession中的方法,args是用户传递的参数数组
 return mySqlSession.selectOne(mapperInfo,args);
 }
 }
 }
 return null;
 }
}

返回到MySqlSession后,就轮到执行器MyExcutor出场了。

MyExcutor:也是一个难点,先说一下程序的逻辑。读取到mapperinfo对象,获得定义的sql,返回类的名称等信息。

用正则解析sql,根据#{},判断sql中有几处?,然后将用户传递的参数按照顺序依次写入到sql的?中。

最后读取结果集,用set方法注入到返回的对象中,这样就实现了返回时候的实体类绑定了。