在大一下学期,除了学习课文内容之余,在空暇的时间内进行了简单的JavaWeb服务端学习。以此作为学习的总结为以后进一步学习的做好基础。
我主要学习的是后端设计,而后端设计中分层次的进行开发是很重要的。分层开发有利于提高系统的可拓展性,增加新功能时于已有模块不冲突。方便查错与调试,某一层出问题不会牵一发而动全身。规范化,每一个业务功能实现都按照相同的结构来实现。Bean、Dao、Service、Servlet是服务端开发最基本最必要的层次,它其实是MVC开发模式的体现。在实际项目开发中可以选择从Bean层开始设计根据数据库的数据由下往上至Servlet开发,也可以根据前端需求从Servlet由上至下Service开发。下面以学校课表查询为例对各层进行介绍。
一、Bean
public class TableBean {
private Integer id;
private String classCode;
private String semester;
private String section;
private String one;
private String two;
private String three;
private String four;
private String five;
private String six;
private String seven;
private String ClassName;
public TableBean(){}
public TableBean(Integer id, String classCode, String semester,
String section, String one, String two, String three, String four,
String five, String six, String seven, String className) {
this.id = id;
this.classCode = classCode;
this.semester = semester;
this.section = section;
this.one = one;
this.two = two;
this.three = three;
this.four = four;
this.five = five;
this.six = six;
this.seven = seven;
ClassName = className;
}
public String getClassName() {
return ClassName;
}
public void setClassName(String className) {
ClassName = className;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getClassCode() {
return classCode;
}
public void setClassCode(String classCode) {
this.classCode = classCode;
}
public String getSemester() {
return semester;
}
public void setSemester(String semester) {
this.semester = semester;
}
public String getSection() {
return section;
}
public void setSection(String section) {
this.section = section;
}
public String getOne() {
return one;
}
public void setOne(String one) {
this.one = one;
}
public String getTwo() {
return two;
}
public void setTwo(String two) {
this.two = two;
}
public String getThree() {
return three;
}
public void setThree(String three) {
this.three = three;
}
public String getFour() {
return four;
}
public void setFour(String four) {
this.four = four;
}
public String getFive() {
return five;
}
public void setFive(String five) {
this.five = five;
}
public String getSix() {
return six;
}
public void setSix(String six) {
this.six = six;
}
public String getSeven() {
return seven;
}
public void setSeven(String seven) {
this.seven = seven;
}
@Override
public String toString() {
return "TableBean [id=" + id + ", classCode=" + classCode
+ ", semester=" + semester + ", section=" + section + ", one="
+ one + ", two=" + two + ", three=" + three + ", four=" + four
+ ", five=" + five + ", six=" + six + ", seven=" + seven
+ ", ClassName=" + ClassName + "]";
}
}
Bean层主要进行的是提供对数据的存与取的方法即get和set方法。
二、Dao
public class ImpleDao implements InterDao {
/*
*课表
*/
public List getTimeTable(TableBean timetable) {
SqlSession session=null;
AccessUtil Util=new AccessUtil();
ListTlist=new ArrayList();
try {
session=Util.getSqlSession();
ITimeTable mapper = session.getMapper(ITimeTable.class);
Tlist=mapper.getTimetable(timetable);
} catch (IOException e) {
e.printStackTrace();
}finally{
Util.destorySession(session);
}
return Tlist;
}
/*
* 成绩
*/
public List getGrade(Student student) {
SqlSession session=null;
AccessUtil Util=new AccessUtil();
ListSlist=new ArrayList();
try {
session=Util.getSqlSession();
ITimeTable mapper = session.getMapper(ITimeTable.class);
Slist=mapper.getGrade(student);
} catch (IOException e) {
e.printStackTrace();
}finally{
Util.destorySession(session);
}
return Slist;
}
}
Dao层是数据交换层,它是连接数据库的桥梁,对数据库中的数据进行增删改查的基本操作。
三、Service
public class ImpleService implements InterService {
/*
* 课表
*
*/
public List getTimeTable(String semester, String className) {
TableBean Tbean=new TableBean();
semester=semester.trim();
className=className.trim();
if(semester!=null&&className!=null){
Tbean.setSemester(semester);
Tbean.setClassName(className);
}
InterDao IDao=new ImpleDao();
return IDao.getTimeTable(Tbean);
}
/*
* 成绩
*
*/
public List getGrade(String number, String password) {
Student student=new Student();
ListSl=new ArrayList();
number=number.trim();
password=password.trim();
if(password!=null&&number!=null){
if(password.matches("^[0.0-9.0]+$")&&number.matches("^[0.0-9.0]+$")){
student.setS_number(number);
student.setS_password(password);
InterDao IDao=new ImpleDao();
Sl= IDao.getGrade(student);
}
}
return Sl;
}
}
Service业务层对前端的数据进行业务处理,对服务端而言,各类它分析这个数据,就知道要调用哪个java类的哪个方法,于是去查找或创建这个对象,并调用其方法,再把方法返回的结果包装成soap格式的数据,通过http响应消息回给客户端。使之达到我们要实现的功能,调用Dao层方法向前端返回数据
public class GetTableSerlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String method=request.getParameter("method");
if("getTime".equals(method)){
this.getTime(request, response);
}
else if("getGrade".equals(method)){
this.getGrade(request, response);
}
}
/*
* 课表
*/
public void getTime(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获取页面值
String semester=request.getParameter("SEMESTER");
String className=request.getParameter("CLASSNAME");
//获取结果集
InterService Iservice=new ImpleService();
ListList=Iservice.getTimeTable(semester,className);
if(List!=null&&List.size()>0){
request.setAttribute("TableList",List);
request.getRequestDispatcher("/Timetable.jsp").forward(request, response);
}
else{
request.setAttribute("Error","查无此课表");
request.getRequestDispatcher("/Error.jsp").forward(request, response);
}
}
/*
* 成绩
*/
public void getGrade(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获取页面值
String number=request.getParameter("number");
String password=request.getParameter("password");
//获取结果集
InterService Iservice=new ImpleService();
ListSList=Iservice.getGrade(number, password);
if(SList!=null&&SList.size()>0){
request.setAttribute("StudnetList",SList);
request.getRequestDispatcher("/StudentGrade.jsp").forward(request, response);
}
else{
request.setAttribute("Error","查无此学生");
request.getRequestDispatcher("/Error.jsp").forward(request, response);
}
}
}
Servlet是一个供其他Java程序(Servlet引擎)调用的Java类,它不能独立运行,它的运行完全由Servlet引擎来控制和调度。针对客户端的多次Servlet请求,通常情况下,服务器只会创建一个Servlet实例对象,也就是说Servlet实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至web容器退出,servlet实例对象才会销毁。Servlet控制层,是一个页面拦截器负责拦截来自前端页面的请求,调用Service的方法然后向页面返回数据,实现前端页面的动态显示。
配置tomcat
在这种小项目中我们通常使用的是tomcat服务器,因为它是开源免费的,在我们刚刚接触Javaweb来时使用很容易上手。电脑上安装配置Tomcat的方法和java有些相同,不过首先需要配置好java的环境才行。
下载Tomcat文件,文件是一个exe的安装文件,下载后直接安装即可。
下载地址在百度输入Tomcat进入官网即可找到下载文件。安装文件没有什么技巧,一直点击下一步即可。
同样安装时注意安装目录,因为一会要配置和java一样的环境变量。
同样打开环境变量的配置窗口,在系统环境变量一栏点击新建。
输入内容如下:
变量名:CATALINA_HOME
变量值:刚刚安装的路径
测试安装配置是否成功
找到暗黑族昂路径下的bin 文件夹,找到里面的执行文件,运行,然后执行下面的操作。
打开浏览器,输入http://localhost:8080.如果出现下面的内容说明成功了。****
如何在IDE中配置服务器
我们以myeclipse10作为开发工具为例
[运行Eclipse程序文件,打开Eclipse工作界面。
选择菜单栏中的window——preferences。
选择左侧的 server——runtime environment——在弹出的窗口中选择 add——然后选择你的Tomcat的版本即可。
选择tomcat的路径,和java的版本即可完成配置工作。
数据库的安装
mysql是一个很好用的开源数据库,在项目中我们往往要进行数据的交换,Mysql如何安装呢
MySQL安装文件分为两种,一种是msi格式的,一种是zip格式的。如果是msi格式的可以直接点击安装,按照它给出的安装提示进行安装(相信大家的英文可以看懂英文提示),一般MySQL将会安装在C:\Program Files\MySQL\MySQL Server 5.6 该目录中;zip格式是自己解压,解压缩之后其实MySQL就可以使用了,但是要进行配置。
解压之后可以将该文件夹改名,放到合适的位置,个人建议把文件夹改名为MySQL Server 5.6,放到C:\Program Files\MySQL路径中。当然你也可以放到自己想放的任意位置。
完成上述步骤之后,很多用户开始使用MySQL,但会出现图示的错误。这是因为没有配置环境变量所致。配置环境变量很简单:
我的电脑->属性->高级->环境变量
选择PATH,在其后面添加: 你的mysql bin文件夹的路径 (如:C:\Program Files\MySQL\MySQL Server 5.6\bin )
PATH=.......;C:\Program Files\MySQL\MySQL Server 5.6\bin (注意是追加,不是覆盖)
配置完环境变量之后先别忙着启动mysql,我们还需要修改一下配置文件(如果没有配置,之后启动的时候就会出现图中的错误哦!:错误2 系统找不到文件),mysql-5.6.1X默认的配置文件是在C:\Program Files\MySQL\MySQL Server 5.6\my-default.ini,或者自己建立一个my.ini文件,
在其中修改或添加配置(如图):
[mysqld]
basedir=C:\Program Files\MySQL\MySQL Server 5.6(mysql所在目录)
datadir=C:\Program Files\MySQL\MySQL Server 5.6\data (mysql所在目录\data)
以管理员身份运行cmd(一定要用管理员身份运行,不然权限不够),
输入:cd C:\Program Files\MySQL\MySQL Server 5.6\bin 进入mysql的bin文件夹(不管有没有配置过环境变量,也要进入bin文件夹,否则之后启动服务仍然会报错误2)
输入mysqld -install(如果不用管理员身份运行,将会因为权限不够而出现错误:Install/Remove of the Service Denied!)
安装成功
安装成功后就要启动服务了,继续在cmd中输入:net start mysql(如图),服务启动成功!
此时很多人会出现错误,请看注意:
注意:这个时候经常会出现错误2和错误1067。
如果出现“错误2 系统找不到文件”,检查一下是否修改过配置文件或者是否进入在bin目录下操作,如果配置文件修改正确并且进入了bin文件夹,需要先删除mysql(输入 mysqld -remove)再重新安装(输入 mysqld -install);
如果出现错误1067,那就是配置文件修改错误,确认一下配置文件是否正确。
服务启动成功之后,就可以登录了,如图,输入mysql -u root -p(第一次登录没有密码,直接按回车过),登录成功!
Mysql-join的使用
1.Left Outer Join左外连接
设数据库中有A、B两表,A和B有共同的交集C,当我们想查询出A的所有记录时我们可以使用左外连接:
select
当我们只想查询出只有A表才有的数据而B表没有的数据时,即去掉集合C
select
2.右外连接
右外连接与左连接是类似的,只是我们把哪个表看为基础表的区别而已。左外连接将A作为基础表,右连接我们把B作为基础表。在A、B表中,查询出B表的所有记录
select
只查询出B表存在而A表没有的记录
select
3.全连接
当需要查询出A、B两表的所有数据时可以使用全链接(Full Join)但在Mysql中是不支持Full Join的。但我们可以通过左连接+右连接的联合达到Full Join的效果,即:
select
4.交叉连接
交叉连接(cross join)又称为笛卡儿积连接(cartesian join)或差乘,如果A和B是两个集合,它们的交叉连接记为:A x B。即A表中的一条记录与B表中每一条记录进行匹配,产生一个新的结果集。如果A中有4条记录,B中有5条记录,则会产生20条结果
select
Mybatis的MyBatis一对多和一对一xml文件的配置
在使用mybatis的时候我们经常要用到联合查询,现在就对一表对多表和一对一表的xml文件配置进行说明
Student.xml
StudentBean
public class Student {
private Integer id;
private String name;
private String sex;
private Integer oid;
private Teacher teacher;//一对一
private List courseList;//一对多
public Student() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Integer getOid() {
return oid;
}
public void setOid(Integer oid) {
this.oid = oid;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public Achievement getAchievement() {
return achievement;
}
public void setAchievement(Achievement achievement) {
this.achievement = achievement;
}
public List getCourseList() {
return courseList;
}
public void setCourseList(List courseList) {
this.courseList = courseList;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", sex=" + sex
+ ", oid=" + oid + ", teacher=" + teacher + ", achievement="
+ achievement + ", courseList=" + courseList + "]";
}
}
一对一在Bean中我们可以将其对象作为自身实体类的一个成员变量,一对多返回的结果是一个集合所以将其集合作为成员变量。
CourseBean
public class Course {
private Integer c_id;
private Integer c_sid;
private String biology;
private String physic;
private String chemistry;
public Course(){}
public Integer getC_id() {
return c_id;
}
public void setC_id(Integer c_id) {
this.c_id = c_id;
}
public Integer getC_sid() {
return c_sid;
}
public void setC_sid(Integer c_sid) {
this.c_sid = c_sid;
}
public String getBiology() {
return biology;
}
public void setBiology(String biology) {
this.biology = biology;
}
public String getPhysic() {
return physic;
}
public void setPhysic(String physic) {
this.physic = physic;
}
public String getChemistry() {
return chemistry;
}
public void setChemistry(String chemistry) {
this.chemistry = chemistry;
}
@Override
public String toString() {
return "Course [c_id=" + c_id + ", c_sid=" + c_sid + ", biology="
+ biology + ", physic=" + physic + ", chemistry=" + chemistry
+ "]";
}
}
TeacherBean
public class Teacher {
private Integer t_id;
private String username;
private String password;
public Integer getT_id() {
return t_id;
}
public void setT_id(Integer t_id) {
this.t_id = t_id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "Teacher [t_id=" + t_id + ", username=" + username
+ ", password=" + password + "]";
}
}
Course.xml
teacher.xml
association标签是用来配置一对一表查询的,collection是配置一对多表查询的。
一对一查询中mybatis会将查询结果封装到相应的对象中,如teacher对象,而一对多将返回一个List集合如List
总结
在我三周的暑假夏令营的学习中,第一次感受到身为一个程序员的压力,996的工作模式让我一度喘不过气来同时带来的也有自身的技术的巨大提升。
这次学习我收获最大的就是学会了Mybatis框架的使用和向Android端的数据传值。以前我们的做法使用JDBC来连接数据库,这样的做法是最基本的但是带来的就是代码的重复。如果使用jdbc代码就要穿插在DAO层的代码中,只是一两个dao方法倒无所谓,但是如果上十个甚至更多呢?无疑就会出现一大堆的重复代码,不好编写更不利于以后的代码维护。但使用了Mybatis框架后就可以很好的解决这个问题,实现了连接数据库的代码与DAO层的完全分离,dao层只负责提供方法,这样就很好的利于以后的维护,大大减少了代码量。Mybatis不仅包含了数据库的连接操作更有对数据库增删改查的语法操作,本身提供了大量标签也可以自己提供自定义标签。mybatis的难点之一就是多表的配置,即一对多或多对一的情况,在我学习中我更喜欢的是多对一的配置,因为它比较直观和简单。在思考问题时我们可以换一个角度解决问题一对多从令一个角度去看它也是多对一的体现,所以在项目中我使用的都是多对一的配置。完全掌握一个技术最好的方法就是去看它的源代码,但是我水平有限很多都看不懂包含了动态代理反射等机制,所以对于mybatis我也只是一个会用不理解其根本的水平。向android传值有两种方式即xml和json,刚开始我是想使用xml的方式但是老师说用json容易拓展和更普遍。所以又去学习了json的使用,其实json也没有想象中那么难也是对java基本数据类型进行转换变成一种新的数据模式即json。真正难的是如何从服务端传值到Android,开始我在网上各个论坛寻找方法,看了很多例子还是不理解,后来我发现其实和服务端向网站页面传值的本是一样的。向Android传值只是多了将数据转换成json打包到url路径中即可,response响应后直接返回数据。明白了这一点后就很容易解决问题了,结合书本上和网上的例子,在加上学长的指点很快就解决了问题。
本次夏令营令我感触很深的是老师上课所教的内容是很表面很简单基础的内容,在实际项目中如果只是掌握这些基础实在是寸步难行,况且我们这次所合作的只是一个很小的项目而已,更不用说以后真正出去工作了。所以大学真正培养的是自学能力与拓展能力,当老师刚交给我们任务时我感到即紧张又害怕,因为我觉得当时我根本完成不了。在项目之前通过慕课网、技术论坛快速吸收的提升自己的技术,然而急于求成让我只能学会模仿而不会拓展。但也只能硬着头皮上,遇到问题再说。刚开始做的一两天,技术的缺失让我寸步难行常常十几行代码都要用上一个小时甚至更长的时间,bug更是层出不穷,真的是很窝火感觉自己之前的知识都是白学没用的。幸好我坚持了下来,我知道这只是暂时的学习不可能能一步登天,从最初的按步照搬逐渐可以改编到自己的程序中使用,也明白了每一行代码的意义。在接下来的学习中,我要进一步提升自学能力提升自己。