ssm 프레임워크 기반 도서 추천 시스템 (하)

43782 단어 연습하다
1. 도서 시스템 관리 이 부분은 사용자 이름에 따라 사용자를 조회하고 모든 사용자를 전시하며 사용자를 추가하고 사용자 정보를 업데이트하며 사용자를 삭제하고 도서를 첨삭하고 수정하는 것을 포함한다.dao층 - 서비스층 - controller층에서 한 걸음 한 걸음 실현하고 다음은 모든 사용자를 보여주는 예를 들겠습니다.(일반적으로 하나의 모방으로 여러 가지 기능을 쓸 수 있지만 일부 서비스층의 논리에 주의해야 한다.)먼저 계층 작성
public interface UserDao {
     List listAllUsers();
}

인터페이스 구현 방법: dao층은 @Repository 주석을 사용합니다
@Repository(value = "userDao")
public class UserDaoImpl extends CommonDao implements UserDao {

    private static final Logger LOGGER = LoggerFactory.getLogger(UserDaoImpl.class);
@Override
    public List listAllUsers() {
        LoggerUtil.info(LOGGER,"enter in UserDaoImpl[listAllUsers]");
        return getSqlSession().selectList("hahaha.listAllUsers");
    }
}

서비스 계층 작성
public interface UserService {

    List listAllUsers();
}

인터페이스 구현 방법:
@Service(value = "UserService")
public class UserServiceImpl implements UserService {

   @Resource(name = "userDao")
    private  UserDao userDao;

    private static final Logger LOGGER = LoggerFactory.getLogger(UserService.class);
   @Override
    public List listAllUsers() {
        LoggerUtil.info(LOGGER,"enter in UserServiceImpl[listAllUsers]");
        List userDOList=userDao.listAllUsers();
        return convertDOSToDTOS(userDOList);
    }
    /**
     * UserDO    UserDTO  
     * @param userDO
     * @return
     */
    private UserDTO convertToDTO(UserDO userDO)
    {
        UserDTO userDTO=new UserDTO();
        userDTO.setUserId(userDO.getUserId());
        userDTO.setUsername(userDO.getUsername());
        userDTO.setPassword(userDO.getPassword());
        userDTO.setEmail(userDO.getEmail());
        userDTO.setGmtCreate(DateUtils.format(userDO.getGmtCreate()));
        userDTO.setGmtModified(DateUtils.format(userDO.getGmtModified()));
        userDTO.setModifier(userDO.getModifier());
        userDTO.setPhoneNumber(userDO.getPhoneNumber());
        userDTO.setAge(userDO.getAge());
        userDTO.setSex(userDO.getSex());
        userDTO.setProfession(userDO.getProfession());
        return userDTO;
    }

    /**
     * UserDTO    UserDO  
     * @param userDOList
     * @return
     */
    private List convertDOSToDTOS(List userDOList)
    {
        List userDTOList= Lists.newArrayList();
        if (!CollectionUtils.isEmpty(userDOList)) {
            for (UserDO userDO : userDOList) {
                UserDTO userDTO = convertToDTO(userDO);
                userDTOList.add(userDTO);
            }
        }
        return userDTOList;
    }
}

마지막으로 controller층입니다. urlpattern이/admin/user일 때 이 방법을 실행하고 모델을 전단에 되돌려줍니다.
@Controller
public class AdminController {
    private static final Logger LOGGER = LoggerFactory.getLogger(LoginController.class);
   @Resource(name = "UserService")
    private UserService userService;
    /**
     *       
     * @param httpSession
     * @param model
     * @return
     */
    @RequestMapping(value = "/admin/user")
    public String listAllUsers(HttpSession httpSession,Model model)
    {
        BaseResult result=new BaseResult();
        try {
            LoggerUtil.info(LOGGER, "enter in AdminController[listAllUsers]");
            UserDTO userDTO = (UserDTO) httpSession.getAttribute("isLogin");
            if (userDTO == null) {
                return "redirect:/login";
            }
           List userDTOList= userService.listAllUsers();
            model.addAttribute("userList",userDTOList);
            result.setSuccess(true);
            return "admin_user";
        }catch(BusinessException be){
            ExceptionHandler.handleBusinessException(LOGGER,result,be,"        ");
        }catch(Exception e){
            ExceptionHandler.handleSystemException(LOGGER,result,e,"        ");
        }
        return "error";
    }

2. 사용자의 협동 필터 알고리즘 추천 알고리즘 사고방식을 바탕으로 1. borrow표를 훑어보고 각 책과 그에 대응하는 대출된 횟수를 맵에 저장한다.2. 데이터 세척: 한 사용자가 같은 책을 여러 번 빌릴 수 있고 여러 번 점수를 매길 수 있기 때문에 가장 최근의 점수를 선택하여 사용자가 이 책에 대한 최종 점수로 한다.3. 사용자가 자신이 보지 못한 책에 대한 예측 평점을 계산한다. (1) 먼저 이 책을 본 사용자를 찾아낸다.(2) 그리고 현재 사용자와 이들 사용자 간의 유사도(필슨 상관계수를 채택)를 계산하고 유사도와 대응하는 사용자가 이 책에 대한 평점 가중권을 통해 예측 평점을 얻는다.(3) 예측 평점을 최대 무더기에 저장하고 순서대로 세 권을 선택하여 사용자에게 추천한다.4、추천 목록이 3권이 부족하면 단계 1의 맵에서 순서대로 아래로 가져옵니다.구체적인 코드는 다음과 같습니다.
package book.task;

import book.dao.BookDao;
import book.dao.BorrowDao;
import book.dao.RecommendDao;
import book.dao.UserDao;
import book.domain.dataobject.*;
import book.domain.exception.BusinessException;
import book.util.LoggerUtil;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import net.sf.jsqlparser.statement.select.Join;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author hui zhang
 * @date 2018/3/22
 */
@Component
public class MyRecommendation {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyRecommendation.class);

    @Resource(name = "bookDao")
    private BookDao bookDao;

    @Resource(name = "userDao")
    private UserDao userDao;

    @Resource(name = "borrowDao")
    private BorrowDao borrowDao;

    @Resource(name = "recommendDao")
    private RecommendDao recommendDao;

    @Resource(name = "transactionTemplate")
    private TransactionTemplate transactionTemplate;


    /**
     *     
     * 1,              (        )
     * 2,      
     * 3,      
     * 4,      (         ,             )
     * 5,                    
     * 6,               
     */
    public void recommend() {
        LoggerUtil.info(LOGGER, "enter in MyRecommendation");
        List userDOList = userDao.listAllUsers();
        List bookDOList = bookDao.listAllBooks();
        List borrowDOList = borrowDao.listAllBorrows();
        List recommendDOList = Lists.newArrayList();

        //            
        Map bookCountMap = Maps.newHashMap();

        //              ,              .
        //             
        Map hasSeenTheBook=Maps.newHashMap();

        recommendDao.deleteBefore(0);
        /**
         *       ,          
         */
        for (BorrowDO borrowDO : borrowDOList) {
            BookDO bookDO = bookDao.queryBookByBookId(borrowDO.getBookId());
            UserDO userDO = userDao.queryByUserId(borrowDO.getUserId());
            //     
            if (bookDO == null || userDO == null) {
                continue;
            }
            //TODO          -    bug
            //                 ,   “bookName-author”
            String key = Joiner.on("-").skipNulls().join(bookDO.getBookName(), bookDO.getAuthor());
            if (bookCountMap.get(key) == null) {
                //        
                bookCountMap.put(key, 1);
                //       ,   “userId-bookName-author”,           
                hasSeenTheBook.put(Joiner.on("-").skipNulls().join(userDO.getUserId(),key),recommendDOList.size());
            } else {
                //         
                int count = bookCountMap.get(key);
                bookCountMap.put(key, count + 1);
                //                   
                if (hasSeenTheBook.get(Joiner.on("-").skipNulls().join(userDO.getUserId(),key))!=null) {
                    int index=hasSeenTheBook.get(Joiner.on("-").skipNulls().join(userDO.getUserId(),key));
                    System.out.println("index:"+index);
                    recommendDOList.get(index).setRate(borrowDO.getGoal());
                }
            }
            RecommendDO recommendDO = new RecommendDO();
            recommendDO.setUserId(borrowDO.getUserId());
            recommendDO.setBookId(key);
            recommendDO.setRate(borrowDO.getGoal());
            recommendDOList.add(recommendDO);
        }
        System.out.println("recommendDOList:"+recommendDOList);
        System.out.println("map:" + bookCountMap);
        //         
        Queue> priorityQueue=new PriorityQueue<>((a,b)->(b.getValue().compareTo(a.getValue())));
        priorityQueue.addAll(bookCountMap.entrySet());
        System.out.println("priorityQueue:"+priorityQueue);
        //                
        Queue<Map.Entry<String,Double>>bookDOQueue=new PriorityQueue<>((a,b)->((b.getValue().compareTo(a.getValue()))));
        for (UserDO userDO : userDOList) {
            //      ,           ,                
            priorityQueue.clear();
            //  ,             ,                
            priorityQueue.addAll(bookCountMap.entrySet());
            Map<String, Double> bookCompare = Maps.newHashMap();
            for (BookDO bookDO : bookDOList) {

                //TODO                ,       
                if (neednot(userDO,bookDO,recommendDOList)){
                    continue;
                }
                //           
                List<RecommendDO> SeenTheBook = find(bookDO, recommendDOList);
                System.out.println("SeenTheBook:" + SeenTheBook+"bookName:"+bookDO.getBookName());
                if (CollectionUtils.isEmpty(SeenTheBook)) {
                    continue;
                }

                //recommend        
                double rate = 0;
                double weightSum = 0;
                for (RecommendDO recommendDO : SeenTheBook) {
                    //               
                    double weight = 0;
                    try {
                        weight = calUserSimilarity(userDO, recommendDO, recommendDOList);
                    } catch (BusinessException be) {
                        continue;
                    }
                    System.out.println("weight:" + weight);
                    //     
                    rate = rate + weight * recommendDO.getRate();
                    System.out.println("  "+userDO.getUserId()+"  "+bookDO.getBookName()+"rate:"+rate);
                    weightSum = weightSum + weight;
                }
                if (weightSum!=0) {
                    //                
                    double score = rate / weightSum;
                    System.out.println("  " + userDO.getUserId() + "  " + bookDO.getBookName() + score);
                    //             
                    bookCompare.put(Joiner.on("-").skipNulls().join(bookDO.getBookName(), bookDO.getAuthor()), score);
                }
            }
            bookDOQueue.clear();
            bookDOQueue.addAll(bookCompare.entrySet());
            System.out.println("      :,userId"+userDO.getUserId()+","+"bookDOQueue:" + bookDOQueue);
            //           
            int count = 0;
            //        
            List<String>recommendList=Lists.newArrayList();
            while (!bookDOQueue.isEmpty() && count < 3) {
                //            
                String mix = bookDOQueue.poll().getKey();
                //   bookNameauthor
                Iterator<String> iterator = Splitter.on("-").split(mix).iterator();
                List<String> stringList = Lists.newArrayList();
                while (iterator.hasNext()) {
                    stringList.add(iterator.next());
                }
                //       
                pushToDataBase(stringList.get(0), stringList.get(1), userDO.getUserId());
                recommendList.add(Joiner.on("-").skipNulls().join(stringList.get(0),stringList.get(1)));
                count++;
            }
            System.out.println("the rest:"+count);
            //         
            while (count < 3&&!priorityQueue.isEmpty()) {
                Map.Entry<String, Integer> entry = priorityQueue.poll();
                System.out.println(entry);
                String mix = entry.getKey();
                System.out.println(mix);
                Iterator<String> iterator = Splitter.on("-").split(mix).iterator();
                List<String> stringList = Lists.newArrayList();
                while (iterator.hasNext()) {
                    stringList.add(iterator.next());
                }
                //                  ,   
                if (hotFilter(userDO,stringList.get(0),stringList.get(1),recommendDOList)){
                    continue;
                }
                //             ,   
                if (recommendList.contains(Joiner.on("-").skipNulls().join(stringList.get(0),stringList.get(1)))){
                    continue;
                }
                recommendList.add(Joiner.on("-").skipNulls().join(stringList.get(0),stringList.get(1)));
                pushToDataBase(stringList.get(0), stringList.get(1), userDO.getUserId());
                count++;
            }

        }
    }

    /**
     *      
     * @param userDO
     * @param s
     * @param s1
     * @param recommendDOListBase
     * @return
     */
    private boolean hotFilter(UserDO userDO, String s, String s1, List recommendDOListBase) {
        for (RecommendDO recommendDO : recommendDOListBase) {
            if (recommendDO.getUserId() == userDO.getUserId() && Joiner.on("-").skipNulls().join(s,s1).equals(recommendDO.getBookId())) {
                return true;
            }
        }
        return false;
    }


    /**
     *            
     * @param userDO
     * @param bookDO
     * @param recommendDOListBase
     * @return
     */
    private boolean neednot(UserDO userDO, BookDO bookDO, List recommendDOListBase) {
        for (RecommendDO recommendDO : recommendDOListBase) {
            if (recommendDO.getUserId() == userDO.getUserId() && Joiner.on("-").skipNulls().join(bookDO.getBookName(), bookDO.getAuthor()).equals(recommendDO.getBookId())) {
                return true;
            }
        }
        return false;
    }

    /**
     *                 
     *
     * @param bookName
     * @param author
     * @param userId
     */
    private void pushToDataBase(String bookName, String author, long userId) {
        RecommendationDO recommendationDO = new RecommendationDO();
        recommendationDO.setUserId(userId);
        recommendationDO.setBookName(bookName);
        recommendationDO.setAuthor(author);
        recommendationDO.setRecommendType(0);
        recommendDao.addRecommendation(recommendationDO);
    }


    /**
     *       ,            
     *
     * @param bookDO
     * @param borrowDOList
     * @return
     */
    private List<RecommendDO> find(BookDO bookDO, List borrowDOList){
        List<RecommendDO> recommendDOList = Lists.newArrayList();
        for (RecommendDO recommendDO : borrowDOList) {
            if (recommendDO.getBookId().equals((Joiner.on("-").skipNulls().join(bookDO.getBookName(), bookDO.getAuthor())))) {
                recommendDOList.add(recommendDO);
            }
        }
        return recommendDOList;
    }


    /**
     *             
     *     (a       -a   )*(b       -b   )  /(a       -a    )      (b       -b    )    
     * UserDO    ,recommendDO   
     *
     * @param userA
     * @param userB
     * @return
     */
    private double calUserSimilarity (UserDO userA, RecommendDO userB, List < RecommendDO > recommendDOListBase){
        Map<String, RecommendDO> recommendDORecommendDOMapA = Maps.newHashMap();
        Map<String, RecommendDO> recommendDORecommendDOMapB = Maps.newHashMap();

        //1,    a,b     
        for (RecommendDO recommendDO : recommendDOListBase) {
            if (recommendDO.getUserId() == userA.getUserId()) {
                recommendDORecommendDOMapA.put(recommendDO.getBookId(), recommendDO);
            } else if (recommendDO.getUserId() == userB.getUserId()) {
                recommendDORecommendDOMapB.put(recommendDO.getBookId(), recommendDO);
            }
        }
        System.out.println("recommendA:" + recommendDORecommendDOMapA);
        System.out.println("recommendB:"+recommendDORecommendDOMapB);
        //  a  b     
        if ((recommendDORecommendDOMapA.size() == 0) || (recommendDORecommendDOMapB.size() == 0)) {
            throw new BusinessException("a,b     ");
        }
        //  a,b       
        Set<String> recommendDOSet = Sets.intersection(recommendDORecommendDOMapA.keySet(), recommendDORecommendDOMapB.keySet());
        if (recommendDOSet.size() == 0) {
            throw new BusinessException("a,b         ");
        }
        System.out.println("recommendSet:"+recommendDOSet);
        //  ab    
        Iterator<String> iterator = recommendDOSet.iterator();
        double averageA = 0;
        double averageB = 0;
        while (iterator.hasNext()) {
            String bookId = iterator.next();
            averageA = averageA + recommendDORecommendDOMapA.get(bookId).getRate();
            averageB = averageB + recommendDORecommendDOMapB.get(bookId).getRate();
        }
        averageA = averageA / recommendDOSet.size();
        averageB = averageB /recommendDOSet.size();
        System.out.println("averageA:"+averageA+"averageB:"+averageB);
        iterator = recommendDOSet.iterator();
        double molecule = 0;
        //   
        while (iterator.hasNext()) {
            String bookId = iterator.next();
            molecule = molecule + (recommendDORecommendDOMapA.get(bookId).getRate() - averageA) * (recommendDORecommendDOMapB.get(bookId).getRate() - averageB);
        }
        //   denominator
        double denominatorLeft = 0;
        iterator = recommendDOSet.iterator();
        while (iterator.hasNext()) {
            String bookId = iterator.next();
            denominatorLeft = denominatorLeft + (recommendDORecommendDOMapA.get(bookId).getRate() - averageA) * (recommendDORecommendDOMapA.get(bookId).getRate() - averageA);
        }
        double denominatorRight = 0;
        iterator = recommendDOSet.iterator();
        while (iterator.hasNext()) {
            String bookId= iterator.next();
            denominatorRight = denominatorRight + (recommendDORecommendDOMapB.get(bookId).getRate() - averageB) * (recommendDORecommendDOMapB.get(bookId).getRate() - averageB);
        }
        System.out.println("molecule:"+molecule);
        return molecule /Math.sqrt( denominatorLeft * denominatorRight);
    }

    public static void main(String[] args) {
        new MyRecommendation().recommend();
    }
}

전체 코드는https://github.com/sandman13/book_recommend살펴보다.

좋은 웹페이지 즐겨찾기