通过前几章的学习,我们已经搭建好了博客网站的基本框架。本章我们将正式开始网站的功能开发。
开发前的准备在正式实现业务逻辑之前,我们先来分析一下完成本应用所需的一些基本框架并将它们集成到工程中。
我们将在开发前做以下准备。
本系统需要用到MySQL,持久层框架采用MyBatis。在缓存方面将用到Redis,主要用于用户登录信息、验证码等的存储。Redis在第5章中已经封装,本章将不再赘述。搜索方面,我们采用比较成熟的Elasticsearch开发系统的搜索引擎。
下面我们就来分别集成并封装MyBatis和 Elasticsearch框架。
MyBatis的集成
MyBatis的集成比较简单,按照以下步骤操作即可。
(1)在public工程中添加 MySQL、MyBatis和 Druid的依赖:
org.mybatis.spring.boot mybatis-spring-boot-starter1.3.2 dependency>mysql mysql-connector-java5.1.46 com.alibaba druid-spring-boot-starter1.1.1e
其中 Druid是阿里巴巴开发的一个数据库连接池框架,本系统的数据库连接池框架采用Druid。
(2)在配置中心的远程Git仓库中新增配置文件datasource.yml并配置数据源:
spring: datasource: druid: url: jdbc:mysql://localhost:3306/blog_db?useUnicode=true&characterEncoding= UTF-8&useSSL=false username: root password:******stat-view- servlet: login-username: adminlogin-password: admin mybatis: #配置mapper.xml的classpath路径 mapper- locations: classpath: /mapper*.xml resource>src/main/resources cincludes>***.xml true < /build> org.mybatis.generator mybatis-generator-maven-plugin${mybatis.generator.version} com. lynn.blog mybatis-generator artifactId>1.0-SNAPSHOT < / dependency>true true < / configuration>
mybatis-generator-core为上述插件所需的依赖包,只需要添加该依赖就能让我们通过编码实现代码生成器规则,但是要执行代码生成器规则还需要指定generator的 Maven插件。在
mybatis-generator-maven-plugin并指定用于mybatis-generator 工程,我门就可以执行插件了。
(2)新建配置文件 generator.properties:
generator .jdbc.driver=com.mysql.jdbc.Driver generator.jdbc.url=jdbc:mysql://localhost:3306/blog_db?useUnicode=true& characterEncoding=utf-8& autoReconnect=true& useSSL=false generator.jdbc.username=root generator.jdbc.password=**丰率**#MySQL 驱动所在全路径 classPathEntry=/Users/lynn/Downloads/mysql-connector-java-5.1.47.jar
上述配置较为简单,只需要指定数据库连接信息和MySQL驱动所在的全路径即可。
(3) mybatis-generator提供了一些默认生成,比如 tinyintW默认生成BIT类型、没有分页等,它提供了插件接口,我们可以自定义插件,扩展代码生成器的规则。下面以分页插件为例讲解自定义插件的生成,读者可以参照本书的配套源码了解其余实现,请看代码:
public class PaginationPlugin extends PluginAdapter {
@Override
public boolean validate(List list) {
return true;
}
@override
public boolean modelExampleClassGenerated(TopLevelclass topLevelClass,
IntrospectedTable introspectedTable) {
PrimitiveTypewrapper integerwrapper = FullyQualifiedavaType.getIntInstance().
getPrimitiveTypewrapper();
Field limit = new Field();limit.setName("limit");
limit.setvisibility( Javavisibility. PRIVATE);limit.setType(integerwrapper);
topLevelclass.addField(limit);Method setLimit = new Method();
setLimit.setVisibility ( avavisibility.PUBLIC);setLimit.setName( "setLimit");
setLimit.addParameter(new Parameter(integerwrapper,"limit"));setLimit.addBodyLine( "this.limit = limit; ");
topLeve1class.addMethod(setLimit);
Method getLimit = new Method();
getLimit.setvisibility ( Javavisibility.PUBLIC);
getLimit.setReturnType(integerwrapper);getLimit.setName( "getLimit" );
getLimit.addBodyLine( "return limit; ");topLevelclass .addMethod(getLimit);Field offset = new Field();
offset.setName( "offset");
offset.setvisibility ( Javavisibility. PRIVATE);offset.setType(integerwrapper);
topLevelclass.addField(offset);Method setoffset = new Method();
setOffset.setVisibility (avavisibility. PUBLIC);setOffset.setName( "setOffset");
setOffset. addParameter(new Parameter(integerwrapper,"offset"));setOffset.addBodyLine("this.offset = offset; ");
topLevelclass.addMethod(setOffset);
Method getoffset = new Method();
getOffset.setvisibility( Javavisibility . PUBLIC);getOffset.setReturnType(integerwrapper);
getOffset.setName( "getOffset" );
getOffset.addBodyLine( "return offset; ");topLevelclass.addMethod(getoffset);
return true;
}
@override
public boolean sqlMapSelectByExamplewithoutBLOBsElementGenerated(XmlElement element,
IntrospectedTable introspectedTable){
XmlElement ifLimitNotNullElement = new XmlElement("if");
ifLimitNotNullElement.addAttribute(new Attribute("test", "limit != null"));Xm1Element ifOffsetNotNullElement = new XmlElement("if");
ifOffsetNotNullElement.addAttribute(new Attribute( "test","offset != null"));ifOffsetNotNullElement.addElement(new TextElement("limit ${offset},${limit}"));ifLimitNotNullElement.addElement(ifOffsetNotNul1Element);
Xm1Element ifOffsetNullElement = new Xm1Element("if");
ifOffsetNullElement.addAttribute(new Attribute("test","offset == null"));ifOffsetNullElement.addElement(new TextElement("limit ${limit}"));
ifLimitNotNullElement.addElement(iFOffsetNullElement);
element.addElement(ifLimitNotNullElement);
return true;
}
}
generator提供了一个PluginAdapter类,方便我们实现自定义的代码生成插件,因此想要实现自定义插件,首先应继承PluginAdapter类并重写validate、
modelExampleclassGenerated 和sqlMapSelectByExamplewithoutBLOBsElementGenerated方法。其中, validate用于设置插件是否有效,上述代码返回true,表示始终有效;modelExampleClassGenerated 的作用是生成Example代码,我们生成了分页必须的 offset 和 limit方法,通过设置offset和 limit即可完成分页;sqlMapSelectByExamplewithoutBLOBSElementGenerated的作用是生成Mapper.xml代码,我们知道MySQL是通过limit关键词来分页的,因此上述代码也相应的生成limit语句来完成分页查询语句的创建。
(4)新建generatorConfig.xml:
commentGenerator>
context>
我们要自动生成相应的数据库CRUDR代码,还需要创建配置文件说明生成原则。在上述配置中,



