1. 程式人生 > >【優雅寫程式碼系統】springboot+mybatis+pagehelper+mybatisplus+druid教你如何優雅寫程式碼

【優雅寫程式碼系統】springboot+mybatis+pagehelper+mybatisplus+druid教你如何優雅寫程式碼

[TOC] > springboot 融合了很多外掛。springboot相比spring來說有一下有點 - 自動配置: 針對很多spring的應用程式,springboot提供了很多自動配置 - 起步依賴: 告訴springboot你需要什麼,他就會引入需要的庫 - 命令列介面:springboot的可選特性 - Autuator: 監控springboot專案的執行情況 # spring基本搭建 - springboot的配置很簡單。在pom中繼承springboot的pom .然後依賴一下pom就可以繼承所需的jar了 ```xml org.springframework.boot
spring-boot-starter-parent 2.0.3.RELEASE
``` ```xml org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test ``` - 出了jar外。我們pom中配置一個外掛就行了 ```xml org.springframework.boot spring-boot-maven-plugin
``` # 整合mybatis 【詳見feature/0002/spring-mybatis 分支】 - 之前我們梳理過mybatis的執行機制及注意點。javaweb的開發時離不開spring的。一個完整的框架是離不開spirng的。所以spring整合mybatis勢在必行。我們下面實現如何在spring下融合mybatis及其優秀的一些外掛搭建架構 # pom配置 - 我們在springboot專案的pom中繼續新增我們mybatis的jar就完成了第一步。 - 一個是mybatis與spring的整合jar 。 開啟springboot載入mybatis專案 - 一個是spring的aopjar包。主要是實現mybatis的事務問題 - 一個是mysql的jar包。這裡主要看你自己的需求。如果你的專案中使用oracle那麼久加入oracle的座標就行了 - druid是管理資料的資料來源 ```xml org.mybatis.spring.boot
mybatis-spring-boot-starter 1.3.1
org.springframework.boot spring-boot-starter-aop mysql mysql-connector-java com.alibaba druid 1.1.10 ``` # mybatis配置 - 上面的pom設定已經準備了mybatis開發階段的基本jar。 有了上述的包就可以搭建mybatis . 正常我們在我們的springboot專案中配置一個bean配置的類 `MybatisConfig` ## 設定資料來源 ```java @Bean @ConfigurationProperties("spring.datasource") public DataSource primaryDataSource() { // 這裡為了演示,暫時寫死 。 實際上是可以通過autoConfigure裝配引數的 DruidDataSource dataSource = new DruidDataSource(); dataSource.setUsername("root"); dataSource.setPassword("123456"); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://192.168.44.130:3306/others?useUnicode=true&characterEncoding=utf8"); return dataSource; } ``` - 在springboot中我們只需要在方法上新增`Bean`註解,就相當於我們在spring的xml中配置的bean標籤。在java程式碼中我們可以進行我們業務處理。個人理解感覺更加的可控。 因為我們使用的mysql。所以這裡我們簡單的使用druid的資料來源 ## 設定sqlsessionfactory ```java @Bean public SqlSessionFactory primarySqlSessionFactory() { SqlSessionFactory factory = null; try { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(primaryDataSource()); sqlSessionFactoryBean.setConfigLocation(new DefaultResourceLoader().getResource("classpath:mybatis-primary.xml")); sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:/com/github/zxhtom.**./*.xml")); factory = sqlSessionFactoryBean.getObject(); } catch (Exception e) { e.printStackTrace(); } return factory; } ``` - 在mybatis中sqlsesson是我們操作資料庫最直接的java類。管理sqlsession就是上面的sqlsessionFactory 。 所以我們配置它也是必須的。因為和spring整合。Mybatis的SqlsessionFactory交由給spring的SqlsessionfactoryBean管理。所以我們先構建SqlSessionFactoryBean。然後配置必須的資料來源、Configuration、mybatis的xml路徑等等資訊 - SqlSessionFactoryBean 設定出了spring的FactoryBean屬性意外。最重要的是可以設定Mybatis的sqlsessionfactory的屬性。上面我們只是簡單的設定了。後期可以根據架構的需求進行不斷的完善。 - 可以設定外掛、快取、別名、對映處理器、事務、環境等等所有mybatis的配置 ## 設定掃描 ```java @Bean public MapperScannerConfigurer mapperScannerConfigurer() { MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); mapperScannerConfigurer.setSqlSessionFactory(primarySqlSessionFactory()); //每張表對應的*.java,interface型別的Java檔案 mapperScannerConfigurer.setBasePackage("com.github.zxhtom.**.mapper"); return mapperScannerConfigurer; } ``` - springboot 中我們的mapper介面也是交由spring來掃描的。之前mybatis程式我們是一個一個手動加入的。spring的特性可以直接掃描指定路徑的所有java類。這裡我們就設定了一下mapper的路徑。 ## 設定開啟事務 - 優秀的架構沒有事務是能使用的。我們配置事務也是很簡單的。在springboot中我們推薦使用java程式碼來配置事務的。下面的配置我們為了容易閱讀。配置在TransactionConfig類中 ```java @Bean public DataSourceTransactionManager primaryTransactionManager() { return new DataSourceTransactionManager(dataSource); } ``` - 首先是配置事務管理器。事務管理的是資料來源。所以這裡我們需要將MybatisConfig中的DataSource載入進來。這裡不多說 - 然後配置我們的通知點 ```java @Bean public TransactionInterceptor txAdvice() { DefaultTransactionAttribute txAttr_REQUIRED = new DefaultTransactionAttribute(); txAttr_REQUIRED.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); DefaultTransactionAttribute txAttr_REQUIRED_READONLY = new DefaultTransactionAttribute(); txAttr_REQUIRED_READONLY.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); txAttr_REQUIRED_READONLY.setReadOnly(true); NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource(); source.addTransactionalMethod("add*", txAttr_REQUIRED); source.addTransactionalMethod("save*", txAttr_REQUIRED); source.addTransactionalMethod("delete*", txAttr_REQUIRED); source.addTransactionalMethod("update*", txAttr_REQUIRED); source.addTransactionalMethod("exec*", txAttr_REQUIRED); source.addTransactionalMethod("set*", txAttr_REQUIRED); source.addTransactionalMethod("get*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("query*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("find*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("list*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("count*", txAttr_REQUIRED_READONLY); source.addTransactionalMethod("is*", txAttr_REQUIRED_READONLY); return new TransactionInterceptor(primaryTransactionManager(), source); } ``` - 最後我們配置一下我們的切面、切點 ```java @Bean public Advisor txAdviceAdvisor() { AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); pointcut.setExpression(AOP_POINTCUT_EXPRESSION); return new DefaultPointcutAdvisor(pointcut, txAdvice()); }@Bean public Advisor txAdviceAdvisor() { AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); pointcut.setExpression(AOP_POINTCUT_EXPRESSION); return new DefaultPointcutAdvisor(pointcut, txAdvice()); } ``` - 最後說明下。TransactionConfig這個類因為配置事務、攔截所以我們需要加入如下註解在雷傷 ```java @Configuration @Aspect @EnableTransactionManagement ``` ## 資源放行 - 以上就是mybatis基本的一個配置了。但是這個時候還是不能使用的。因為我們的mapper對應的xml是放在java目錄下的。正常src下都是java。xml檔案在maven編譯時不放行的。我們需要特殊處理下 - 在pom的build下加入放行配置 ```xml src/main/java **/*.xml **/*.properties **/*.yaml true src/main/resources **/*.* false ``` - 加入如下配置後別忘記了clean一下在執行。防止快取。clean之後看看target下檔案 ![](http://oytmxyuek.bkt.clouddn.com/20200610001.jpg) ## 測試 - 為了方便測試我們需要編寫測試類。 ```java @SpringBootTest(classes = Application.class) @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration public class TestDataSource { @Autowired private TestMapper testMapper; @Test public void test() { List> test = testMapper.test(); System.out.println(test); } } ``` ## 結果 ![](http://oytmxyuek.bkt.clouddn.com/20200610002.jpg) - 這裡是我查詢資料庫中的一條資料。主要是測試springboot整合mybatis的流程。到這裡mybatis就整合完了。 # 思考&&疑問 - 上面的配置我們是接入mybatis了。但是在筆者其他架構上測試過。在MybatisConfig這個類中配置資料來源的時候可以直接new出DruidDataSource就可以了。springboot會自動通過DataSourceProperties這個類獲取到資料來源資訊的。但是筆者這裡一直沒有嘗試成功。至於原理更是沒有搞懂了。這裡留下一個彩蛋希望知道的朋友能說說這事怎麼回事 ```java @Bean @ConfigurationProperties(prefix = "spring.datasource") public DataSource primaryDataSource() { return new DruidDataSource(); } ``` - 上述程式碼和本案例中相比就少了很多配置。雖然有的朋友說可以通過對映實體來做。但是直接new物件對我們而言更簡單。疑問 # 使用通用mapper功能 【詳見feature/0002/spring-mybatis-tk-page 分支】 ```xml tk.mybatis mapper 3.3.9 ``` - 這些外掛其實就是改寫我們之前學習的myabtis四大元件中的某一個元件而實現的。所以不管是通用mapper還是後面要說的myabtis-plus都是需要重新改寫我們的myabtis配置類的。 - 首先我們想接入通用mapper時,我們需要改用tk提供的掃包配置 ```java @Bean public MapperScannerConfigurer mapperScannerConfigurer() { tk.mybatis.spring.mapper.MapperScannerConfigurer mapperScannerConfigurer = new tk.mybatis.spring.mapper.MapperScannerConfigurer(); //MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); mapperScannerConfigurer.setSqlSessionFactory(primarySqlSessionFactory()); //每張表對應的*.java,interface型別的Java檔案 mapperScannerConfigurer.setBasePackage("com.github.zxhtom.**.mapper"); return mapperScannerConfigurer; } ``` - 然後新增通用mapper配置 ```java @Bean() public MapperHelper primaryMapperHelper() throws Exception { MapperHelper mapperHelper = new MapperHelper(); Config config = mapperHelper.getConfig(); //表名欄位名使用駝峰轉下劃線大寫形式 config.setStyle(Style.camelhumpAndUppercase); mapperHelper.registerMapper(Mapper.class); mapperHelper.processConfiguration(primarySqlSessionFactory().getConfiguration()); return mapperHelper; } ``` - 測試程式碼就很簡單了。 ```java User user = tkMapper.selectByPrimaryKey(1); ``` # 使用mybatis-plus 【詳見feature/0002/spring-mybatisplus 分支】 - mybatis-plus 實際上就是通用mapper 。這裡可以理解就是不同的實現。接入mybatis-plus其實很簡單。首先我們引入座標 ```xml com.baomidou mybatis-plus-boot-starter 2.2.0 ``` - 然後我們建立實體 ```java @Data @TableName(value = "person_info_large") public class User { @TableId(value = "id",type = IdType.AUTO) private Integer id; private String account; private String name; private String area; private String title; private String motto; } ``` - 然後就是編寫我們的Mapper 。需要繼承BaseMapper ```java public interface PlusMapper extends BaseMapper { } ``` - 上述的編寫之後基本就可以查詢了。但是注意一下我們需要修改上面的myabtisCOnfog這個類。因為接入mybatisplus後需要我們用mybatisplus中的sqlsessionbean。 ```java @Bean public SqlSessionFactory primarySqlSessionFactory() { SqlSessionFactory factory = null; try { MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(primaryDataSource()); sqlSessionFactoryBean.setConfigLocation(new DefaultResourceLoader().getResource("classpath:mybatis-primary.xml")); sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:com/github/zxhtom.**./*.xml")); sqlSessionFactoryBean.setTypeAliasesPackage("com.github.zxhtom.**.model"); factory = sqlSessionFactoryBean.getObject(); } catch (Exception e) { e.printStackTrace(); } return factory; } ``` - 和通用mapper一樣。就這樣我們就可以呼叫BaseMapper為我們提供的方法操作資料庫了。 ```java @Test public void plusTest() { User user = plusMapper.selectById(1); System.out.println(user); } ``` # 使用分頁外掛 ## mybatis-plus自帶分頁 【詳見feature/0002/spring-mybatisplus 分支】 - 首先我們使用mybatis plus自帶的分頁外掛,將外掛類注入到容器中 ```java @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); } ``` - 然後我們查詢的構造一個Page物件就行了。引數分別是第幾頁、展示條數 ```java return plusMapper.selectPage(page, null); ``` - 就是這麼簡單。使用簡單原理才是我們學習的重點。喜歡myabtis外掛原理的可以留言。抽空可以研究 ## github分頁外掛 【詳見feature/0002/spring-mybatis-tk-page 分支】 - 因為myatis-plus自帶了分頁外掛。上面也展示瞭如何使用myabtis-plus外掛。還有一個github上開元的分頁外掛。這裡就和通用mapper進行組合使用 - pagehelper官方更新還是挺勤奮的。提供了pagehelper 和springboot auto裝配兩種。 筆者這裡測試了`pagehelper-spring-boot-starter`這個包不適合本案例中。因為本案例中掃描mapper路徑是通過`MapperScannerConfigurer`註冊的。如果使用`pagehelper-spring-boot-starter`的話就會導致分頁攔截器失效。我們看看原始碼 ![](http://oytmxyuek.bkt.clouddn.com/20200610003.jpg) - 這是因為這版本提供了springboot自動裝配。但是自動裝配的程式碼中進行新增攔截器的時候sqlsessionfactory這個時候還沒有進行掃描mapper.也就沒有進行addMapper 。 所以這個時候新增的攔截器攔截不到我們的mapper . 如果非要使用這個版本的話。我們掃描mapper就不能通過`MapperScannerConfigurer` . 經過筆者測試。需要在MybatisConfig類上新增掃描註解`@MapperScan(basePackages = {"com.github.zxhtom.**.mapper"}, sqlSessionFactoryRef = "primarySqlSessionFactory")` ### 使用常規版本 - 為了符合本版本宗旨 。 我們這裡使用如下座標 ```xml com.github.pagehelper pagehelper 5.1.7 ``` - 使用這個版本pagehelper。 沒有了springboot的自動裝配了。我們可以自己新增外掛。新增外掛有兩種方式。想自動裝配版本一樣通過Configuration進行新增不過我們通過Condition條件選擇新增的時機 。 - 還有一個簡單的方式就是通過`SqlSessionFactoryBean`設定`sqlSessionFactoryBean.setPlugins(new Interceptor[]{new PageInterceptor()});`。 - 因為通過sqlsessionFactoryBean新增的外掛和在settings檔案中新增是一樣的。在通過XmlFactory.build Configuration物件是會自動將外掛裝在上。這個時候mapper也都掃描過了。 ```java @Bean public SqlSessionFactory primarySqlSessionFactory() { SqlSessionFactory factory = null; try { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(primaryDataSource()); sqlSessionFactoryBean.setConfigLocation(new DefaultResourceLoader().getResource("classpath:mybatis-primary.xml")); sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:com/github/zxhtom.**./*.xml")); sqlSessionFactoryBean.setTypeAliasesPackage("com.github.zxhtom.**.model"); sqlSessionFactoryBean.setPlugins(new Interceptor[]{new PageInterceptor()}); factory = sqlSessionFactoryBean.getObject(); } catch (Exception e) { e.printStackTrace(); } return factory; } ``` # 總結 - 這裡簡單闡述下為什麼不適用註解掃描mapper、或者不在配置檔案中配置掃包路徑。因為通過`MapperScannerConfigurer`我們可以動態控制路徑。這樣顯得比較有逼格。在實際開發中筆者推薦使用註解方式掃描。因為這樣可以避免不必要的坑。 - 到這裡我們整理了【springboot整合mybaits】、【mybatis-plus】、【通用mapper】、【pagehelper外掛整合】 這四個模組的整理中我們發現離不開myabtis的四大元件。springboot其實我們還未接觸到深的內容。這篇文章主要偏向myabtis . 後續還會繼續衍生探索 【myabtis+druid】監控資料資訊 。 - 喜歡研究原始碼和開元框架小試牛刀的歡迎關注我 [加入戰隊](#addMe) # # 加入戰隊 ## 微信公眾號 ![微信公眾號](http://oytmxyuek.bkt.clouddn.com/weixin.jpeg) # 主題 ![](http://oytmxyuek.bkt.clouddn.com/plus.jpg) [非xml配置springboot+mybatis事務管理](https://blog.csdn.net/u012688704/article/details/81