发表于: 2017-10-15 21:51:54

2 654


今天完成的事情:


通过demo(图书管理系统)学习SSM框架(大部分)


通过idea新建mavenwebapp工程:bookmanager 图书预约系统

包含两个表:

book

appointment


工程结构:

配置文件:

①web.xml:

一个seckill-dispatcher的DiepatcherServlet和他的Mapping

用init-param标签初始化:

<init-param>

 <param-name>contextConfigLocation</param-name>

 <param-value>classpath:spring/spring-*.xml</param-value>

</init-param>

mapping中

<url-pattern>/</url-pattern>设置匹配到任意/xx路径型


②spring-web.xml

自动注册DefaultAnnotationHandlerMapping,AnnotationMethodHandlerAdapter

<mvc:annotation-driven />


老样子,对静态资源的处理

<mvc:default-servlet-handler />


老样子的配置JstlView

添加前后缀。


最后,开启指定包上的注解

<context:component-scan base-package="org.shunly.bookmanager.web"/>


③spring-servlet.xml

<context:component-scan base-package="org.shunly.bookmanager"/>

配置一个事务管理器:

<bean id="transactionManager"      class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

  <property name="dataSource" ref="dataSource"/>

</bean>

这个是注解式事务管理:

<tx:annotation-driven transaction-manager="transactionManager"/>


④spring-dao.xml

dataSource、sqlSessionFactory、以及Dao的注入。

使用了c3p0的连接池

部分私有属性:

<property name="maxPoolSize" value="30"/>

<property name="minPoolSize" value="10"/>

<!--关闭后不自动commit-->

<property name="autoCommitOnClose" value="false"/>

<!--连接失败后重试次数-->

<property name="acquireRetryAttempts" value="2"/>

<!--超时时间-->

<property name="checkoutTimeout" value="10000"/>


⑤mybatis-config.xml

学习了新的私有属性:

<settings>

<!--开启 jdbc的getGeneratedKeys方法获取数据库自增主键值-->

<setting name="useGeneratedKeys" value="true"/>

<!--开启 列别名替换列名-->

<setting name="useColumnLabel" value="true"/>

<!--开启驼峰命名转换-->

<setting name="mapUnderscoreToCamelCase" value="true"/>

</settings>




entity实体:与数据库的表相对应的类(pojo)

Book和Appointment


dao数据访问层:数据库操作有关的接口

BookDao包含  

①id查询图书 Book selectById(long id)

②查询所有图书  List<Book> selectAll(@Param("offset")int offset, @Param("limit") int limit);

③更新(减少)馆藏数量  int reduceNumber( long bookId);


AppointmentDao包含

①预约记录插入 

int insertAppointment(@Param("bookId") long bookId, @Param("studentId") long studentId);

②通过主键查询预约记录

Appointment selectByKeyFromBook(@Param("bookId") long bookId, @Param("studentId") long studentId);


enums枚举:存放和异常有关的状态

AppointStateEnum:

两个属性:state,stateInfo

一个包含这两个属性的构造器

SUCCESS(1"预约成功")NO_NUMBER(0"库存不足")REPEAT_APPOINT(-1"重复预约")INNER_ERROR(-2"系统异常");

该方法遍历整个枚举的值,如果状态码匹配,则返回这个枚举类,否则返回null;

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



dto数据传输层:传输返回数据给service

AppointExecution 封装预约结果信息

四个属性:bookId, state(状态码), stateInfo(状态信息), Appointment(预约信息类)

两个构造器:成功的则给Appointment赋值,失败的则没有。



exception异常:处理异常的。。(这样定义异常和处理是比较正确的么)

分别处理库存不足异常、预约重复异常、预约异常。

继承RuntimeException


service业务接口:

根据使用者角度有三个方法:

①Book getById(long bookId);

② List<Book> getList();

③AppointExecution appoint(long bookId, long studentId);


ServiceImp业务实现:

两个Dao接口属性BookDao、AppointmentDao

使用BookDao的selectById和selectAll方法实现①和②。

方法③:利用update的返回值判断是否库存足够,再通过insert返回值判断是否重复,最后得到预约成功的信息。

@Transactional
public AppointExecution appoint(long bookId, long studentId) {
try {
int update = bookDao.reduceNumber(bookId);
      if (update <= 0) {
throw new NoNumberException("no number");
      } else {
int insert = appointmentDao.insertAppointment(bookId, studentId);
          if (insert <= 0) {
throw new RepeatAppointException("repeat appoint");
          } else {
Appointment appointment = appointmentDao.selectByKeyFromBook(bookId, studentId);
              return new AppointExecution(bookId, AppointStateEnum.SUCCESS, appointment);
          }
}
}catch (NoNumberException e1){
throw e1;
  }catch (RepeatAppointException e2){
throw e2;
  }catch (Exception e){
logger.error(e.getMessage(),e);
       throw new AppointException(("appoint inner error:" + e.getMessage()));
  }
}



缺省BookController和Result(封装json返回结果)

涉及到了Json,暂不表。


测试结果:

①BookDaoTest


②AppointmentDaoTest


③BookServiceImpTest


明天计划的事情:

着手完成任务2,json和JsonTagLib

 
遇到的问题:

Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.


新版本的jdbc驱动。。。class变更为com.mysql.cj.jdbc.Driver 注意修改。


收获:

小知识:

①使用mybatis时,Dao接口中的方法如果参数两个及以上,使用@Param("xxx")来注解参数xxx。

②ORDER BY xx是排序语句

③mysql忽略主键冲突,避免重复插入的方法: 

INSERT IGNORE INTO `table_name` (`column1`...) VALUES(`value1`...);

REPLACE INTO `table_name`(`colomn1`, ...) VALUES (...);

当遇到重复时

IGNORE 忽略该句,返回0。

REPLACE 从表中删除受影响的行,并重新插入。返回一个数,来指示受影响的行的数目。该数是被删除和被插入的行数的和。

④联合查询 INNER JOIN

用法示例:

SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a INNER JOIN tcount_tbl b ON a.runoob_author = b.runoob_author;


返回列表 返回列表
评论

    分享到