注意:本项目为博主初学Web开发时所写,所使用的方法都比较笨,不符合主流开发方法。例如,包管理应该使用Maven进行管理而不是手动导入,对前端后端代码的架构也并不是很清晰。大家学习思想即可,可以不用浪费时间在将这个项目跑起来。目前主流的技术应当是Spring+SpringMVC+Mybatis的SSM框架,配合Shiro做权限控制,Redis做缓存,也可以学习SpringBoot开发微服务。由于本博主已经保研,较少接触开发,故此项目也不再进行维护。
DAO层-数据的增删改查
J2EE开发人员使用数据访问对象(DAO)设计模式把底层的数据访问逻辑和高层的商务逻辑分开.实现DAO模式能够更加专注于编写数据访问代码。DAO层的每个类都依赖于SessionFactory,SessionFactory接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。这里用到了工厂模式。同理我们需要在applicationContext.xml中注入sessionFactory
我们来看一下UserDao.java
public class UserDao {
privateSessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
protected Session getSession() {
returnsessionFactory.getCurrentSession();
}
publicvoid saveUser(User user) {
getSession().save(user);
}
publicUser loadUser(Integer id) {
return(User)getSession().get(User.class, id);
}
publicvoid updateUser(User user) {
getSession().update(user);
}
publicList allUser() {
Stringhql="from User";
returngetSession().createQuery(hql).list();
}
PublicUser loadByAccount(String account){
Stringhql="from User u where u.account=:account";
Queryquery=getSession().createQuery(hql);
query.setParameter("account",account);
ListuserList=query.list();
if(userList.size()<1){
returnnull;
}
Useruser=(User)userList.get(0);
returnuser;
}
}
HQL语句
这里我们简单学习一下HQL语句,详细的可以去百度搜一下“hql语法与详细解释”
HQL语句是Hibernate专用的语句,在上面UserDao中,我们可以看到几条HQL语句,比如String hql="from User";会读取所有的user,那我们想加上一些条件的话,可以是”from User u whereu.userId=5”,这样会读取到userid为5的User。那如果我们想通过传入参数来得到对应的user的信息的话,可以这样子:
String hql="from User u whereu.account=:account";
Query query=getSession().createQuery(hql);
query.setParameter("account",account);
有点类似JDBC的PreparedStatement,先搭好语句的框架,再将具体的值set进去。那如果要排序呢?很简单,只要在最后面加上order by XXX(asc/desc 升序/降序)即可。
from Comment comment wherecomment.blogId=:blogId order by comment.date asc
知道这些,我们就可以写出很多的功能了,其他的要用到的时候再了解即可。
这里我采用的是对每一个JavaBean都有一个对应的DAO,也可以弄个BaseDAO, 其他DAO继承这个BaseDAO,根据主键来进行添删改查 ,适用于通用的操作。至于具体业务操作的,就写在特定的DAO里面。
编写完Dao,我们的业务逻辑就可以开始使用这个Dao类来操作数据库了。
Service层-处理业务逻辑
Service层,也就是业务逻辑层,主要是对一些业务逻辑进行处理后返回结果给控制器。
一个Service层一般可以依赖1到n个Dao层的类,用以形成它自身的业务逻辑。
以用户信息的业务逻辑为例
public class UserInfoServiceImpl extendsBaseServiceImpl implements UserInfoService{
privateUserInfoDao userInfoDao;
publicvoid setUserInfoDao(UserInfoDao userInfoDao) {
this.userInfoDao= userInfoDao;
}
publicUserInfoDao getUserInfoDao() {
returnuserInfoDao;
}
@Override
publicvoid saveUserInfo(Integer userId,String userName, Boolean sex, DateuserBirthday, String userJob, String post,String userIntroduction, Integer userPlace,String userImage) {
UserInfouserInfo=new UserInfo();
userInfo.setUserId(userId);
userInfo.setSex(sex);
userInfo.setUserBirthday(userBirthday);
if(userImage==null)userImage=Constant.DEFAULT_IMAGE_URL;//默认头像
userInfo.setUserImage(userImage);
userInfo.setUserIntroduction(userIntroduction);
userInfo.setUserJob(userJob);
userInfo.setUserName(userName);
userInfo.setPost(post);
userInfo.setUserPlace(userPlace);
userInfoDao.saveUserInfo(userInfo);
}
publicvoid updateDetail(Integer userId,String userName,Boolean sex,DateuserBirthday,String userJob, String post,String userIntroduction,IntegeruserPlace){
UserInfouserInfo=userInfoDao.loadUserInfoByUserId(userId);
if(userName!=null&&userName!="")userInfo.setUserName(userName);
if(sex!=null)userInfo.setSex(sex);
if(userBirthday!=null)userInfo.setUserBirthday(userBirthday);
if(userJob!=null&&userJob!="")userInfo.setUserJob(userJob);
if(userIntroduction!=null&&userIntroduction!="")userInfo.setUserIntroduction(userIntroduction);
userInfo.setUserPlace(userPlace);
if(post!=null&post!="")userInfo.setPost(post);
if(userInfo.getUserImage()==null)userInfo.setUserImage(Constant.DEFAULT_IMAGE_URL);
userInfoDao.updateUserInto(userInfo);
}
@Override
publicvoid updateUserImage(Integer userId, String userImageURL) {
userInfoDao.updateImageURL(userId,userImageURL);
}
@Override
publicString loadUserNameById(Integer userId) {
UserInfouserInfo=userInfoDao.loadUserInfoByUserId(userId);
returnuserInfo.getUserName();
}
publicUserInfo getUserInfoByUserId(Integer userId){
returnuserInfoDao.loadUserInfoByUserId(userId);
}
publicInteger getUserIdRandomly(Integer userId){
ListuserInfoList=userInfoDao.allOtherUserInfo(userId);
intsize=userInfoList.size();
if(size!=0){
intx=(int)(Math.random()*size);
intid=userInfoList.get(x).getUserId();
returnid;
}
return0;
}
}
在通过userInfoDao获取数据库中的数据后,可以对数据进行处理,写回到数据库中,或者是返回相应的结果。这个没什么好讲的。
Action控制层
连接前后端的一层。前端所发送的请求,都会被Struts框架拦截,根据它自身的struts配置文件,转发到对应的action类中。
Action的处理流程可以分为以下步骤:
① 获取参数
② 调用相对应的业务逻辑层的方法进行处理,得到结果
③ 根据结果返回不同的页面,或者返回相对应的json数据。
Action类的写法如下:
public class UserAction extendsActionSupport{
privateUserService userService;
privateUserInfoService userInfoService;
privateMap jsonMap=null;
publicvoid setJsonMap(Map jsonMap) {
this.jsonMap= jsonMap;
}
publicMap getJsonMap() {
returnjsonMap;
}
publicvoid setUserService(UserService userService){
this.userService=userService;
}
publicUserService getUserService(){
returnuserService;
}
publicvoid setUserInfoService(UserInfoService userInfoService) {
this.userInfoService= userInfoService;
}
publicUserInfoService getUserInfoService() {
returnuserInfoService;
}
publicString login() throws Exception{
HttpServletRequestrequest = ServletActionContext.getRequest();
HttpSessionsession = request.getSession();
Stringaccount = request.getParameter("account");
String password = request.getParameter("password");
System.out.println("login"+account+" "+password);
if(userService.loginCheck(account,password)==true){
IntegeruserId=userService.loadUserId(account);
session.setAttribute("userId",userId);
UserInfouserInfo=userInfoService.getUserInfoByUserId(userId);
userInfo.setUserRecentLoginTime(newDate());
userInfoService.update(userInfo);
returnConstant.SUCCESS;
}else{
returnConstant.FAIL;
}
}
publicString passwordCheck(){
HttpServletRequestrequest = ServletActionContext.getRequest();
jsonMap=newHashMap();
Stringpassword=request.getParameter("password");
Stringaccount=request.getParameter("account");
System.out.println(account+""+password);
Booleanmatch=userService.loginCheck(account,password);
jsonMap.put("valid",match);
return"jsonMap";
}
}
获取参数:
通过HttpServletRequest request =ServletActionContext.getRequest();以及 HttpSessionsession = request.getSession();
我们可以得到serlvet中学习过的request,session等对象,通过这几个对象,我们可以获取请求传过来的值,或者是设置相应作用域的值。例如
Stringpassword=request.getParameter("password");
Stringaccount=request.getParameter("account");
session.setAttribute("userId",userId);//在整个会话期间的userId,表明登录者为该用户
配置返回页面:
在struts.xml中,可以在
当我们对应的action返回“success”时,则会跳转到main.jsp中。
当我们对应的action返回”fail”时,则会跳转到fail.jsp中。
当然,前后端的交互远不止这样,除此之外,前后端的数据交互可以利用json来进行交互。JSON(JavaScript Object Notation, JS对象标记)是一种轻量级的数据交换格式。它有以下特征
· 对象表示为键值对
· 数据由逗号分隔
· 花括号保存对象
· 方括号保存数组
一个简单的json如下var json = '{"a": "Hello", "b": "World"}'; //这是一个 JSON 字符串,本质是一个字符串。关于JSON数据的交互我们之后会进行讲解。
----------------------------------------------------------------------------
本项目下载地址:
github:https://github.com/SCAUMankind/SSHBlogSystem