iBase4J项目笔记
目錄:
1 數(shù)據(jù)庫密碼加密
2 service層概述
3 web層概述
4 后端CRUD
4.1 READ
4.2 UPDATE
4.3 CREATE
4.4 DELETE
5 facade層概述
1 數(shù)據(jù)庫密碼加密
iBase4J項目的service層中數(shù)據(jù)庫配置文件中數(shù)據(jù)庫的連接密碼必須是經(jīng)過加密過后的,如何獲取加密方法
1.1 加密類是 org.ibase4j.core.util.PropertiesUtil
end
2 Service層
2.1 所有service層都繼承于BaseService
package top.ibase4j.core.base;import java.util.Date; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.RandomUtils; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheConfig; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.dao.DuplicateKeyException; import org.springframework.transaction.annotation.Transactional;import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.baomidou.mybatisplus.mapper.Wrapper; import com.baomidou.mybatisplus.plugins.Page;import top.ibase4j.core.Constants; import top.ibase4j.core.util.CacheUtil; import top.ibase4j.core.util.DataUtil; import top.ibase4j.core.util.ExceptionUtil; import top.ibase4j.core.util.InstanceUtil; import top.ibase4j.core.util.PropertiesUtil;/*** 業(yè)務(wù)邏輯層基類,繼承基類后必須配置CacheConfig(cacheNames="")* * @author ShenHuaJie* @version 2016年5月20日 下午3:19:19*/ public abstract class BaseService<T extends BaseModel> implements ApplicationContextAware {protected Logger logger = LogManager.getLogger(getClass());@Autowiredprotected BaseMapper<T> mapper;protected ApplicationContext applicationContext;int maxThread = PropertiesUtil.getInt("db.reader.list.maxThread", 50);int threadSleep = PropertiesUtil.getInt("db.reader.list.threadWait", 5);ExecutorService executorService = Executors.newFixedThreadPool(maxThread);/*** 分頁查詢* @param params* @return*/@SuppressWarnings("unchecked")public static Page<Long> getPage(Map<String, Object> params) {Integer current = 1;Integer size = 10;String orderBy = "id_", sortAsc = null;if (DataUtil.isNotEmpty(params.get("pageNumber"))) {current = Integer.valueOf(params.get("pageNumber").toString());}if (DataUtil.isNotEmpty(params.get("pageIndex"))) {current = Integer.valueOf(params.get("pageIndex").toString());}if (DataUtil.isNotEmpty(params.get("pageSize"))) {size = Integer.valueOf(params.get("pageSize").toString());}if (DataUtil.isNotEmpty(params.get("limit"))) {size = Integer.valueOf(params.get("limit").toString());}if (DataUtil.isNotEmpty(params.get("offset"))) {current = Integer.valueOf(params.get("offset").toString()) / size + 1;}if (DataUtil.isNotEmpty(params.get("sort"))) {orderBy = (String)params.get("sort");params.remove("sort");}if (DataUtil.isNotEmpty(params.get("orderBy"))) {orderBy = (String)params.get("orderBy");params.remove("orderBy");}if (DataUtil.isNotEmpty(params.get("sortAsc"))) {sortAsc = (String)params.get("sortAsc");params.remove("sortAsc");}Object filter = params.get("filter");if (filter != null) {params.clear();params.putAll(JSON.parseObject(filter.toString(), Map.class));}if (size == -1) {Page<Long> page = new Page<Long>();page.setOrderByField(orderBy);page.setAsc("Y".equals(sortAsc));return page;}Page<Long> page = new Page<Long>(current, size, orderBy);page.setAsc("Y".equals(sortAsc));return page;}/*** @param id* @param userId*/@Transactionalpublic void del(Long id, Long userId) {try {T record = this.queryById(id);record.setEnable(0);record.setUpdateTime(new Date());record.setUpdateBy(userId);mapper.updateById(record);try {CacheUtil.getCache().set(getCacheKey(id), record);} catch (Exception e) {logger.error(Constants.Exception_Head, e);}} catch (Exception e) {throw new RuntimeException(e.getMessage(), e);}}/*** @param id*/@Transactionalpublic void delete(Long id) {try {mapper.deleteById(id);} catch (Exception e) {throw new RuntimeException(e.getMessage(), e);}try {CacheUtil.getCache().del(getCacheKey(id));} catch (Exception e) {logger.error(Constants.Exception_Head, e);}}/*** @param t* @return*/@Transactionalpublic Integer deleteByEntity(T t) {Wrapper<T> wrapper = new EntityWrapper<T>(t);return mapper.delete(wrapper);}/*** @param columnMap* @return*/@Transactionalpublic Integer deleteByMap(Map<String, Object> columnMap) {return mapper.deleteByMap(columnMap);}/*** 根據(jù)Id查詢(默認(rèn)類型T)* @param ids* @return*/public List<T> getList(final List<Long> ids) {final List<T> list = InstanceUtil.newArrayList();if (ids != null) {for (int i = 0; i < ids.size(); i++) {list.add(null);}final Map<Integer, Object> thread = InstanceUtil.newConcurrentHashMap();for (int i = 0; i < ids.size(); i++) {final int index = i;executorService.execute(new Runnable() {public void run() {try {list.set(index, queryById(ids.get(index)));} finally {thread.put(index, 0);}}});}while (thread.size() < list.size()) {try {Thread.sleep(threadSleep);} catch (InterruptedException e) {logger.error("", e);}}}return list;}/*** 根據(jù)Id查詢(cls返回類型Class)* @param ids* @param cls* @return*/public <K> List<K> getList(final List<Long> ids, final Class<K> cls) {final List<K> list = InstanceUtil.newArrayList();if (ids != null) {for (int i = 0; i < ids.size(); i++) {list.add(null);}final Map<Integer, Object> thread = InstanceUtil.newConcurrentHashMap();for (int i = 0; i < ids.size(); i++) {final int index = i;executorService.execute(new Runnable() {public void run() {try {T t = queryById(ids.get(index));K k = InstanceUtil.to(t, cls);list.set(index, k);} finally {thread.put(index, 0);}}});}while (thread.size() < list.size()) {try {Thread.sleep(threadSleep);} catch (InterruptedException e) {logger.error("", e);}}}return list;}/*** 根據(jù)Id查詢(默認(rèn)類型T)* @param ids* @return*/public Page<Map<String, Object>> getPageMap(final Page<Long> ids) {if (ids != null) {Page<Map<String, Object>> page = new Page<Map<String, Object>>(ids.getCurrent(), ids.getSize());page.setTotal(ids.getTotal());final List<Map<String, Object>> records = InstanceUtil.newArrayList();for (int i = 0; i < ids.getRecords().size(); i++) {records.add(null);}final Map<Integer, Object> thread = InstanceUtil.newConcurrentHashMap();for (int i = 0; i < ids.getRecords().size(); i++) {final int index = i;executorService.execute(new Runnable() {public void run() {try {records.set(index, InstanceUtil.transBean2Map(queryById(ids.getRecords().get(index))));} finally {thread.put(index, 0);}}});}while (thread.size() < records.size()) {try {Thread.sleep(threadSleep);} catch (InterruptedException e) {logger.error("", e);}}page.setRecords(records);return page;}return new Page<Map<String, Object>>();}/*** @param params* @return*/public Page<T> query(Map<String, Object> params) {Page<Long> page = getPage(params);page.setRecords(mapper.selectIdPage(page, params));return getPage(page);}/*** @param id* @return*/@Transactionalpublic T queryById(Long id) {return queryById(id, 1);}/*** @param params* @return*/public List<T> queryList(Map<String, Object> params) {List<Long> ids = mapper.selectIdPage(params);List<T> list = getList(ids);return list;}/*** @param entity* @return*/public List<T> selectList(Wrapper<T> entity) {return mapper.selectList(entity);}/*** @param entity* @return*/public T selectOne(T entity) {return mapper.selectOne(entity);}/* (non-Javadoc)* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.* ApplicationContext) */public void setApplicationContext(ApplicationContext applicationContext) {this.applicationContext = applicationContext;}/*** @param record* @return*/@SuppressWarnings("unchecked")@Transactionalpublic T update(T record) {try {record.setUpdateTime(new Date());if (record.getId() == null) {record.setCreateTime(new Date());mapper.insert(record);try {CacheUtil.getCache().set(getCacheKey(record.getId()), record);} catch (Exception e) {logger.error(Constants.Exception_Head, e);}} else {String lockKey = getLockKey("U" + record.getId());if (CacheUtil.tryLock(lockKey)) {try {T org = null;String key = getCacheKey(record.getId());try {org = (T)CacheUtil.getCache().get(key);} catch (Exception e) {logger.error(Constants.Exception_Head, e);}if (org == null) {org = mapper.selectById(record.getId());}T update = InstanceUtil.getDiff(org, record);update.setId(record.getId());mapper.updateById(update);record = mapper.selectById(record.getId());try {CacheUtil.getCache().set(key, record);} catch (Exception e) {logger.error(Constants.Exception_Head, e);}} finally {CacheUtil.unlock(lockKey);}} else {throw new RuntimeException("數(shù)據(jù)不一致!請刷新頁面重新編輯!");}}} catch (DuplicateKeyException e) {logger.error(Constants.Exception_Head, e);throw new RuntimeException("已經(jīng)存在相同的配置.");} catch (Exception e) {logger.error(Constants.Exception_Head, e);throw new RuntimeException(ExceptionUtil.getStackTraceAsString(e));}return record;}/*** 獲取緩存鍵值* @param id* @return*/protected String getCacheKey(Object id) {String cacheName = getCacheKey();return new StringBuilder(Constants.CACHE_NAMESPACE).append(cacheName).append(":").append(id).toString();}/*** 獲取緩存鍵值* @param id* @return*/protected String getLockKey(Object id) {String cacheName = getCacheKey();return new StringBuilder(Constants.CACHE_NAMESPACE).append(cacheName).append(":LOCK:").append(id).toString();}/*** @param params* @param cls* @return*/protected <P> Page<P> query(Map<String, Object> params, Class<P> cls) {Page<Long> page = getPage(params);page.setRecords(mapper.selectIdPage(page, params));return getPage(page, cls);}/*** @param millis*/protected void sleep(int millis) {try {Thread.sleep(RandomUtils.nextLong(10, millis));} catch (InterruptedException e) {logger.error("", e);}}/*** @return*/private String getCacheKey() {Class<?> cls = getClass();String cacheName = Constants.cacheKeyMap.get(cls);if (StringUtils.isBlank(cacheName)) {CacheConfig cacheConfig = cls.getAnnotation(CacheConfig.class);if (cacheConfig != null && ArrayUtils.isNotEmpty(cacheConfig.cacheNames())) {cacheName = cacheConfig.cacheNames()[0];} else {cacheName = getClass().getName();}Constants.cacheKeyMap.put(cls, cacheName);}return cacheName;}/** 根據(jù)Id查詢(默認(rèn)類型T) */private Page<T> getPage(final Page<Long> ids) {if (ids != null) {Page<T> page = new Page<T>(ids.getCurrent(), ids.getSize());page.setTotal(ids.getTotal());final List<T> records = InstanceUtil.newArrayList();for (int i = 0; i < ids.getRecords().size(); i++) {records.add(null);}final Map<Integer, Object> thread = InstanceUtil.newConcurrentHashMap();for (int i = 0; i < ids.getRecords().size(); i++) {final int index = i;executorService.execute(new Runnable() {public void run() {try {records.set(index, queryById(ids.getRecords().get(index)));} finally {thread.put(index, 0);}}});}while (thread.size() < records.size()) {try {Thread.sleep(threadSleep);} catch (InterruptedException e) {logger.error("", e);}}page.setRecords(records);return page;}return new Page<T>();}/** 根據(jù)Id查詢(cls返回類型Class) */private <K> Page<K> getPage(final Page<Long> ids, final Class<K> cls) {if (ids != null) {Page<K> page = new Page<K>(ids.getCurrent(), ids.getSize());page.setTotal(ids.getTotal());final List<K> records = InstanceUtil.newArrayList();for (int i = 0; i < ids.getRecords().size(); i++) {records.add(null);}final Map<Integer, Object> thread = InstanceUtil.newConcurrentHashMap();for (int i = 0; i < ids.getRecords().size(); i++) {final int index = i;executorService.execute(new Runnable() {public void run() {try {T t = queryById(ids.getRecords().get(index));K k = InstanceUtil.to(t, cls);records.set(index, k);} finally {thread.put(index, 0);}}});}while (thread.size() < records.size()) {try {Thread.sleep(threadSleep);} catch (InterruptedException e) {logger.error("", e);}}page.setRecords(records);return page;}return new Page<K>();}@SuppressWarnings("unchecked")private T queryById(Long id, int times) {String key = getCacheKey(id);T record = null;try {record = (T)CacheUtil.getCache().get(key);} catch (Exception e) {logger.error(Constants.Exception_Head, e);}if (record == null) {String lockKey = getLockKey(id);if (CacheUtil.tryLock(lockKey)) {try {record = mapper.selectById(id);try {CacheUtil.getCache().set(key, record);} catch (Exception e) {logger.error(Constants.Exception_Head, e);}} finally {CacheUtil.unlock(lockKey);}} else {if (times > 3) {return mapper.selectById(id);}logger.debug(getClass().getSimpleName() + ":" + id + " retry queryById.");sleep(20);return queryById(id, times + 1);}}return record;} } BaseService技巧01:BaseService類實現(xiàn)了ApplicationContextAware后就可以通過ApplicationContext類型的成員變量去獲取在spring容器中定義的其他bean了
protected ApplicationContext applicationContext;參考文檔:點擊前往
技巧02:BaseService類提供了一些類的數(shù)據(jù)操作方法
2.2 SysUserService類的query方法詳解
注意:僅僅解釋如何獲取數(shù)據(jù),權(quán)限先關(guān)的暫時還未弄清楚,當(dāng)更新
2.2.1 調(diào)用父類的query方法
技巧01:query方法是一個沒有約束的查詢方法,該方法的參數(shù)是和分頁查詢有關(guān)的,不涉及任何與條件查詢相關(guān)的參數(shù)
/*** @param params* @return*/public Page<T> query(Map<String, Object> params) {Page<Long> page = getPage(params);page.setRecords(mapper.selectIdPage(page, params));return getPage(page);}技巧02:從query方法的源代碼中可以看出,query方法調(diào)用了BaseService類中的getPage方法
/*** 分頁查詢* @param params* @return*/@SuppressWarnings("unchecked")public static Page<Long> getPage(Map<String, Object> params) {Integer current = 1;Integer size = 10;String orderBy = "id_", sortAsc = null;if (DataUtil.isNotEmpty(params.get("pageNumber"))) {current = Integer.valueOf(params.get("pageNumber").toString());}if (DataUtil.isNotEmpty(params.get("pageIndex"))) {current = Integer.valueOf(params.get("pageIndex").toString());}if (DataUtil.isNotEmpty(params.get("pageSize"))) {size = Integer.valueOf(params.get("pageSize").toString());}if (DataUtil.isNotEmpty(params.get("limit"))) {size = Integer.valueOf(params.get("limit").toString());}if (DataUtil.isNotEmpty(params.get("offset"))) {current = Integer.valueOf(params.get("offset").toString()) / size + 1;}if (DataUtil.isNotEmpty(params.get("sort"))) {orderBy = (String)params.get("sort");params.remove("sort");}if (DataUtil.isNotEmpty(params.get("orderBy"))) {orderBy = (String)params.get("orderBy");params.remove("orderBy");}if (DataUtil.isNotEmpty(params.get("sortAsc"))) {sortAsc = (String)params.get("sortAsc");params.remove("sortAsc");}Object filter = params.get("filter");if (filter != null) {params.clear();params.putAll(JSON.parseObject(filter.toString(), Map.class));}if (size == -1) {Page<Long> page = new Page<Long>();page.setOrderByField(orderBy);page.setAsc("Y".equals(sortAsc));return page;}Page<Long> page = new Page<Long>(current, size, orderBy);page.setAsc("Y".equals(sortAsc));return page;} getPage技巧03:getPage方法主要是查看query方法中的參數(shù)是否有和分頁查詢相關(guān)的參數(shù),如果有就將這些參數(shù)封裝成一個對象返回給query方法使用
技巧04:mapper.selectIdPage(page, params)的作用是調(diào)用相應(yīng)的mapper接口去獲取數(shù)據(jù)
技巧05:page.setRecords(mapper.selectIdPage(page, params));的作用是將獲取到的數(shù)據(jù)封裝到一個page對象中
技巧06:getPage(page);的作用是對獲取到的數(shù)據(jù)進一步進行封裝,僅僅將需要查詢的頁碼數(shù)據(jù)進行封裝
2.2.2 向web層返回一個Page對象
技巧01:該Page對象封裝了查詢到的數(shù)據(jù)信息,以及一些分頁查詢參數(shù)
?end
3 Web層
3.1 所有的web層都會繼承AbstractController
/*** */ package top.ibase4j.core.base;import java.util.Date; import java.util.List; import java.util.Map;import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.ui.ModelMap;import com.baomidou.mybatisplus.plugins.Page;/*** 控制器基類* * @author ShenHuaJie* @version 2016年5月20日 下午3:47:58*/ public abstract class AbstractController<T extends BaseProvider> extends BaseController {protected final Logger logger = LogManager.getLogger(this.getClass());@Autowiredprotected T provider;public abstract String getService();public Object query(ModelMap modelMap, Map<String, Object> param) {if (param.get("keyword") == null && param.get("search") != null) {param.put("keyword", param.get("search"));}Parameter parameter = new Parameter(getService(), "query", param);logger.info("{} execute query start...", parameter.getNo());Page<?> list = provider.execute(parameter).getResultPage();logger.info("{} execute query end.", parameter.getNo());return setSuccessModelMap(modelMap, list);}public Object queryList(ModelMap modelMap, Map<String, Object> param) {Parameter parameter = new Parameter(getService(), "queryList", param);logger.info("{} execute queryList start...", parameter.getNo());List<?> list = provider.execute(parameter).getResultList();logger.info("{} execute queryList end.", parameter.getNo());return setSuccessModelMap(modelMap, list);}public Object get(ModelMap modelMap, BaseModel param) {Parameter parameter = new Parameter(getService(), "queryById", param.getId());logger.info("{} execute queryById start...", parameter.getNo());Object result = provider.execute(parameter).getResult();logger.info("{} execute queryById end.", parameter.getNo());return setSuccessModelMap(modelMap, result);}public Object update(ModelMap modelMap, BaseModel param) {Long userId = getCurrUser();if (param.getId() == null) {param.setCreateBy(userId);param.setCreateTime(new Date());}param.setUpdateBy(userId);param.setUpdateTime(new Date());Parameter parameter = new Parameter(getService(), "update", param);logger.info("{} execute update start...", parameter.getNo());provider.execute(parameter);logger.info("{} execute update end.", parameter.getNo());return setSuccessModelMap(modelMap);}public Object delete(ModelMap modelMap, BaseModel param) {Parameter parameter = new Parameter(getService(), "delete", param.getId());logger.info("{} execute delete start...", parameter.getNo());provider.execute(parameter);logger.info("{} execute delete end.", parameter.getNo());return setSuccessModelMap(modelMap);} } AbstractController技巧01:AbstractController中的BaseProvider對象通過excute方法去調(diào)用Service層相關(guān)方法,excute方法接收的是一個包含service名稱、service中的方法名稱、參數(shù)封裝成的的Parameter對象;Page<?> list = provider.execute(parameter).getResultPage()的作用是將從service層查詢到的數(shù)據(jù)放到一個Page對象中;return setSuccessModelMap(modelMap, list)的作用是將數(shù)據(jù)進行封裝并放回給前端
技巧02:AbsstractController中的抽象方法getService是用來指定調(diào)用那個Service的,返回值是一個字符串;所有繼承自AbsstractController的類都必須實現(xiàn)該方法,因為在調(diào)用Service層的時候回用到該方法,而且該方法在AbsstractController是一個抽象方法,所有的子類必須實現(xiàn)
3.2 AbstractController還繼承自BaseController接口
該接口提供了最外層數(shù)據(jù)的封裝方法
/*** */ package top.ibase4j.core.base;import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Map;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.shiro.authz.UnauthorizedException; import org.springframework.beans.propertyeditors.CustomDateEditor; import org.springframework.http.ResponseEntity; import org.springframework.ui.ModelMap; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.InitBinder;import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.SerializerFeature; import com.baomidou.mybatisplus.plugins.Page;import top.ibase4j.core.Constants; import top.ibase4j.core.exception.BaseException; import top.ibase4j.core.exception.IllegalParameterException; import top.ibase4j.core.support.DateFormat; import top.ibase4j.core.support.HttpCode; import top.ibase4j.core.util.InstanceUtil; import top.ibase4j.core.util.WebUtil;/*** 控制器基類* * @author ShenHuaJie* @version 2016年5月20日 下午3:47:58*/ public abstract class BaseController {protected final Logger logger = LogManager.getLogger(this.getClass());/** 獲取當(dāng)前用戶Id */protected Long getCurrUser() {return WebUtil.getCurrentUser();}@InitBinderprotected void initBinder(WebDataBinder binder) {binder.registerCustomEditor(Date.class, new CustomDateEditor(new DateFormat(), true));}/** 設(shè)置成功響應(yīng)代碼 */protected ResponseEntity<ModelMap> setSuccessModelMap(ModelMap modelMap) {return setSuccessModelMap(modelMap, null);}/** 設(shè)置成功響應(yīng)代碼 */protected ResponseEntity<ModelMap> setSuccessModelMap(ModelMap modelMap, Object data) {return setModelMap(modelMap, HttpCode.OK, data);}/** 設(shè)置響應(yīng)代碼 */protected ResponseEntity<ModelMap> setModelMap(ModelMap modelMap, HttpCode code) {return setModelMap(modelMap, code, null);}/** 設(shè)置響應(yīng)代碼 */protected ResponseEntity<ModelMap> setModelMap(ModelMap modelMap, HttpCode code, Object data) {Map<String, Object> map = InstanceUtil.newLinkedHashMap();map.putAll(modelMap);modelMap.clear();for (Iterator<String> iterator = map.keySet().iterator(); iterator.hasNext();) {String key = iterator.next();if (!key.startsWith("org.springframework.validation.BindingResult") && !key.equals("void")) {modelMap.put(key, map.get(key));}}if (data != null) {if (data instanceof Page) {Page<?> page = (Page<?>)data;modelMap.put("rows", page.getRecords());modelMap.put("current", page.getCurrent());modelMap.put("size", page.getSize());modelMap.put("pages", page.getPages());modelMap.put("total", page.getTotal());} else if (data instanceof List<?>) {modelMap.put("rows", data);modelMap.put("total", ((List<?>)data).size());} else {modelMap.put("data", data);}}modelMap.put("code", code.value().toString());modelMap.put("msg", code.msg());modelMap.put("timestamp", System.currentTimeMillis());logger.info("RESPONSE : " + JSON.toJSONString(modelMap));return ResponseEntity.ok(modelMap);}/** 異常處理 */@ExceptionHandler(Exception.class)public void exceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception ex)throws Exception {logger.error(Constants.Exception_Head, ex);ModelMap modelMap = new ModelMap();if (ex instanceof BaseException) {((BaseException)ex).handler(modelMap);} else if (ex instanceof IllegalArgumentException) {new IllegalParameterException(ex.getMessage()).handler(modelMap);} else if (ex instanceof UnauthorizedException) {modelMap.put("code", HttpCode.FORBIDDEN.value().toString());modelMap.put("msg", StringUtils.defaultIfBlank(ex.getMessage(), HttpCode.FORBIDDEN.msg()));} else {modelMap.put("code", HttpCode.INTERNAL_SERVER_ERROR.value().toString());String msg = StringUtils.defaultIfBlank(ex.getMessage(), HttpCode.INTERNAL_SERVER_ERROR.msg());modelMap.put("msg", msg.length() > 100 ? "系統(tǒng)走神了,請稍候再試." : msg);}response.setContentType("application/json;charset=UTF-8");modelMap.put("timestamp", System.currentTimeMillis());logger.info("RESPONSE : " + JSON.toJSON(modelMap));byte[] bytes = JSON.toJSONBytes(modelMap, SerializerFeature.DisableCircularReferenceDetect);response.getOutputStream().write(bytes);} } BaseControllerend
4 后端CRUD
4.1 READ
4.1.1 在數(shù)據(jù)庫中創(chuàng)建一個名為 test_user 表
坑01:如果和數(shù)據(jù)庫表對應(yīng)的實體類繼承了BaseModel類,那么在創(chuàng)建數(shù)據(jù)庫表時就必須在數(shù)據(jù)表中添加和BaseModel中屬性對應(yīng)的字段,否則就會報錯:XXX字段不存在
CREATE TABLE `NewTable` ( `id_` bigint(20) NOT NULL , `name` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL , `phone` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' , `enable_` int(11) NOT NULL , `remark_` varchar(22) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , `create_by` bigint(22) NULL DEFAULT NULL , `create_time` date NULL DEFAULT NULL , `update_by` bigint(20) NULL DEFAULT NULL , `update_time` date NULL DEFAULT NULL , `keyword` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , PRIMARY KEY (`id_`) ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci ROW_FORMAT=COMPACT ;4.1.2 在facade層創(chuàng)建一個名為 Test.java 實體類
技巧01:將每個實體類中公用的屬性提取出來作為父類,在iBase4j中是將公用的屬性提取出來放在了BaseModel中
坑01:由于實體類繼承了BaseModel,所以和實體類對應(yīng)的數(shù)據(jù)庫表必須有和BaseModel對應(yīng)的字段,否則會報錯:XXX字段不存在
package org.ibase4j.model;import com.baomidou.mybatisplus.annotations.TableField; import com.baomidou.mybatisplus.annotations.TableName;import top.ibase4j.core.base.BaseModel;@TableName("test_user") @SuppressWarnings("serial") public class Test extends BaseModel {@TableField("name")private String name;@TableField("phone")private String phone;@TableField(exist = false)private String oldPassword;@TableField(exist = false)private String deptName;@TableField(exist = false)private String userTypeText;@TableField(exist = false)private String permission;public String getOldPassword() {return oldPassword;}public void setOldPassword(String oldPassword) {this.oldPassword = oldPassword;}public String getDeptName() {return deptName;}public void setDeptName(String deptName) {this.deptName = deptName;}public String getUserTypeText() {return userTypeText;}public void setUserTypeText(String userTypeText) {this.userTypeText = userTypeText;}public String getPermission() {return permission;}public void setPermission(String permission) {this.permission = permission;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}} Test.java4.1.3 在service層創(chuàng)建一個名為?TestService.java 服務(wù)類
技巧01:在iBase4j中所有的服務(wù)類都繼承了BaseService類,因為在BaseService類中基本的CRUD方法
技巧02:在自定義的服務(wù)中定義一個查詢方法,在這個查詢方法中調(diào)用父類的query方法進行查詢
坑01:自定義服務(wù)類在繼承BaseService服務(wù)類時需要制定泛型類型,這個泛型類型必須是facade中定義的實體類,即使是Object類型也會報錯
package org.ibase4j.service;import java.util.List; import java.util.Map;import org.apache.commons.lang3.StringUtils; import org.ibase4j.mapper.SysUserThirdpartyMapper; import org.ibase4j.model.SysUser; import org.ibase4j.model.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;import com.baomidou.mybatisplus.plugins.Page;import top.ibase4j.core.base.BaseService;@Service public class TestService extends BaseService<Test> {@Autowiredprivate SysUserThirdpartyMapper thirdpartyMapper;@Autowiredprivate SysDicService sysDicService;@Autowiredprivate SysDeptService sysDeptService;@Autowiredprivate SysAuthorizeService sysAuthorizeService;// public Page<SysUser> query(Map<String, Object> params) { // System.out.println("測試服務(wù)層"); // Map<String, String> userTypeMap = sysDicService.queryDicByType("USERTYPE"); // Page<SysUser> pageInfo = super.query(params); // for (SysUser userBean : pageInfo.getRecords()) { // if (userBean.getUserType() != null) { // userBean.setUserTypeText(userTypeMap.get(userBean.getUserType())); // } // List<String> permissions = sysAuthorizeService.queryUserPermission(userBean.getId()); // for (String permission : permissions) { // if (StringUtils.isBlank(userBean.getPermission())) { // userBean.setPermission(permission); // } else { // userBean.setPermission(userBean.getPermission() + ";" + permission); // } // } // } // return pageInfo; // }public Page<Test> query(Map<String, Object> params) { // Page<Test> pageInfo = new Page<Test>();Page<Test> pageInfo = super.query(params);return pageInfo;}} TestService.java4.1.4 在service層中創(chuàng)建一個名為 TestMapper.java 接口
這個接口就類似于springboot中的JPA接口,該接口和對應(yīng)的XML文件配合來實現(xiàn)數(shù)據(jù)庫的CRUD操作
技巧01:自定義的DAO接口繼承自BaseMapper接口,BaseMapper接口中定義了公用的分頁查詢
package org.ibase4j.mapper;import java.util.List; import java.util.Map;import org.apache.ibatis.annotations.Param; import org.ibase4j.model.Test;import top.ibase4j.core.base.BaseMapper;public interface TestMapper extends BaseMapper<Test> {List<Long> selectIdPage(@Param("cm") Map<String, Object> params); } TestMapper.java4.1.5 在service層中創(chuàng)建一個名為 TestMapper.xml 文件
這個自定義的XML文件主要是和Mapper接口配合使用實現(xiàn)數(shù)據(jù)庫的CRUD操作的
詳情請參見mybatis先關(guān)的技術(shù)文檔
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="org.ibase4j.mapper.TestMapper"><!-- 查詢列表--><select id="selectIdPage" resultType="java.lang.Long">SELECT id_ FROM test_userORDER BY id_ DESC</select> </mapper>4.1.6 在web層創(chuàng)建一個名為 TestController.java 控制類
自定義的控制類必須繼承AbstractController,因為在AbstractController類中封裝了CRUD操作
技巧01:繼承AbstractController類后必須實現(xiàn)getService方法,該方法的返回值就是service層中對應(yīng)的一個服務(wù)類的類名(PS:類名首字母小寫后的結(jié)果)
技巧02:在自定義的控制類中隨便寫一個方法,然后在該方法中調(diào)用的父類的query方法就可以實現(xiàn)數(shù)據(jù)查詢操作了
package org.ibase4j.web;import java.util.Map;import org.ibase4j.provider.ISysProvider; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import top.ibase4j.core.base.AbstractController;@RestController @RequestMapping(value = "/test") public class TestController extends AbstractController<ISysProvider> {@Overridepublic String getService() {// TODO Auto-generated method stubreturn "testService";}@PutMapping(value = "/test01")public Object test01(ModelMap modelMap, @RequestBody Map<String, Object> param) {System.out.println("測試控制層"); // return "測試請求成功";return super.query(modelMap, param);}} TestController.java4.1.7 效果展示
利用Postman或者Advanced REST client 模擬前端進行測試即可
坑01:由于iBase4j后臺默認(rèn)使用的是分頁查詢,所以在請求中必須傳入pageSize的值,例如:
請求成功后的效果如下:
4.2 UPDATE
待更新......2018年3月21日09:21:09
4.3 CREATE
待更新......2018-3-21 09:21:21
4.4 DELETE
待更新......2018-3-21 09:21:29
?end
5 facade層概述
facade中主要編寫的是實體類,每一個實體類都和數(shù)據(jù)庫中表有著嚴(yán)格的對應(yīng)關(guān)系;每個實體類類都繼承自BaseModel,在BaseModel中定義了一些通用的屬性,例如:id、enable、remark等等
坑01:由于所有的實體類都繼承自BaseModel類,所以在創(chuàng)建數(shù)據(jù)庫時BaseModel中的屬性必須有相應(yīng)的字段與其對應(yīng),否則在啟動service層時會報錯:XXX字段不存在
end
?
轉(zhuǎn)載于:https://www.cnblogs.com/NeverCtrl-C/p/8253157.html
總結(jié)
以上是生活随笔為你收集整理的iBase4J项目笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python 实现微信小程序的用户登录
- 下一篇: Spark天堂之门解密