Tkmybatis快速入手
Tkmybatis
案例碼云地址:使用 git clone 即可查看
https://gitee.com/JavaBigDataStudy/tk-mybatis-jpa-demo.git
讓你遠離sql語句的Mybatis工具==>去除mapper.xml
只需三步即可使用單表常用操作:導包==》繼承==》在啟動類中設置掃描 ==>使用
通過我們?nèi)フ{(diào)用它封裝的各種方法來實現(xiàn)sql語句的效果。對于單表查詢不需要寫SQL語句,這樣就不用像mybatis那樣每次寫一個接口就要寫一條sql語句
特點:
Tkmybatis是基于Mybatis框架開發(fā)的一個工具,通過調(diào)用它提供的方法實現(xiàn)對單表的數(shù)據(jù)操作,不需要寫任何sql語句,這極大地提高了項目開發(fā)效率。
Tkmybatis使用 :
項目結(jié)構(gòu):
1、pom.xml添加依賴
<dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>tk.mybatis</groupId><artifactId>mapper</artifactId><version>3.4.2</version></dependency><!--mapper--><dependency><groupId>tk.mybatis</groupId><artifactId>mapper-spring-boot-starter</artifactId><version>1.1.3</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency> </dependencies>2、創(chuàng)建數(shù)據(jù)庫表對應實體類對象
DROP TABLE IF EXISTS category; CREATE TABLE category (category_id INT PRIMARY KEY,category_name VARCHAR (50) NOT NULL,description VARCHAR (100) );DELETE FROM category; INSERT INTO category (category_id, category_name, description) VALUES(1, 'Beverages', 'test'),(2, 'Condiments', 'test'),(3, 'Oil', 'test'); @Data @Table(name = "category") public class Category {@Id@Column(name = "category_id")private Integer categoryID;private String categoryName;private String description; } 實體類中,使用了以下注解:@Table 描述數(shù)據(jù)庫表信息,主要屬性有name(表名)、schema、catalog、uniqueConstraints等。@Id 指定表主鍵字段,無屬性值。@Column 描述數(shù)據(jù)庫字段信息,主要屬性有name(字段名)、columnDefinition、insertable、length、nullable(是否可為空)、precision、scale、table、unique、updatable等。@ColumnType 描述數(shù)據(jù)庫字段類型,可對一些特殊類型作配置,進行特殊處理,主要屬性有jdbcType、column、typeHandler等。@Transient 標識該屬性不進行數(shù)據(jù)庫持久化操作,無屬性。還有其他相關注解,如@ColumnResult、@JoinColumn、@OrderBy、@Embeddable等,可以做簡單解一下,用的不多。@Data lombok插件用于簡化代碼的注解,無需寫get set 等代碼。3、Mapper數(shù)據(jù)庫操作接口
只需要繼承tk.mybatis.mapper.common.Mapper即可。
4、Tkmybatis數(shù)據(jù)庫操作方法API
增 Mapper.insert(record);保存一個實體,null的屬性也會保存,不會使用數(shù)據(jù)庫默認值Mapper.insertSelective(record);保存一個實體,null的屬性不會保存,會使用數(shù)據(jù)庫默認值刪 Mapper.delete(record);根據(jù)實體屬性作為條件進行刪除,查詢條件使用等號Mapper.deleteByExample(example)根據(jù)Example條件刪除數(shù)據(jù)Mapper.deleteByPrimaryKey(key)根據(jù)主鍵字段進行刪除,方法參數(shù)必須包含完整的主鍵屬性改 Mapper.updateByExample(record, example)根據(jù)Example條件更新實體`record`包含的全部屬性,null值會被更新Mapper.updateByExampleSelective(record, example)根據(jù)Example條件更新實體`record`包含的不是null的屬性值Mapper.updateByPrimaryKey(record)根據(jù)主鍵更新實體全部字段,null值會被更新Mapper.updateByPrimaryKeySelective(record)根據(jù)主鍵更新屬性不為null的值查 Mapper.select(record)根據(jù)實體中的屬性值進行查詢,查詢條件使用等號Mapper.selectAll()查詢?nèi)拷Y(jié)果Mapper.selectByExample(example)根據(jù)Example條件進行查詢Mapper.selectByExampleAndRowBounds(example, rowBounds)根據(jù)example條件和RowBounds進行分頁查詢Mapper.selectByPrimaryKey(key)根據(jù)主鍵字段進行查詢,方法參數(shù)必須包含完整的主鍵屬性,查詢條件使用等號Mapper.selectByRowBounds(record, rowBounds)根據(jù)實體屬性和RowBounds進行分頁查詢Mapper.selectCount(record)根據(jù)實體中的屬性查詢總數(shù),查詢條件使用等號Mapper.selectCountByExample(example)根據(jù)Example條件進行查詢總數(shù)Mapper.selectOne(record)根據(jù)實體中的屬性進行查詢,只能有一個返回值,有多個結(jié)果是拋出異常,查詢條件使用等號Example條件 (自定義查詢條件)
//注意:(addEqualTo)這里的userId是映射的實體類。@Testpublic void selectAllTest2() {Example example = new Example(Category.class);example.createCriteria().andEqualTo("categoryID",1).andEqualTo("categoryName","Beverages");List<Category> categories = categoryDao.selectByExample(example);System.out.println(categories);assertEquals(true, categories.size() > 0);}//注意:(addCondition)這里的user_id是數(shù)據(jù)庫的字段。即where后面的條件。應該寫sql語句。@Testpublic void selectAllTest3() {Example example = new Example(Category.class);example.createCriteria().andCondition("category_id=",1).andCondition("category_name=","Beverages");List<Category> categories = categoryDao.selectByExample(example);System.out.println(categories);assertEquals(true, categories.size() > 0);}Example條件基本涵蓋了常用的sql條件,并且支持使用原生sql語句字符串查詢。
拓展-復雜查詢
方式1:
執(zhí)行的sql為:
SELECT category_id, category_name, description FROM category WHERE (
category_name = ?
OR category_id = ?
OR description = ? ) AND (category_id = ?)
方式2
@Testpublic void testNestConditions2(){Weekend<Category> weekend = new Weekend<>(Category.class);//關鍵字查詢部分String keyword = "key";WeekendCriteria<Category, Object> keywordCriteria = weekend.weekendCriteria();if (!StringUtils.isEmpty(keyword)) {keywordCriteria.orLike(Category::getCategoryName, keyword).orLike(Category::getCategoryID, keyword).orLike(Category::getDescription, keyword);//此處不需要再用下面這一句了,不然上面這個條件組合會重復一次//weekend.and(keywordCriteria)}//部門查詢部分Example example = new Example(Category.class);Example.Criteria criteria = example.createCriteria();criteria.andEqualTo("categoryID", "i222");weekend.and(criteria);List<Category> users = categoryDao.selectByExample(weekend);}其中Weekend是高版本的通用mapper版本才有,而且需要java8語法支持。
執(zhí)行效果如下圖:
總結(jié)下來,就是
每個條件組合(a/b/c) (d)各自創(chuàng)建自己的cirteria,再用and或者or方法去連接
結(jié)語
Tkmybatis極大地提高了我們對單表數(shù)據(jù)庫操作的開發(fā)效率,可以在實際項目開發(fā)中推薦使用。
拓展部分:
源碼的簡單分析,大家可以自己基于這個原理自定義特定的需求
此框架為我們實現(xiàn)這些功能所有的改動都在Mapper層面,所有的Mapper都繼承了tk.mybatis.mapper.common.Mapper
public interface WorkerMapper extends Mapper {}
Mapper接口的聲明如下,可以看到Mapper接口實現(xiàn)了所有常用的方法
看一下完整的UML圖,太大了,可以用新窗口打開,放大之后再看
這里選擇一個接口:SelectOneMapper接口,對于源碼進行簡單分析,此接口聲明如下:
public interface SelectOneMapper<T> {/** * 根據(jù)實體中的屬性進行查詢,只能有一個返回值,有多個結(jié)果是拋出異常,查詢條件使用等號 * * @param record * @return */@SelectProvider(type = BaseSelectProvider.class, method = "dynamicSQL")T selectOne(T record);}@SelectProvider是mybatis3之后提供的,用于靈活的設置sql來源,這里設置了服務提供類和方法,但這個庫并沒有直接用method指定的方法來返回sql,而是在運行時進行解析的,代碼如下
public class BaseSelectProvider extends MapperTemplate {public String selectOne(MappedStatement ms) {Class<?> entityClass = getEntityClass(ms);//修改返回值類型為實體類型setResultType(ms, entityClass);StringBuilder sql = new StringBuilder();sql.append(SqlHelper.selectAllColumns(entityClass));sql.append(SqlHelper.fromTable(entityClass, tableName(entityClass)));sql.append(SqlHelper.whereAllIfColumns(entityClass, isNotEmpty()));return sql.toString();} }到這里我們就大概知道了這個庫為我們提供便利的原理了,總的來說就是這個庫幫我們提供了對表的基本操作的sql,幫我們省了很多工作量,而且維護起來也很方便,否則我們的xml文件動不動就幾百行甚至上千行
對源碼的探索不能到這里停止,最起碼要分析到與另一個框架的整合點
我們知道,mybatis的mapper接口是在啟動的時候被框架以JdkProxy的形式封裝了的,具體對應的類是MapperFactoryBean,這個類中有一個checkDaoConfig()方法,是從父類繼承并重寫了該方法,繼承結(jié)構(gòu)如下
MapperFactoryBean -> SqlSessionDaoSupport -> DaoSupport
這里的DaoSupport就是spring提供的Dao的抽象,代碼如下
框架自定義的MapperFactoryBean重寫了checkDaoConfig()方法,完成對所有sql語句的設置,代碼如下
@Overrideprotected void checkDaoConfig() {super.checkDaoConfig();//通用Mapperif (mapperHelper.isExtendCommonMapper(getObjectType())) {//這里去處理該類所對應的MappedStatement,封裝在helper類中處理mapperHelper.processConfiguration(getSqlSession().getConfiguration(), getObjectType());}}MapperHelper的processConfiguration方法如下
public void processConfiguration(Configuration configuration, Class<?> mapperInterface) {String prefix;if (mapperInterface != null) {prefix = mapperInterface.getCanonicalName();} else {prefix = "";}for (Object object : new ArrayList<Object>(configuration.getMappedStatements())) {if (object instanceof MappedStatement) {MappedStatement ms = (MappedStatement) object;//檢查這個MappedStatement是否屬于此映射對象if (ms.getId().startsWith(prefix) && isMapperMethod(ms.getId())) {if (ms.getSqlSource() instanceof ProviderSqlSource) {//去設置該statement的sql語句setSqlSource(ms);}}}}}設置sql的邏輯,提供了幾種不同類型的sqlsource
到這里整個sql的獲取流程就分析完了。大家可以根據(jù)實際需求拓展。
總結(jié)
以上是生活随笔為你收集整理的Tkmybatis快速入手的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WinForm计时器
- 下一篇: yum和rdm命令