Spring Boot學習筆記(七)通用mapper,代碼生成,分頁組件接入

代碼自動生成

底層服務有很多通用的CRUD,利用代碼生成最好不過了,這裡作者將代碼生成放在<code>test/<code>中的 <code>CodeGenerator/<code>,避免與正式代碼衝突。

生成的代碼不細說了,大家可以慢慢理解,覺得有困難的可以直接拿過來用。

主要通過<code>org.mybatis.generator/<code>來實現,項目中的<code>generator.template/<code>模板文件可以自行定義。

Mybatis及分頁插件配置

首先引用分頁插件包:

<dependency>
<groupid>com.github.pagehelper/<groupid>
<artifactid>pagehelper/<artifactid>
<version>4.2.1/<version>/<dependency>

然後進行相應的配置:

@Beanpublic SqlSessionFactory sqlSessionFactoryBean(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean(); factory.setDataSource(dataSource); factory.setTypeAliasesPackage(MODEL_PACKAGE); //配置分頁插件,詳情請查閱官方文檔
PageHelper pageHelper = new PageHelper();
Properties properties = new Properties();
properties.setProperty("pageSizeZero", "true");//分頁尺寸為0時查詢所有紀錄不再執行分頁
properties.setProperty("reasonable", "true");//頁碼<=0 查詢第一頁,頁碼>=總頁數查詢最後一頁
properties.setProperty("supportMethodsArguments", "true");//支持通過 Mapper 接口參數來傳遞分頁參數
pageHelper.setProperties(properties); //添加插件
factory.setPlugins(new Interceptor[]{pageHelper}); //添加XML目錄
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); factory.setMapperLocations(resolver.getResources("classpath:mapper/*.xml")); return factory.getObject();
}

通用Mapper配置

引用通用mapper,簡單的增刪改查就不用再寫對應的xml了,之後有新增字段只要修改對應的model就可以了,還是非常方便的。

引用對應的包:

<dependency>
<groupid>tk.mybatis/<groupid>
<artifactid>mapper/<artifactid>
<version>3.4.2/<version>/<dependency>

然後進行相應的配置:

@Beanpublic MapperScannerConfigurer mapperScannerConfigurer() {
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean");
mapperScannerConfigurer.setBasePackage(MAPPER_PACKAGE); //配置通用Mapper,詳情請查閱官方文檔
Properties properties = new Properties();
properties.setProperty("mappers", MAPPER_INTERFACE_REFERENCE);
properties.setProperty("notEmpty", "false");//insert、update是否判斷字符串類型!='' 即 test="str != null"表達式內是否追加 and str != ''
properties.setProperty("IDENTITY", "MYSQL");
mapperScannerConfigurer.setProperties(properties); return mapperScannerConfigurer;
}

生成代碼的實現

在分頁組件,通用mapper都配置完之後,我們需要通過自動生成,根據自定義模板生成我們所需要的<code>Model/<code>、<code>Mapper/<code>、<code>MapperXML/<code>、<code>Service/<code>、<code>ServiceImpl/<code>、<code>Controller/<code>對應的基礎代碼。

首先是模板的定義,定義常用的變量,定製你的代碼,比如<code>service/<code>模板,這樣只要替換對應的變量就可以達到生成需要的代碼的目的。

package ${basePackage}.service;import ${basePackage}.model.${modelNameUpperCamel};import ${basePackage}.common.Service;/**
* Created by ${author} on ${date}.
*/public interface ${modelNameUpperCamel}Service extends Service {
}

然後需要編寫下基於通用MyBatis Mapper插件的Service接口的實現,從而在生成模板中根據該規則打通mapper與service層。

public abstract class AbstractService implements Service { @Autowired
protected Mapper mapper; private Class modelClass; // 當前泛型真實類型的Class
public AbstractService() {
ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
modelClass = (Class) pt.getActualTypeArguments()[0];
} public void save(T model) {
mapper.insertSelective(model);
} public void save(List models) {
mapper.insertList(models);
} public void deleteById(Long id) {
mapper.deleteByPrimaryKey(id);
} public void deleteByIds(String ids) {
mapper.deleteByIds(ids);
} public void update(T model) {
mapper.updateByPrimaryKeySelective(model);
} public T findById(Long id) { return mapper.selectByPrimaryKey(id);
} @Override
public T findBy(String fieldName, Object value) throws TooManyResultsException { try {
T model = modelClass.newInstance();
Field field = modelClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(model, value); return mapper.selectOne(model);
} catch (ReflectiveOperationException e) { throw new ServiceException(e.getMessage(), e);
}
} public List findByIds(String ids) { return mapper.selectByIds(ids);
} public List findByCondition(Condition condition) { return mapper.selectByCondition(condition);
} public List findAll() { return mapper.selectAll();
}
}

具體的詳細代碼可以看下demo。

統一響應結果和異常處理

在配置springMVC時,通過繼承<code>WebMvcConfigurerAdapter/<code>,重寫對應的方法,實現我們一些定製化的需求。

使用<code>FastJson/<code>

阿里的fstjson轉化效率還是比較高的,我們統一替換:

@Overridepublic void configureMessageConverters(List<httpmessageconverter>> converters) {
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
FastJsonConfig config = new FastJsonConfig(); config.setSerializerFeatures(SerializerFeature.WriteMapNullValue,//保留空的字段
SerializerFeature.WriteNullStringAsEmpty,//String null -> ""
SerializerFeature.WriteNullNumberAsZero);//Number null -> 0
converter.setFastJsonConfig(config);
converter.setDefaultCharset(Charset.forName("UTF-8"));
converters.add(converter);
}/<httpmessageconverter>

統一異常處理

統一異常捕獲,在業務失敗直接使用ServiceException("message")拋出,統一輸出<code>{"code":400,"message":"這裡是錯誤消息"}/<code>

@Overridepublic void configureHandlerExceptionResolvers(List<handlerexceptionresolver> exceptionResolvers) {
exceptionResolvers.add((request, response, handler, e) -> {
Result result = new Result(); if (e instanceof ServiceException) {//業務失敗的異常,如“賬號或密碼錯誤”
result.setCode(ResultCode.FAIL).setMessage(e.getMessage());
logger.info(e.getMessage());
} else if (e instanceof NoHandlerFoundException) {
result.setCode(ResultCode.NOT_FOUND).setMessage("接口 [" + request.getRequestURI() + "] 不存在");
} else if (e instanceof ServletException) {
result.setCode(ResultCode.FAIL).setMessage(e.getMessage());
} else {
result.setCode(ResultCode.INTERNAL_SERVER_ERROR).setMessage("接口 [" + request.getRequestURI() + "] 內部錯誤,請聯繫管理員");
String message; if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;

message = String.format("接口 [%s] 出現異常,方法:%s.%s,異常摘要:%s",
request.getRequestURI(),
handlerMethod.getBean().getClass().getName(),
handlerMethod.getMethod().getName(),
e.getMessage());
} else {
message = e.getMessage();
}
logger.error(message, e);
}
responseResult(response, result); return new ModelAndView();
});
}/<handlerexceptionresolver>

統一攔截器

可以通過重寫<code>addInterceptors/<code>方法來自定義攔截,比如說用戶登錄,token驗證等。

@Overridepublic void addInterceptors(InterceptorRegistry registry) { //具體實現}

添加Swagger

之前的文章有具體介紹配置Swagger,這裡只要在之前的基礎上在springMVC配置項下添加swagger資源即可:

@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("swagger-ui.html") .addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**") .addResourceLocations("classpath:/META-INF/resources/webjars/");
}

項目的基本內容介紹到這裡,具體的還是需要大家自行去看想代碼,實際操作一下。

總結

看代碼的學習效率還是比看書快的,多實踐,實踐完看原理,感覺這樣最好。

如果想獲取對應的代碼,可以關注我的公眾號:<code>Bug生活2048/<code>,回覆<code>SpringBoot/<code>就可以啦。

相互學習,共同進步~


分享到:


相關文章: