国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

SSM框架整合

lanffy / 1641人閱讀

摘要:環境工具數據庫連接工具準備工作步驟新建項目建好基本目錄,按住配置目錄,如下圖新建幾個包,如下圖包名名稱作用數據訪問層接口與數據操作有關的都放在這里實體類一般與數據庫的表相對應,封裝層取出來的數據為一個對象,也就是我們常說的,一般只在層與層之

環境

Windows10

JDK1.8

MySql5.5

工具

Maven3.5

IDEA2017

Navicat(數據庫連接工具)

準備工作 步驟 1、新建Maven webapp項目



建好基本目錄,按住 Ctrl+Alt+Shift+s配置目錄,如下圖

新建幾個包,如下圖:

包名 名稱 作用
dao 數據訪問層(接口 與數據操作有關的都放在這里
entity 實體類 一般與數據庫的表相對應,封裝dao層取出來的數據為一個對象,也就是我們常說的pojo,一般只在dao層與service層之間傳輸
dto 數據傳輸層 用于service層與web層之間傳輸,相當于vo
service 業務邏輯(接口) 寫我們的業務邏輯,在設計業務接口時候應該站在“使用者”的角度。
serviceImpl 業務邏輯(實現) 實現我們業務接口,一般事務控制是寫在這里,沒什么好說的。
controller 控制器 springmvc就是在這里發揮作用的
2、配置文件

配置完成的目錄如下:

pom.xml


  4.0.0
  com.messchx
  ssmdemo
  war
  1.0-SNAPSHOT
  ssmdemo Maven Webapp
  http://maven.apache.org

  
    ssmdemo

    
      
        org.mortbay.jetty
        maven-jetty-plugin
        6.1.7
        
          
            
              8888
              30000
            
          
          ${project.build.directory}/${pom.artifactId}-${pom.version}
          
          /
        
      

      
      
        org.mybatis.generator
        mybatis-generator-maven-plugin
        1.3.2
      

      
        org.apache.maven.plugins
        maven-compiler-plugin
        
          
          1.8
          1.8
        
      
    
    
    
      
        
        src/main/java
        
        
          **/*.xml
          **/*.properties
        
      
      
        
        src/main/resources
        
        
          **/*.xml
          **/*.properties
        
      

    
  

  
    
    UTF-8
    UTF-8
    
    4.3.5.RELEASE
    
    3.4.1
  
  
    
    
      javax
      javaee-api
      7.0
    

    
    
      junit
      junit
      4.12
    

    
    
      ch.qos.logback
      logback-classic
      1.2.2
    

    
    
      com.fasterxml.jackson.core
      jackson-databind
      2.8.7
    


    
    
      mysql
      mysql-connector-java
      5.1.41
      runtime
    

    
    
      com.mchange
      c3p0
      0.9.5.2
    

    
    
      org.mybatis
      mybatis
      ${mybatis.version}
    

    
    
      org.mybatis
      mybatis-spring
      1.3.1
    

    
    
      org.springframework
      spring-core
      ${spring.version}
    
    
      org.springframework
      spring-beans
      ${spring.version}
    
    
      org.springframework
      spring-context
      ${spring.version}
    
    
      org.springframework
      spring-jdbc
      ${spring.version}
    
    
      org.springframework
      spring-tx
      ${spring.version}
    
    
      org.springframework
      spring-web
      ${spring.version}
    
    
      org.springframework
      spring-webmvc
      ${spring.version}
    
    
      org.springframework
      spring-test
      ${spring.version}
    
  

spring配置文件,主要是dao、service、controller

spring-dao.xml



    
    
    

    
    
        
        
        
        
        

        
        
        
        
        
        
        
        
        
    

    
    
        
        
        
        
        
        
        
        
    

    
    
        
        
        
        
    
    

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=root    

提示:配置文件中的jdbc.username,如果寫成username,可能會與系統環境中的username變量沖突,所以到時候真正連接數據庫的時候,用戶名就被替換成系統中的用戶名(有得可能是administrator),那肯定是連接不成功的

mybatis-config.xml




    
    
        
        

        
        

        
        
    

spring-service.xml



    
    

    
    
        
        
    

    
    

spring-controller.xml



    
    
    
    

    
    

    
    
        
        
        
    

    
    

web.xml


  
  
  
    dispatcherServlet
    org.springframework.web.servlet.DispatcherServlet
    
    
      contextConfigLocation
      classpath:spring/spring-*.xml
    
    1
  
  
    dispatcherServlet
    
    /
    

logback.xml(日志)



    
        
        
            %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
        
    

    
        
    

generatorConfig.xml,mybatis逆向工程,生成dao(即mapper)和model(即po),這里先不用





    
    

    
    

    

        
        
            
            
        

        
        
        


        
        
            
        


        
        

            
            
            
            
            
            
            
            
        

        
        
            
        

        
        
            
        

        
        

到這里基本的配置都完了,剩下的就是寫代碼。

3、代碼,應用實例(圖書管理系統)

mysql數據文件:

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for appointment
-- ----------------------------
DROP TABLE IF EXISTS `appointment`;
CREATE TABLE `appointment` (
  `book_id` bigint(20) NOT NULL COMMENT "圖書ID",
  `student_id` bigint(20) NOT NULL COMMENT "學號",
  `appoint_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT "預約時間",
  PRIMARY KEY (`book_id`,`student_id`),
  KEY `idx_appoint_time` (`appoint_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT="預約圖書表";

-- ----------------------------
-- Records of appointment
-- ----------------------------
INSERT INTO `appointment` VALUES ("1000", "12345678910", "2018-01-16 15:44:36");
INSERT INTO `appointment` VALUES ("1001", "12345678910", "2018-01-16 15:58:02");

-- ----------------------------
-- Table structure for book
-- ----------------------------
DROP TABLE IF EXISTS `book`;
CREATE TABLE `book` (
  `book_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT "圖書ID",
  `name` varchar(100) NOT NULL COMMENT "圖書名稱",
  `number` int(11) NOT NULL COMMENT "館藏數量",
  PRIMARY KEY (`book_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1004 DEFAULT CHARSET=utf8 COMMENT="圖書表";

-- ----------------------------
-- Records of book
-- ----------------------------
INSERT INTO `book` VALUES ("1000", "Java程序設計", "9");
INSERT INTO `book` VALUES ("1001", "數據結構", "9");
INSERT INTO `book` VALUES ("1002", "設計模式", "10");
INSERT INTO `book` VALUES ("1003", "編譯原理", "10");
3.1 dao層

在entity包中添加圖書實體Book.java和預約圖書實體Appointment.java
Book.java

public class Book {

    private long bookId;// 圖書ID

    private String name;// 圖書名稱

    private int number;// 館藏數量

    // 省略構造方法,getter和setter方法,toString方法

}

Appointment.java

   /**預約圖書實體*/
public class Appointment {

    private long bookId;// 圖書ID

    private long studentId;// 學號

    private Date appointTime;// 預約時間

    // 多對一的復合屬性
    private Book book;// 圖書實體
    
    // 省略構造方法,getter和setter方法,toString方法

}

在dao包新建接口BookDao.java和Appointment.java
BookDao.java

public interface BookDao {

    /**
     * 通過ID查詢單本圖書
     *
     * @param id
     * @return
     */
    Book queryById(long id);

    /**
     * 查詢所有圖書
     *
     * @param offset 查詢起始位置
     * @param limit 查詢條數
     * @return
     */
    List queryAll(@Param("offset") int offset, @Param("limit") int limit);

    /**
     * 減少館藏數量
     *
     * @param bookId
     * @return 如果影響行數等于>1,表示更新的記錄行數
     */
    int reduceNumber(long bookId);
}

AppointmentDao.java

public interface AppointmentDao {

    /**
     * 插入預約圖書記錄
     *
     * @param bookId
     * @param studentId
     * @return 插入的行數
     */
    int insertAppointment(@Param("bookId") long bookId, @Param("studentId") long studentId);

    /**
     * 通過主鍵查詢預約圖書記錄,并且攜帶圖書實體
     *
     * @param bookId
     * @param studentId
     * @return
     */
    Appointment queryByKeyWithBook(@Param("bookId") long bookId, @Param("studentId") long studentId);

}

提示:這里為什么要給方法的參數添加@Param注解呢?是因為該方法有兩個或以上的參數,一定要加,不然mybatis識別不了。上面的BookDao接口的queryById方法和reduceNumber方法只有一個參數book_id,所以可以不用加 @Param注解,當然加了也無所謂~
我們不需要實現dao接口, mybatis會動態實現,但是我們需要編寫相應的mapper。在mapper目錄里新建兩個文件BookDao.xml和ppointmentDao.xml,分別對應上面兩個dao接口。

BookDao.xml




    
    

    

    
        UPDATE book
        SET number = number - 1
        WHERE
        book_id = #{bookId}
        AND number > 0
    

AppointmentDao.xml




    
        
        INSERT ignore INTO appointment (book_id, student_id)
        VALUES (#{bookId}, #{studentId})
    

    

mapper總結:namespace是該xml對應的接口全名,select和update中的id對應方法名,resultType是返回值類型,parameterType是參數類型(這個其實可選),最后#{...}中填寫的是方法的參數,還有一個小技巧要交給大家,就是在返回Appointment對象包含了一個屬性名為book的Book對象,那么可以使用"book.屬性名"的方式來取值,看上面queryByKeyWithBook方法的sql。

測試:在測試分支建立相應的包,測試前需要讓程序讀入spring-dao和mybatis等配置文件,所以我這里就抽離出來一個BaseTest類,只要是測試方法就繼承它即可。
BaseTest.java

/**
* 配置spring和junit整合,junit啟動時加載springIOC容器 spring-test,junit
*/
@RunWith(SpringJUnit4ClassRunner.class)
// 告訴junit spring配置文件
@ContextConfiguration({ "classpath:spring/spring-dao.xml", "classpath:spring/spring-service.xml" })
public class BaseTest {

}

新建BookDaoTest.java和AppointmentDaoTest.java兩個dao測試文件
BookDaoTest.java

public class BookDaoTest extends BaseTest {
    @Autowired
    private BookDao bookDao;

    @Test
    public void testQueryById() throws Exception {
        long bookId = 1000;
        Book book = bookDao.queryById(bookId);
        System.out.println(book);
    }

    @Test
    public void testQueryAll() throws Exception {
        List books = bookDao.queryAll(0, 4);
        for (Book book : books) {
            System.out.println(book);
        }
    }

    @Test
    public void testReduceNumber() throws Exception {
        long bookId = 1000;
        int update = bookDao.reduceNumber(bookId);
        System.out.println("update=" + update);
    }

}

BookDaoTest測試結果,testQueryById

testQueryAll

testReduceNumber

AppointmentDaoTest.java

public class AppointmentDaoTest extends BaseTest{
    @Autowired
    private AppointmentDao appointmentDao;

    @Test
    public void testInsertAppointment() throws Exception {
        long bookId = 1000;
        long studentId = 12345678910L;
        int insert = appointmentDao.insertAppointment(bookId, studentId);
        System.out.println("insert=" + insert);
    }

    @Test
    public void testQueryByKeyWithBook() throws Exception {
        long bookId = 1000;
        long studentId = 12345678910L;
        Appointment appointment = appointmentDao.queryByKeyWithBook(bookId, studentId);
        System.out.println(appointment);
        System.out.println(appointment.getBook());
    }

}

AppointmentDaoTest測試結果,testInsertAppointment

testQueryByKeyWithBook

3.2 servic層

我們先定義幾個預約圖書操作返回碼的數據字典,也就是我們要返回給客戶端的信息。我們這類使用枚舉類

返回碼 說明
1 預約成功
0 庫存不足
-1 重復預約
-2 系統異常

AppointStateEnum.java

package com.messchx.ssm.enums;

/**
 * 使用枚舉表述常量數據字典
 */
public enum AppointStateEnum {
    SUCCESS(1, "預約成功"), NO_NUMBER(0, "庫存不足"), REPEAT_APPOINT(-1, "重復預約"), INNER_ERROR(-2, "系統異常");

    private int state;

    private String stateInfo;

    private AppointStateEnum(int state, String stateInfo) {
        this.state = state;
        this.stateInfo = stateInfo;
    }

    public int getState() {
        return state;
    }

    public String getStateInfo() {
        return stateInfo;
    }

    public static AppointStateEnum stateOf(int index) {
        for (AppointStateEnum state : values()) {
            if (state.getState() == index) {
                return state;
            }
        }
        return null;
    }

}

在dto包下新建AppointExecution.java用來存儲我們執行預約操作的返回結果。
AppointExecution.java

/**
* 封裝預約執行后結果
*/
public class AppointExecution {

    // 圖書ID
    private long bookId;

    // 秒殺預約結果狀態
    private int state;

    // 狀態標識
    private String stateInfo;

    // 預約成功對象
    private Appointment appointment;

    public AppointExecution() {
    }

    // 預約失敗的構造器
    public AppointExecution(long bookId, AppointStateEnum stateEnum) {
        this.bookId = bookId;
        this.state = stateEnum.getState();
        this.stateInfo = stateEnum.getStateInfo();
    }

    // 預約成功的構造器
    public AppointExecution(long bookId, AppointStateEnum stateEnum, Appointment appointment) {
        this.bookId = bookId;
        this.state = stateEnum.getState();
        this.stateInfo = stateEnum.getStateInfo();
        this.appointment = appointment;
    }
    
    // 省略getter和setter方法,toString方法

}

在exception包下新建三個文件NoNumberException.java RepeatAppointException.java AppointException.java預約業務異常類(都需要繼承RuntimeException),分別是無庫存異常、重復預約異常、預約未知錯誤異常,用于業務層非成功情況下的返回(即成功返回結果,失敗拋出異常)。
NoNumberException.java

/**
* 庫存不足異常
*/
public class NoNumberException extends RuntimeException {

    public NoNumberException(String message) {
        super(message);
    }

    public NoNumberException(String message, Throwable cause) {
        super(message, cause);
    }

}

RepeatAppointException.java

/**
* 重復預約異常
*/
public class RepeatAppointException extends RuntimeException {

    public RepeatAppointException(String message) {
        super(message);
    }

    public RepeatAppointException(String message, Throwable cause) {
        super(message, cause);
    }

}

AppointException.java

/**
* 預約業務異常
*/
public class AppointException extends RuntimeException {

    public AppointException(String message) {
        super(message);
    }

    public AppointException(String message, Throwable cause) {
        super(message, cause);
    }

}

在service包下新建BookService.java圖書業務接口
BookService.java

/**
* 業務接口:站在"使用者"角度設計接口 三個方面:方法定義粒度,參數,返回類型(return 類型/異常)
*/
public interface BookService {

    /**
     * 查詢一本圖書
     *
     * @param bookId
     * @return
     */
    Book getById(long bookId);

    /**
     * 查詢所有圖書
     *
     * @return
     */
    List getList();

    /**
     * 預約圖書
     *
     * @param bookId
     * @param studentId
     * @return
     */
    AppointExecution appoint(long bookId, long studentId);

}

在service.impl包下新建BookServiceImpl.java使用BookService接口,并實現里面的方法。
BookServiceImpl

@Service
public class BookServiceImpl implements BookService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    // 注入Service依賴
    @Autowired
    private BookDao bookDao;

    @Autowired
    private AppointmentDao appointmentDao;


    @Override
    public Book getById(long bookId) {
        return bookDao.queryById(bookId);
    }

    @Override
    public List getList() {
        return bookDao.queryAll(0, 1000);
    }

    @Override
    @Transactional
    /**
     * 使用注解控制事務方法的優點: 1.開發團隊達成一致約定,明確標注事務方法的編程風格
     * 2.保證事務方法的執行時間盡可能短,不要穿插其他網絡操作,RPC/HTTP請求或者剝離到事務方法外部
     * 3.不是所有的方法都需要事務,如只有一條修改操作,只讀操作不需要事務控制
     */
    public AppointExecution appoint(long bookId, long studentId) {
        try {
            // 減庫存
            int update = bookDao.reduceNumber(bookId);
            if (update <= 0) {// 庫存不足
                //return new AppointExecution(bookId, AppointStateEnum.NO_NUMBER);//錯誤寫法                
                throw new NoNumberException("no number");
            } else {
                // 執行預約操作
                int insert = appointmentDao.insertAppointment(bookId, studentId);
                if (insert <= 0) {// 重復預約
                    //return new AppointExecution(bookId, AppointStateEnum.REPEAT_APPOINT);//錯誤寫法
                    throw new RepeatAppointException("repeat appoint");
                } else {// 預約成功
                    Appointment appointment = appointmentDao.queryByKeyWithBook(bookId, studentId);
                    return new AppointExecution(bookId, AppointStateEnum.SUCCESS, appointment);
                }
            }
        // 要先于catch Exception異常前先catch住再拋出,不然自定義的異常也會被轉換為AppointException,導致控制層無法具體識別是哪個異常
        } catch (NoNumberException e1) {
            throw e1;
        } catch (RepeatAppointException e2) {
            throw e2;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            // 所有編譯期異常轉換為運行期異常
            //return new AppointExecution(bookId, AppointStateEnum.INNER_ERROR);//錯誤寫法
            throw new AppointException("appoint inner error:" + e.getMessage());
        }
    }

}

測試一下業務代碼
BookServiceImplTest.java

public class BookServiceImplTest extends BaseTest {

    @Autowired
    private BookService bookService;

    @Test
    public void testAppoint() throws Exception {
        long bookId = 1001;
        long studentId = 12345678910L;
        AppointExecution execution = bookService.appoint(bookId, studentId);
        System.out.println(execution);
    }

}

BookServiceImplTest測試結果

首次執行是“預約成功”,如果再次執行的話,應該會出現“重復預約”

在dto包里新建一個封裝json返回結果的類Result.java,設計成泛型
Result.java

/**
* 封裝json對象,所有返回結果都使用它
*/
public class Result {

    private boolean success;// 是否成功標志

    private T data;// 成功時返回的數據

    private String error;// 錯誤信息

    public Result() {
    }

    // 成功時的構造器
    public Result(boolean success, T data) {
        this.success = success;
        this.data = data;
    }

    // 錯誤時的構造器
    public Result(boolean success, String error) {
        this.success = success;
        this.error = error;
    }

    // 省略getter和setter方法
}
3.3 controller層

BookController.java

@Controller
@RequestMapping("/book") // url:/模塊/資源/{id}/細分 /seckill/list
public class BookController {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private BookService bookService;

    @RequestMapping(value = "/list", method = RequestMethod.GET)
    private String list(Model model) {
        List list = bookService.getList();
        model.addAttribute("list", list);
        // list.jsp + model = ModelAndView
        return "list";// WEB-INF/jsp/"list".jsp
    }

    @RequestMapping(value = "/{bookId}/detail", method = RequestMethod.GET)
    private String detail(@PathVariable("bookId") Long bookId, Model model) {
        if (bookId == null) {
            return "redirect:/book/list";
        }
        Book book = bookService.getById(bookId);
        if (book == null) {
            return "forward:/book/list";
        }
        model.addAttribute("book", book);
        return "detail";
    }

    //ajax json
    @RequestMapping(value = "/{bookId}/appoint", method = RequestMethod.POST, produces = {
            "application/json; charset=utf-8" })
    @ResponseBody
    private Result appoint(@PathVariable("bookId") Long bookId, @RequestParam("studentId") Long studentId) {
        if (studentId == null || studentId.equals("")) {
            return new Result<>(false, "學號不能為空");
        }
        //AppointExecution execution = bookService.appoint(bookId, studentId);//錯誤寫法,不能統一返回,要處理異常(失敗)情況
        AppointExecution execution = null;
        try {
            execution = bookService.appoint(bookId, studentId);
        } catch (NoNumberException e1) {
            execution = new AppointExecution(bookId, AppointStateEnum.NO_NUMBER);
        } catch (RepeatAppointException e2) {
            execution = new AppointExecution(bookId, AppointStateEnum.REPEAT_APPOINT);
        } catch (Exception e) {
            execution = new AppointExecution(bookId, AppointStateEnum.INNER_ERROR);
        }
        return new Result(true, execution);
    }

}

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/68261.html

相關文章

  • 從零開始搭建SSM框架(Spring + Spring MVC + Mybatis)

    摘要:打開,,選中,然后再選中,輸入項目的和,指定等配置,修改,打開項目,添加一些必要的目錄,最終項目框架目錄圖如下修改文件,指定各依賴和插件的版本等信息在標簽里面管理各依賴的版本號添加項目依賴管理依賴配置好之后,開始整合。 最近在回顧和總結一些技術,想到了把之前比較火的 SSM 框架重新搭建出來,作為一個小結,同時也希望本文章寫出來能對大家有一些幫助和啟發,因本人水平有限,難免可能會有一些...

    MiracleWong 評論0 收藏0
  • Maven多模塊項目搭建+整合SSM框架

    摘要:繼承作用就是避免配置重復,對于子項目來說應該關心父項目是怎么樣配置的。聚合字面理解就是聚在一起合作完成工作,就是將子模塊聚集起來完成相應的項目需求父工程的搭建項目結構在父工程中,主要負責完成依賴的版本管理,并不是實際的依賴。 從大二開始就一直關注segmentFault,在問題專區幫忙回答一些自己知曉的問題;在寫這篇文章之前我一直會在朋友圈發一些自己遇到的問題以及解決辦法,這是第一次寫...

    liaosilzu2007 評論0 收藏0
  • SSM框架整合

    摘要:整合項目結構導入版本號相關包相關包相關包相關包數據庫連接池集成標準標簽庫日志相關包單元測試相關包里面為空開發環境下,日志級別設置 ssm整合項目結構 showImg(https://segmentfault.com/img/bVbsw8O?w=533&h=815); Maven導入jar pom.xml 4.0.0 cn.scitc Test 1...

    twohappy 評論0 收藏0
  • ssm框架整合

    ssm整合 開發環境ide,mysql數據庫,Spring+SpringMVC+Mybatis,tomcat8.5,jdk使用的是1.7版本。 第一步:導入jar包 Spring+ SpringMVC + MyBatis + Mybatis-spring整合包 AOP聯盟+織入 + c3p0 數據庫連接池 + MySQL連接驅動 + jstl 鏈接:https://pan.baidu.com/...

    Simon_Zhou 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<