本章節開始介紹
數據訪問
方面的相關知識點。對於後端開發者而言,和數據庫打交道是天天都在進行的,因此一個好用的ORM框架
是頗有必要的。目前,絕大部分公司都選擇MyBatis
框架做爲底層數據庫持久化框架。java
看着如今
Mybatis
框架的大行其道,讓我不由想起,大學時期,當時仍是hibernate
的時代,如今基本已經忘記了。而當時,Mybatis
的前身iBatis
還在書中的某個章節出現過。當時大學老師的意思是:目前國內基本沒有使用iBatis
的公司,因此這一章節略過,略,過。。。如今對這個還記憶猶新,看着如今Mybatis
大行其道,不由使人唏噓呀。mysql
Mybatis-Plus(簡稱MP)是一個 Mybatis 的加強工具,在 Mybatis 的基礎上只作加強不作改變,爲簡化開發、提升效率而生。git
官方網站:http://mp.baomidou.comgithub
簡單來講,Mybatis-Plus
是Mybatis
的加強工具包,其簡化了CRUD
操做,提供了代碼生成器
,強大的條件構造器
(這是我最喜歡的一個),同時內置了多個實用插件:標配的分頁
插件、性能分析
插件、全局攔截
插件等。使得開發過程當中,基本的範式代碼都一句話解決了,省去了不少重複的操做(程序猿存在的意義呢,說好的讓咱們搬磚呢!)。web
這裏選用的mybatis-plus版本爲:
2.1.9
, mybatisplus-spring-boot-starter版本爲:1.0.5
。 對應Mybatis版本爲:3.4.5
spring
0. 這裏以user
表爲例子,數據庫爲mysqlsql
DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` bigint(20) DEFAULT NULL COMMENT '惟一標示', `code` varchar(20) DEFAULT NULL COMMENT '編碼', `name` varchar(64) DEFAULT NULL COMMENT '名稱', `status` char(1) DEFAULT '1' COMMENT '狀態 1啓用 0 停用', `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間', `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改時間' ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
1. pom依賴:數據庫
<!--mybatis plus --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatisplus-spring-boot-starter</artifactId> <version>1.0.5</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus</artifactId> <version>2.1.9</version> </dependency>
2. 配置文件(固然也能夠直接使用@Bean的方式進行或者經過application
配置文件進行,詳見官網) **spring-mybatis.xml **apache
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!--建立jdbc數據源 這裏直接使用阿里的druid數據庫鏈接池 --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close"> <property name="driverClassName" value="${mysql.driver}"/> <property name="url" value="${mysql.url}"/> <property name="username" value="${mysql.username}"/> <property name="password" value="${mysql.password}"/> <!-- 初始化鏈接大小 --> <property name="initialSize" value="0"/> <!-- 鏈接池最大使用鏈接數量 --> <property name="maxActive" value="20"/> <!-- 鏈接池最大空閒 --> <property name="maxIdle" value="20"/> <!-- 鏈接池最小空閒 --> <property name="minIdle" value="0"/> <!-- 獲取鏈接最大等待時間 --> <property name="maxWait" value="60000"/> <property name="validationQuery" value="${validationQuery}"/> <property name="testOnBorrow" value="false"/> <property name="testOnReturn" value="false"/> <property name="testWhileIdle" value="true"/> <!-- 配置間隔多久才進行一次檢測,檢測須要關閉的空閒鏈接,單位是毫秒 --> <property name="timeBetweenEvictionRunsMillis" value="60000"/> <!-- 配置一個鏈接在池中最小生存的時間,單位是毫秒 --> <property name="minEvictableIdleTimeMillis" value="25200000"/> <!-- 打開removeAbandoned功能 --> <property name="removeAbandoned" value="true"/> <!-- 1800秒,也就是30分鐘 --> <property name="removeAbandonedTimeout" value="1800"/> <!-- 關閉abanded鏈接時輸出錯誤日誌 --> <property name="logAbandoned" value="true"/> <!-- 監控數據庫 --> <property name="filters" value="mergeStat"/> </bean> <!-- (事務管理)transaction manager, use JtaTransactionManager for global tx --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 可經過註解控制事務 --> <tx:annotation-driven transaction-manager="transactionManager"/> <!--mybatis--> <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!-- 自動掃描mapper.xml文件,支持通配符 --> <property name="mapperLocations" value="classpath:mapper/**/*.xml"/> <!-- 配置文件,好比參數配置(是否啓動駝峯等)、插件配置等 --> <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/> <!-- 啓用別名,這樣就無需寫全路徑類名了,具體可自行查閱資料 --> <property name="typeAliasesPackage" value="cn.lqdev.learning.springboot.chapter9.biz.entity"/> <!-- MP 全局配置注入 --> <property name="globalConfig" ref="globalConfig"/> </bean> <bean id="globalConfig" class="com.baomidou.mybatisplus.entity.GlobalConfiguration"> <!-- AUTO->`0`("數據庫ID自增")QW INPUT->`1`(用戶輸入ID") ID_WORKER->`2`("全局惟一ID") UUID->`3`("全局惟一ID") --> <property name="idType" value="3" /> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- 自動掃描包路徑,接口自動註冊爲一個bean類 --> <property name="basePackage" value="cn.lqdev.learning.springboot.chapter9.biz.dao"/> </bean> </beans>
3. 編寫啓動類,應用啓動時自動加載配置xml文件後端
/** * mybatisPlus 配置類,使其加載配置文件 * @author oKong * */ @Configuration @ImportResource(locations = {"classpath:/mybatis/spring-mybatis.xml"}) //@MapperScan("cn.lqdev.learning.springboot.chapter9.biz.dao") //@EnableTransactionManagement public class MybatisPlusConfig { }
至此,mybatis-plus
就配置完成了,接下來,利用代碼生成器
一次性建立所需的dao
、mapper
、通用CRUD
service類。 **4. 編寫代碼生成器類 ** 因爲生成器依賴velocity
模版引擎,故須要加入依賴:
<dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>2.0</version> <scope>test</scope> </dependency>
MysqlGenerator,此類較長,相關配置可根據實際狀況信息修改替換。
public class MysqlGenerator { private static final String PACKAGE_NAME = "cn.lqdev.learning.springboot.chapter9"; private static final String MODULE_NAME = "biz"; private static final String OUT_PATH = "D:\\develop\\code"; private static final String AUTHOR = "oKong"; private static final String DRIVER = "com.mysql.jdbc.Driver"; private static final String URL = "jdbc:mysql://127.0.0.1:3306/learning?useUnicode=true&characterEncoding=UTF-8"; private static final String USER_NAME = "root"; private static final String PASSWORD = "123456"; /** * <p> * MySQL 生成演示 * </p> */ public static void main(String[] args) { // 自定義須要填充的字段 List<TableFill> tableFillList = new ArrayList<TableFill>(); // 代碼生成器 AutoGenerator mpg = new AutoGenerator().setGlobalConfig( // 全局配置 new GlobalConfig().setOutputDir(OUT_PATH)// 輸出目錄 .setFileOverride(true)// 是否覆蓋文件 .setActiveRecord(true)// 開啓 activeRecord 模式 .setEnableCache(false)// XML 二級緩存 .setBaseResultMap(false)// XML ResultMap .setBaseColumnList(true)// XML columList .setAuthor(AUTHOR) // 自定義文件命名,注意 %s 會自動填充表實體屬性! .setXmlName("%sMapper").setMapperName("%sDao") // .setServiceName("MP%sService") // .setServiceImplName("%sServiceDiy") // .setControllerName("%sAction") ).setDataSource( // 數據源配置 new DataSourceConfig().setDbType(DbType.MYSQL)// 數據庫類型 .setTypeConvert(new MySqlTypeConvert() { // 自定義數據庫表字段類型轉換【可選】 @Override public DbColumnType processTypeConvert(String fieldType) { System.out.println("轉換類型:" + fieldType); // if ( fieldType.toLowerCase().contains( "tinyint" ) ) { // return DbColumnType.BOOLEAN; // } return super.processTypeConvert(fieldType); } }).setDriverName(DRIVER).setUsername(USER_NAME).setPassword(PASSWORD).setUrl(URL)) .setStrategy( // 策略配置 new StrategyConfig() // .setCapitalMode(true)// 全局大寫命名 .setDbColumnUnderline(true)// 全局下劃線命名 // .setTablePrefix(new String[]{"demo_"})// 此處能夠修改成您的表前綴 .setNaming(NamingStrategy.underline_to_camel)// 表名生成策略 // .setInclude(new String[] {"user_org"}) // 須要生成的表 // .setExclude(new String[]{"test"}) // 排除生成的表 // 自定義實體,公共字段 // .setSuperEntityColumns(new String[]{"test_id"}) .setTableFillList(tableFillList) // 自定義實體父類 // .setSuperEntityClass("com.baomidou.demo.common.base.BsBaseEntity") // // 自定義 mapper 父類 // .setSuperMapperClass("com.baomidou.demo.common.base.BsBaseMapper") // // 自定義 service 父類 // .setSuperServiceClass("com.baomidou.demo.common.base.BsBaseService") // // 自定義 service 實現類父類 // .setSuperServiceImplClass("com.baomidou.demo.common.base.BsBaseServiceImpl") // 自定義 controller 父類 // .setSuperControllerClass("com.baomidou.demo.TestController") // 【實體】是否生成字段常量(默認 false) // public static final String ID = "test_id"; .setEntityColumnConstant(true) // 【實體】是否爲構建者模型(默認 false) // public User setName(String name) {this.name = name; return this;} .setEntityBuilderModel(true) // 【實體】是否爲lombok模型(默認 false)<a href="https://projectlombok.org/">document</a> .setEntityLombokModel(true) // Boolean類型字段是否移除is前綴處理 // .setEntityBooleanColumnRemoveIsPrefix(true) // .setRestControllerStyle(true) // .setControllerMappingHyphenStyle(true) ).setPackageInfo( // 包配置 new PackageConfig().setModuleName(MODULE_NAME).setParent(PACKAGE_NAME)// 自定義包路徑 .setController("controller")// 這裏是控制器包名,默認 web .setXml("mapper").setMapper("dao") ).setCfg( // 注入自定義配置,能夠在 VM 中使用 cfg.abc 設置的值 new InjectionConfig() { @Override public void initMap() { Map<String, Object> map = new HashMap<String, Object>(); map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp"); this.setMap(map); } }.setFileOutConfigList( Collections.<FileOutConfig>singletonList(new FileOutConfig("/templates/mapper.xml.vm") { // 自定義輸出文件目錄 @Override public String outputFile(TableInfo tableInfo) { return OUT_PATH + "/xml/" + tableInfo.getEntityName() + "Mapper.xml"; } }))) .setTemplate( // 關閉默認 xml 生成,調整生成 至 根目錄 new TemplateConfig().setXml(null) // 自定義模板配置,模板能夠參考源碼 /mybatis-plus/src/main/resources/template 使用 copy // 至您項目 src/main/resources/template 目錄下,模板名稱也可自定義以下配置: // .setController("..."); // .setEntity("..."); // .setMapper("..."); // .setXml("..."); // .setService("..."); // .setServiceImpl("..."); ); // 執行生成 mpg.execute(); } }
運行後便可,省了多少事!
簡單演示下增刪改查及分頁的使用。
使用分頁時,mybatis-config.xml
須要加入分頁插件:PaginationInterceptor
<plugins> <!-- 分頁插件配置 --> <plugin interceptor="com.baomidou.mybatisplus.plugins.PaginationInterceptor"></plugin> </plugins>
編寫控制層
/** * 用戶控制層 簡單演示增刪改查及分頁 * @author oKong * */ @RestController @RequestMapping("/user") public class UserController { @Autowired IUserService userService; @PostMapping("add") //正常業務時, 須要在user類裏面進行事務控制,控制層通常不進行業務控制的。 //@Transactional(rollbackFor = Exception.class) public Map<String,String> addUser(@Valid @RequestBody UserReq userReq){ User user = new User(); user.setCode(userReq.getCode()); user.setName(userReq.getName()); //因爲設置了主鍵策略 id可不用賦值 會自動生成 //user.setId(0L); userService.insert(user); Map<String,String> result = new HashMap<String,String>(); result.put("respCode", "01"); result.put("respMsg", "新增成功"); //事務測試 //System.out.println(1/0); return result; } @PostMapping("update") public Map<String,String> updateUser(@Valid @RequestBody UserReq userReq){ if(userReq.getId() == null || "".equals(userReq.getId())) { throw new CommonException("0000", "更新時ID不能爲空"); } User user = new User(); user.setCode(userReq.getCode()); user.setName(userReq.getName()); user.setId(Long.parseLong(userReq.getId())); userService.updateById(user); Map<String,String> result = new HashMap<String,String>(); result.put("respCode", "01"); result.put("respMsg", "更新成功"); return result; } @GetMapping("/get/{id}") public Map<String,Object> getUser(@PathVariable("id") String id){ //查詢 User user = userService.selectById(id); if(user == null) { throw new CommonException("0001", "用戶ID:" + id + ",未找到"); } UserResp resp = UserResp.builder() .id(user.getId().toString()) .code(user.getCode()) .name(user.getName()) .status(user.getStatus()) .build(); Map<String,Object> result = new HashMap<String,Object>(); result.put("respCode", "01"); result.put("respMsg", "成功"); result.put("data", resp); return result; } @GetMapping("/page") public Map<String,Object> pageUser(int current, int size){ //分頁 Page<User> page = new Page<>(current, size); Map<String,Object> result = new HashMap<String,Object>(); result.put("respCode", "01"); result.put("respMsg", "成功"); result.put("data", userService.selectPage(page)); return result; } }
啓動應用後,使用postman
依次訪問對應的url地址便可。
新增
數據庫:
分頁
因爲配置了分析插件,控制檯會輸出執行的sql語句
其餘的就不一一貼圖了。
正常狀況下,只須要在服務層中加入
@Transactional
便可,事務相關的此章節不進行闡述,以後有機會會專門拿一個章節來講明下。
示例中爲了方便,直接在控制層中加入了@Transactional
進行事務測試,正式開發過程當中,強烈建議在服務層進行業務控制,控制層通常上是進行邏輯判斷的!
可能在實際開發中,你們會碰到,爲了方便,一些類型、狀態字段會編寫成枚舉類型,好比啓用狀態:DISABLE("0"),ENABLE("1")。此時可經過配置
typeHandlers
進行自定義類型的處理,這裏簡單以EnumOrdinalTypeHandler(存儲enum類裏的序號值)
進行示例,固然也可根據須要進行自定義處理器的編寫,好比編寫一個通用的枚舉轉換器等,其餘相關知識點,你們可自行谷歌。
StatusEnums
public enum StatusEnum { DISABLE, ENABLE; }
將user對象修改爲枚舉類型
/** * 狀態1 啓用 0 停用 */ private StatusEnum status;
配置文件mybatis-config.xml
加入處理類
<typeHandlers> <typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler" javaType="cn.lqdev.learning.springboot.chapter9.biz.entity.StatusEnum"/> </typeHandlers>
以後就會自動進行轉換了。你們可下載示例,進行實際操做下。
本章節主要是對
Mybatis-plus
的集成和簡單使用進行了說明,詳細的用法,可到官網查看,官網有詳細的使用指南,這裏就不班門弄斧了。至此,對於通常的開發需求基本上均可以知足了。接下來的章節會重點講解其餘配套工具的使用,敬請期待!
目前互聯網上不少大佬都有
springboot
系列教程,若有雷同,請多多包涵了。本文是做者在電腦前一字一句敲的,每一步都是實踐的。若文中有所錯誤之處,還望提出,謝謝。
499452441
lqdevOps
原文地址:https://blog.lqdev.cn/2018/07/21/springboot/chapter-nine/
完整示例:chapter-9