MybatisPlus學(xué)習(xí)筆記

一、MybatisPlus簡(jiǎn)介

1.1.簡(jiǎn)介

Mybatis-Plus(簡(jiǎn)稱MP)是一個(gè) Mybatis 的增強(qiáng)工具,在 Mybatis 的基礎(chǔ)上只做增強(qiáng)不做改變,為簡(jiǎn)化開發(fā)、提高效率而生。

1.2.文檔地址

官網(wǎng)文檔地址

1.3.MybatisPlus的特性

  • 無(wú)侵入:Mybatis-Plus 在 Mybatis 的基礎(chǔ)上進(jìn)行擴(kuò)展,只做增強(qiáng)不做改變,引入 Mybatis-Plus 不會(huì)對(duì)您現(xiàn)有的 Mybatis 構(gòu)架產(chǎn)生任何影響,而且 MP 支持所有 Mybatis 原生的特性
  • 依賴少:僅僅依賴 Mybatis 以及 Mybatis-Spring
  • 損耗小啟動(dòng)即會(huì)自動(dòng)注入基本 CURD,性能基本無(wú)損耗,直接面向?qū)ο蟛僮?/code>
  • 預(yù)防Sql注入:內(nèi)置 Sql 注入剝離器,有效預(yù)防Sql注入攻擊
  • 通用CRUD操作內(nèi)置通用 Mapper、通用 Service,僅僅通過(guò)少量配置即可實(shí)現(xiàn)單表大部分 CRUD 操作,更有強(qiáng)大的條件構(gòu)造器,滿足各類使用需求
  • 多種主鍵策略:支持多達(dá)4種主鍵策略(內(nèi)含分布式唯一ID生成器),可自由配置,完美解決主鍵問題
  • 支持熱加載:Mapper 對(duì)應(yīng)的 XML 支持熱加載,對(duì)于簡(jiǎn)單的 CRUD 操作,甚至可以無(wú) XML 啟動(dòng)
  • 支持ActiveRecord:支持 ActiveRecord 形式調(diào)用,實(shí)體類只需繼承 Model 類即可實(shí)現(xiàn)基本 CRUD 操作
  • 支持代碼生成:采用代碼或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 層代碼,支持模板引擎,更有超多自定義配置等您來(lái)使用(P.S. 比 Mybatis 官方的 Generator 更加強(qiáng)大?。?/li>
  • 支持自定義全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 支持關(guān)鍵詞自動(dòng)轉(zhuǎn)義:支持?jǐn)?shù)據(jù)庫(kù)關(guān)鍵詞(order、key......)自動(dòng)轉(zhuǎn)義,還可自定義關(guān)鍵詞
  • 內(nèi)置分頁(yè)插件:基于 Mybatis 物理分頁(yè),開發(fā)者無(wú)需關(guān)心具體操作,配置好插件之后,寫分頁(yè)等同于普通List查詢
  • 內(nèi)置性能分析插件可輸出 Sql 語(yǔ)句以及其執(zhí)行時(shí)間,建議開發(fā)測(cè)試時(shí)啟用該功能,能有效解決慢查詢
  • 內(nèi)置全局?jǐn)r截插件:提供全表 delete 、 update 操作智能分析阻斷,預(yù)防誤操作

二、集成MybatisPlus

2.1.Maven導(dǎo)入MybatisPlus依賴

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus</artifactId>
    <version>3.0-gamma</version>
</dependency>

2.2.修改sqpsessionFactoryBean

<!--  配置SqlSessionFactoryBean 
  Mybatis提供的: org.mybatis.spring.SqlSessionFactoryBean
  MP提供的:com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean
  -->
<!-- 配置sqlsessionFactoryBean -->
<bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
    <!-- 數(shù)據(jù)源 -->
    <property name="dataSource" ref="dataSource"></property>
    <property name="configLocation" value="classpath:mybatis-config.xml"></property> 
    <!-- 別名處理 -->
    <property name="typeAliasesPackage" value="com.luo.beans"></property>
</bean>

三、入門的Hello World

3.1.準(zhǔn)備數(shù)據(jù)表

DROP TABLE IF EXISTS `tbl_user`;
CREATE TABLE `tbl_user` (
  `email` varchar(50) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `gender` char(255) DEFAULT NULL,
  `user_name` varchar(255) DEFAULT NULL,
  `id` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

INSERT INTO `tbl_user` VALUES ('243518985@qq.com', 24, '1', '羅康元 ', 1);
INSERT INTO `tbl_user` VALUES ('1835856@qq.com', 34, '2', '張三', 2);
INSERT INTO `tbl_user` VALUES ('323134435@163.com', 53, '1', '李四', 3);
INSERT INTO `tbl_user` VALUES ('345464566@qq.com', 43, '1', '王五', 4);
INSERT INTO `tbl_user` VALUES ('luokangyuansb@gmail.com', 45, '1', '趙六', 5);

3.2.準(zhǔn)備Java實(shí)體類

public class User {
    
    private Integer id;
    
    private String userName;
    
    private String email;
    
    private Integer gender;
    
    private Integer age;
}

3.3.加入依賴的jar包

<dependencies>
    <!-- mp依賴:mybatisPlus 會(huì)自動(dòng)的維護(hù)Mybatis 以及MyBatis-spring相關(guān)的依賴-->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus</artifactId>
        <version>2.3</version>
    </dependency>
    <!--junit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.9</version>
    </dependency>
    <!-- log4j -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    <!-- c3p0 -->
    <dependency>
        <groupId>com.mchange</groupId>
        <artifactId>c3p0</artifactId>
        <version>0.9.5.2</version>
    </dependency>
    <!-- mysql -->
    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.11</version>
    </dependency>
    <!-- spring -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.3.10.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>4.3.10.RELEASE</version>
    </dependency>
</dependencies>

3.5.mybatis-config.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

</configuration>

3.6.log4j.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
 
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
 
 <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
   <param name="Encoding" value="UTF-8" />
   <layout class="org.apache.log4j.PatternLayout">
    <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m  (%F:%L) \n" />
   </layout>
 </appender>
 <logger name="java.sql">
   <level value="debug" />
 </logger>
 <logger name="org.apache.ibatis">
   <level value="info" />
 </logger>
 <root>
   <level value="debug" />
   <appender-ref ref="STDOUT" />
 </root>
</log4j:configuration>

3.7.db.properties文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Hongkong
jdbc.username=root
jdbc.password=jiamei@20141107.

3.8.applicationContext.xml文件

<!-- 數(shù)據(jù)源 -->
<context:property-placeholder location="classpath:db.properties" />
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="${jdbc.driver}"></property>
    <property name="jdbcUrl" value="${jdbc.url}"></property>
    <property name="user" value="${jdbc.username}"></property>
    <property name="password" value="${jdbc.password}"></property>
</bean>
<!--事務(wù)管理器  -->
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>
<!--基于注解的事務(wù)管理  -->
<tx:annotation-driven transaction-manager="dataSourceTransactionManager" />
<!--  配置SqlSessionFactoryBean 
  Mybatis提供的: org.mybatis.spring.SqlSessionFactoryBean
  MP提供的:com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean
  -->
<!-- 配置sqlsessionFactoryBean -->
<bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
    <!-- 數(shù)據(jù)源 -->
    <property name="dataSource" ref="dataSource"></property>
    <property name="configLocation" value="classpath:mybatis-config.xml"></property> 
    <!-- 別名處理 -->
    <property name="typeAliasesPackage" value="com.luo.beans"></property>
</bean>
<!--  配置mybatis掃描的mapper接口路徑-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.luo.mapper"></property>
</bean>

3.9.通用的CRUD操作

假設(shè)我們有一張user表,我們需要對(duì)這個(gè)表進(jìn)行增刪改查操作,如果說(shuō)沒有代碼生成的話,在mybatis我們需要編寫UserMapper接口,手寫CRUD方法,在UserMapper.xml文件中寫對(duì)應(yīng)的sql語(yǔ)句,但是,在MybatisPlus中,我們只需要?jiǎng)?chuàng)建UserMapper接口,繼承BaseMapper接口,就可以完成CRUD操作,甚至不需要?jiǎng)?chuàng)建SQl映射文件。

public interface UserMapper extends BaseMapper<User>{

}

然后,我們就寫一些基本的單元測(cè)試方法,測(cè)試我們的CRUD,來(lái)到我們的測(cè)試類中,如下:

public class TestMp {

    private ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");

    private UserMapper userMapper = ioc.getBean("userMapper",UserMapper.class);
}

說(shuō)明:在測(cè)試類中我們將使用從SpringIOC容器中獲取的userMapper進(jìn)行CRUD一系列操作

保存一條數(shù)據(jù)userMapper.insert(user);

@Test
public void insert(){
    User user = new User();
    user.setUserName("luokangyuan");
    user.setAge(66);
    user.setEmail("2356775645@qq.com");
    user.setGender(2);
    Integer result = userMapper.insert(user);
    System.out.println(result);
    // 直接獲取插入數(shù)據(jù)返回的自增主鍵值
    System.out.println(user.getId()+"======");
}

插入數(shù)據(jù)的方法有兩個(gè):insert和insertAllColumn,二者的執(zhí)行結(jié)果是一樣的,區(qū)別在于,前者會(huì)根據(jù)實(shí)體類的每一個(gè)屬性值進(jìn)行一個(gè)非空校驗(yàn),在插入的sql語(yǔ)句中不會(huì)出現(xiàn)實(shí)體類屬性為空的字段;

注意:在沒有使用全局配置之前,我們需要指定實(shí)體類對(duì)應(yīng)的數(shù)據(jù)庫(kù)表和主鍵生成策略

  • 主鍵生成策略:@TableId(type = IdType.AUTO,value = "id"),value屬性值當(dāng)實(shí)體類字段名和數(shù)據(jù)庫(kù)一致時(shí)可以不寫,這里的value指的是數(shù)據(jù)庫(kù)字段名稱,type的類型有以下幾種:
    • IdType.AUTO:數(shù)據(jù)庫(kù)ID自增
    • IdType.INPUT:用戶輸入ID
    • IdType.ID_WORKER:全局唯一ID,內(nèi)容為空自動(dòng)填充(默認(rèn)配置)
    • IdType.UUID:全局唯一ID,內(nèi)容為空自動(dòng)填充
  • 實(shí)體對(duì)應(yīng)表名注解:@TableName(value = "tbl_user");指定當(dāng)前實(shí)體類對(duì)應(yīng)的數(shù)據(jù)庫(kù)表
  • 數(shù)據(jù)庫(kù)字段映射名稱:@TableField(value = "user_name"),當(dāng)禁止駝峰映射規(guī)則后可以使用
  • 忽略插入到表的字段:@ableField(exist = false),如下,數(shù)據(jù)庫(kù)沒有money這個(gè)字段,如果不忽略,那么插入就會(huì)報(bào)錯(cuò),找不到這個(gè)字段;
@TableField(exist = false)
private Double money;

更新一條數(shù)據(jù)

@Test
public void update(){
    User user = new User();
    user.setId(7);
    user.setUserName("王八");
    user.setAge(56);
    //user.setEmail("2356775645@qq.com");
    user.setGender(2);
    Integer result = userMapper.updateById(user);
}

同理:更新方法也有兩個(gè)updateById和updateAllColumnById,前者會(huì)對(duì)實(shí)體類屬性名進(jìn)行非空校驗(yàn),為空的就不會(huì)出現(xiàn)在sql語(yǔ)句中,也就是不會(huì)更新原有數(shù)據(jù),后者是會(huì)更新所有列,如果實(shí)體類屬性值為空,則數(shù)據(jù)庫(kù)對(duì)應(yīng)字段名更新為null;

查詢一條數(shù)據(jù)

@Test
public void select(){
    // 1.通過(guò)ID查詢一條數(shù)據(jù)
    User user = userMapper.selectById(7);
    // 2.通過(guò)多個(gè)列進(jìn)行查詢,如果查處的數(shù)據(jù)有多條就會(huì)報(bào)錯(cuò)
    User u = new User();
    u.setId(2);
    u.setUserName("張三");
    User user1 = userMapper.selectOne(u);
    // 3.查詢符合多個(gè)ID的數(shù)據(jù),使用的是in關(guān)鍵字查詢
    List<Integer> ids = new ArrayList<Integer>();
    ids.add(3);
    ids.add(4);
    ids.add(5);
    List<User> users = userMapper.selectBatchIds(ids);
    // 4.通過(guò)封裝map條件,注意的是封裝的是列字段名,不是實(shí)體里屬性名,
    // map中的key充當(dāng)sql中的條件名稱
    Map<String,Object> maps = new HashMap<String, Object>();
    maps.put("user_name","張三");
    maps.put("age",347);
    List<User> users1 = userMapper.selectByMap(maps);
    // 5.分頁(yè)查詢方法,查看第二頁(yè),每頁(yè)2條數(shù)據(jù),在sql語(yǔ)句并沒有l(wèi)imit關(guān)鍵字
    // 所以要實(shí)現(xiàn)物理分頁(yè),還需借助插件,例如mybatis的pageHepler或者M(jìn)ybatisPlus提供的分頁(yè)插件
    List<User> users2 = userMapper.selectPage(new Page<User>(2, 2), null);
}

刪除一條數(shù)據(jù)

@Test
public void delete(){
    // 1.根據(jù)ID刪除
    Integer integer = userMapper.deleteById(8);
    // 2.根據(jù)條件刪除,map中的key為列名,千萬(wàn)注意
    Map<String ,Object> maps = new HashMap<String, Object>();
    maps.put("age",66);
    maps.put("gender",2);
    Integer integer1 = userMapper.deleteByMap(maps);
    // 3.根據(jù)ID批量刪除,使用in關(guān)鍵字
    List<Integer> ids = new ArrayList<Integer>();
    ids.add(5);
    ids.add(7);
    Integer integer2 = userMapper.deleteBatchIds(ids);
}

3.10.MybatisPlus全局配置

在前面的CRUD操作中,我們會(huì)使用直接注解指定主鍵生成策略和表名到實(shí)體類的映射,但是配置的僅僅會(huì)對(duì)當(dāng)前實(shí)體類起作用,所以,引入了全局配置,如下:

<!-- 定義MybatisPlus的全局策略配置-->
<bean id ="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
    <!--映射數(shù)據(jù)庫(kù)下劃線字段名到數(shù)據(jù)庫(kù)實(shí)體類的駝峰命名的映射-->
    <property name="dbColumnUnderline" value="true"></property>
    <!-- 全局的主鍵策略 -->
    <property name="idType" value="0"></property>
    <!-- 全局的表前綴策略配置 -->
    <property name="tablePrefix" value="tbl_"></property>
</bean>

然后,將MybatisPlus全局配置注入到sqlSessionFactoryBean中

<!-- 注入全局MP策略配置 -->
<property name="globalConfig" ref="globalConfiguration"></property>

3.11.mybatisPlusCRUD總結(jié)

在前面,我們實(shí)現(xiàn)了基本的CRUD操作,操作簡(jiǎn)單,僅僅只需繼承一個(gè)BaseMapper就可以完成,實(shí)現(xiàn)單一,批量,分頁(yè)等等一系列操作,很大的減少了開發(fā)負(fù)擔(dān),但這僅僅是Mybatisplus的冰山一角,當(dāng)我們需要多條件查詢的時(shí)候,就會(huì)使用到MybatisPlus中強(qiáng)大的條件構(gòu)造器EntityWrapper;

四、條件查詢

條件構(gòu)造器就是EntityWrapper,就是一個(gè)封裝查詢條件對(duì)象,讓開發(fā)者自由的定義查詢條件,主要用于sql的拼接,排序或者實(shí)體參數(shù)等;條件構(gòu)造器

注意:使用的參數(shù)是數(shù)據(jù)庫(kù)字段名稱,不是Java類屬性名

4.1.selectPage中的條件查詢

@Test
public void entityWrapperTedst(){
    // 分頁(yè)查詢第一頁(yè),每頁(yè)2條記錄,年齡在41-53之間,genger為1,user_name為王五的用戶
    List<User> users = userMapper.selectPage(new Page<User>(1, 2),
         new EntityWrapper<User>()
         .between("age", 41, 53)
         .eq("gender",1)
         .eq("user_name","王五")
    );

}

4.2.模糊查詢和或查詢

@Test
public void selectListTest(){
    List<User> users = userMapper.selectList(new EntityWrapper<User>()
          .eq("gender", 1)
          .like("user_name", "三")
          .orNew()
          .like("email", "5")
    );
}

使用或條件查詢可以使用or()也可以使用orNew(),二者的區(qū)別在于sql中的條件部分不一樣,如下:

使用or()的sql語(yǔ)句

SELECT id AS id,user_name AS userName,email,gender,age FROM tbl_user WHERE (gender = ? AND user_name LIKE ? OR email LIKE ?)

使用orNew()的sql語(yǔ)句

SELECT id AS id,user_name AS userName,email,gender,age FROM tbl_user WHERE (gender = ? AND user_name LIKE ?) OR (email LIKE ?)

4.3.修改滿足條件的數(shù)據(jù)

@Test
public void updataByEntityWrapper(){
    User user = new User();
    user.setEmail("luokangyuan@sina,com");
    user.setAge(24);
    user.setUserName("四川麻醬");
    Integer update = userMapper.update(user, new EntityWrapper<User>()
       .eq("user_name","李四")
       .eq("age",53)
       );
}

4.4.刪除滿足條件的數(shù)據(jù)

@Test
public void deleteByEntityWrapper(){
    userMapper.delete(new EntityWrapper<User>()
      .eq("user_name","王八")
      .eq("age",56)
    );
}

4.5.條件查詢之Condition

Condition繼承了Wrapper類,另外,我們不需要再new一個(gè)Condition對(duì)象,直接調(diào)用condition類的靜態(tài)方法create就可以得到一個(gè)condition對(duì)象,然后使用wrapper的所有方法,簡(jiǎn)單使用如下:

@Test
public void testCondition(){
    userMapper.selectPage(new Page<User>(1,2), Condition.create()
     .between("age",45,56)
   );
}

五、活動(dòng)記錄AR

Active Record(活動(dòng)記錄),簡(jiǎn)稱AR,是一種領(lǐng)域模型模式,特點(diǎn)就是一個(gè)模型類對(duì)應(yīng)關(guān)系型數(shù)據(jù)庫(kù)中的一個(gè)表,而模型類的一個(gè)實(shí)例對(duì)應(yīng)表中的一條記錄;

5.1.開啟AR模式

開啟AR模式的方法很簡(jiǎn)單,就是讓我們的實(shí)體類繼承Model類,并實(shí)現(xiàn)其抽象方法,指定主鍵即可,如下

public class User extends Model<User> {

    @Override
    protected Serializable pkVal() {
        return id;
    }
}

5.2.插入一條數(shù)據(jù)

@Test
public void insert(){
    User user = new User();
    user.setUserName("杉木");
    user.setAge(25);
    user.setEmail("shancnu@163.com");
    user.setGender(1);
    boolean rs = user.insert();
}

5.3.修改一條數(shù)據(jù)

@Test
public void update(){
    User user = new User();
    user.setUserName("杉木博客");
    user.setAge(35);
    user.setId(10);
    boolean rs = user.updateById();
}

說(shuō)明:和通用的CRUD中的更新方法一樣,updateAllColumnById()會(huì)更新所有列

5.4.查詢數(shù)據(jù)

@Test
public void select(){
    User user = new User();
    user.setId(2);
    // 根據(jù)ID查詢一條數(shù)據(jù)
    User user1 = user.selectById();
    // 查詢所有的數(shù)據(jù)
    List<User> users = user.selectAll();
    // 根據(jù)條件查詢
    List<User> usersList = user.selectList(new EntityWrapper<User>()
           .like("user_name", "三"));
    // 統(tǒng)計(jì)滿足條件的數(shù)據(jù)數(shù)量
    int gender = user.selectCount(new EntityWrapper<User>().eq("gender", 1));
    // 統(tǒng)計(jì)全表數(shù)量
    int count = user.selectCount(null);
}

5.5.刪除一條數(shù)據(jù)

@Test
public void delete(){
    User user = new User();
    user.setId(7);
    boolean rs = user.deleteById();
    System.out.print(rs);
}

當(dāng)然,也可以根據(jù)條件刪除多條數(shù)據(jù),這里需要注意的是:當(dāng)刪除不存在的數(shù)據(jù)時(shí)候,返回的結(jié)果也是true;

// 刪除不存在邏輯屬于成功
public static boolean delBool(Integer result) {
    return null != result && result >= 0;
}

5.6.分頁(yè)查詢數(shù)據(jù)

在前面的CRUD中的分頁(yè)查詢返回的是list數(shù)據(jù)集合,但是在AR中返回的卻是Page對(duì)象,如下

@Test
public void selectPage(){
    User user = new User();
    Page<User> userPage = user.selectPage(new Page<User>(1, 2),
          new EntityWrapper<User>().like("user_name", "三"));
    List<User> records = userPage.getRecords();
}

5.7.AR總結(jié)

AR提供的是一種更為快速的實(shí)現(xiàn)CRUD操作,本質(zhì)很是調(diào)用Mybatis對(duì)應(yīng)的方法,說(shuō)的簡(jiǎn)單一點(diǎn)就是語(yǔ)法糖;

糖雖然好吃,但是,不要管不住嘴;

六、代碼生成器

我們知道m(xù)ybatis有一個(gè)代碼生成器MBG,可以生成Java實(shí)體類mapper接口和映射文件,但是MybatisPlus卻更加強(qiáng)大,可以生成service和controller,可以配置實(shí)體類是否支持AR等,代碼生成器

說(shuō)明:建議數(shù)據(jù)庫(kù)表名和字段名采用駝峰命名方式,和實(shí)體來(lái)一致,可以避免在對(duì)應(yīng)實(shí)體類產(chǎn)生的性能損耗

6.1.導(dǎo)入依賴

<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.0</version>
</dependency>

說(shuō)明:MybatisPlus默認(rèn)使用的是velocity模版引

6.2.編寫配置類

@Test
public void testMbg(){

    // 1.全局配置
    GlobalConfig globalConfig = new GlobalConfig();
    globalConfig.setActiveRecord(true)// 是否開啟AR模式
        .setAuthor("luokangyuan") // 指定作者
        .setOutputDir("/Users/luokangyuan/Documents/project/mybatisdemo/src/main/java")
        .setFileOverride(true) // 指定文件覆蓋
        .setIdType(IdType.AUTO) // 設(shè)置主鍵自增策略
        .setServiceImplName("%sService") // 設(shè)置生成的services接口的名字的首字母是否為I
        .setBaseResultMap(true) // 基本的字段映射
        .setBaseColumnList(true); // 基本的sql片段
    // 2.配置數(shù)據(jù)源
    DataSourceConfig dataSourceConfig = new DataSourceConfig();
    dataSourceConfig.setDbType(DbType.MYSQL) // 設(shè)置數(shù)據(jù)庫(kù)類型
        .setDriverName("com.mysql.jdbc.Driver")
        .setUrl("jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Hongkong")
        .setUsername("root")
        .setPassword("jiamei@20141107.");
    // 3.策略配置
    StrategyConfig strategyConfig = new StrategyConfig();
    strategyConfig.setCapitalMode(true) //全局大寫命名
        .setDbColumnUnderline(true) // 指定表名和字段名是否使用了下劃線
        .setNaming(NamingStrategy.underline_to_camel) // 數(shù)據(jù)庫(kù)字段下劃線轉(zhuǎn)駝峰命令策略
        .setTablePrefix("tbl_") // 設(shè)置表前綴
        .setInclude("tbl_dept","tbl_file"); // 設(shè)置需要生成的表
    // 4.包名策略配置
    PackageConfig packageConfig = new PackageConfig();
    packageConfig.setParent("com.luo") // 設(shè)置父包
        .setMapper("mapper")
        .setService("service")
        .setController("controller")
        .setEntity("beans")
        .setXml("mapper");
    // 5. 開始生成代碼
    AutoGenerator autoGenerator = new AutoGenerator();
    autoGenerator.setGlobalConfig(globalConfig)
        .setDataSource(dataSourceConfig)
        .setStrategy(strategyConfig)
        .setPackageInfo(packageConfig);
    autoGenerator.execute();
}

6.3.生成的service代碼查看

@Service
public class DeptService extends ServiceImpl<DeptMapper, Dept> implements IDeptService {

}

DeptService繼承了ServiceImpl,在ServiceImpl中就已經(jīng)注入了DeptMapper,所以,我們就不需要再次注入,在ServiceImpl中也幫我們提供了常用的CRUD方法,我們可以直接使用,

@Controller
@RequestMapping("/dept")
public class DeptController {
    @Autowired
    private IDeptService service;

    public String select(){
        service.selectList(null);
        return null;
    }
}

七、插件擴(kuò)展

7.1.注冊(cè)分頁(yè)插件

<bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
    <!-- 數(shù)據(jù)源 -->
    <property name="dataSource" ref="dataSource"></property>
    <property name="configLocation" value="classpath:mybatis-config.xml"></property>
    <!-- 別名處理 -->
    <property name="typeAliasesPackage" value="com.luo.beans"></property>
    <!-- 注入全局MP策略配置 -->
    <property name="globalConfig" ref="globalConfiguration"></property>
    <property name="plugins">
        <list>
            <bean class="com.baomidou.mybatisplus.plugins.PaginationInterceptor"></bean>
        </list>
    </property>
</bean>

真正的分頁(yè)查詢

ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");

private UserMapper userMapper = ioc.getBean("userMapper",UserMapper.class);

@Test
public void testPage(){
    Page<User> page = new Page<User>(1,4);
    List<User> users = userMapper.selectPage(page,null);
    page.setRecords(users);
    System.out.print("總記錄數(shù)"+page.getTotal());
    System.out.print("當(dāng)前頁(yè)碼"+page.getCurrent());
    System.out.print("總頁(yè)碼"+page.getPages());
    System.out.print("每頁(yè)記錄數(shù)"+page.getSize());
    System.out.print("是否有前一頁(yè)"+page.hasPrevious());
    System.out.print("是否有后一頁(yè)"+page.hasNext());
}

說(shuō)明:我們可以將分頁(yè)查詢的數(shù)據(jù)放在page對(duì)象中,返回前端一個(gè)page對(duì)象即可

7.2.執(zhí)行分析插件

<bean class="com.baomidou.mybatisplus.plugins.SqlExplainInterceptor">
    <property name="stopProceed" value="true"></property>
</bean>

測(cè)試如下:

@Test
public void testDeltetAll(){
    userMapper.delete(null);
}

sql分析插件只支持mysql5.6.3以上的版本,本質(zhì)就是通過(guò)sql分析命令Explain分析當(dāng)前的sql語(yǔ)句,根據(jù)結(jié)果集中的Extra列來(lái)斷定當(dāng)前是否全表操作;

7.3.性能分析插件

性能分析插件用于輸出每秒sql語(yǔ)句和其執(zhí)行時(shí)間,首先注冊(cè)插件,如下:

<bean class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor">
    <property name="format" value="true"></property>
</bean>

測(cè)試如下:

@Test
public  void testPer(){
    Dept dept = new Dept();
    dept.setDeptName("開發(fā)部");
    dept.setDeptCount("34");
    dept.setDeptBegintime(new Date());
    dept.insert();
}

結(jié)果如下:

 Time:142 ms - ID:com.luo.mapper.DeptMapper.insert
 Execute SQL:
    INSERT 
    INTO
        tbl_dept
        ( dept_count, dept_name, dept_beginTime ) 
    VALUES
        ( '34', '開發(fā)部', '2018-08-26 23:09:17.293' )]

7.4.樂觀鎖插件

當(dāng)我們?cè)陂_發(fā)中,有時(shí)需要判斷,當(dāng)我們更新一條數(shù)據(jù)庫(kù)記錄時(shí),希望這條記錄沒有被別人更新,這個(gè)時(shí)候就可以使用樂觀鎖插件,他的原理就是,取出記錄時(shí),獲取當(dāng)前的version,更新的時(shí)候帶上這個(gè)version,執(zhí)行更新的時(shí)候set version = yourVersion+1 where version = yourVersion,如果version不對(duì),則更新失敗,注意的是:@version用于注解實(shí)體字段,必須要有;

首先,注冊(cè)插件

<bean class="com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor"></bean>

實(shí)體類添加對(duì)應(yīng)屬性,同時(shí)數(shù)據(jù)庫(kù)表也要添加對(duì)應(yīng)字段

@Version
private Integer version;

測(cè)試如下:

@Test
public void testVersion(){
    Dept dept = new Dept();
    dept.setDeptName("測(cè)試部");
    dept.setVersion(1);
    dept.setId(1);
    dept.updateById();
}

如果:這個(gè)時(shí)候?qū)?shù)據(jù)庫(kù)version改為2,在執(zhí)行更新就會(huì)顯示更新記錄數(shù)為0;

八、自定義全局操作

8.1.自定義全局實(shí)例

自定義全局操作,就是將我們需要的sql在項(xiàng)目啟動(dòng)的時(shí)候就注入到全局中,操作步驟如下:

  • 在Mapper接口中定義我們需要注入的方法;
  • 擴(kuò)展AutoSqlInjector中的inject方法,實(shí)現(xiàn)Mapper中我們自定義方法要注入的sql;
  • 最后,在全局配置中,配置我們自定義的注入器即可;

第一步:mapper中定義方法

public interface UserMapper extends BaseMapper<User> {
    
    int deleteAll();
}

第二步:重寫inject方法

public class MySqlInjector  extends AutoSqlInjector {

    @Override
    public void inject(Configuration configuration, MapperBuilderAssistant builderAssistant, Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
        // 構(gòu)造sql語(yǔ)句
        String sql = "delete from " + table.getTableName();
        // 構(gòu)造方法名
        String method = "deleteAll";
        // 構(gòu)造SqlSource對(duì)象
        SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
        // 構(gòu)造一個(gè)刪除的MapperStatement
        this.addDeleteMappedStatement(mapperClass,method,sqlSource);
    }
}?

第三步:注入自定義配置

<bean id ="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
     <!--映射數(shù)據(jù)庫(kù)下劃線字段名到數(shù)據(jù)庫(kù)實(shí)體類的駝峰命名的映射-->
     <property name="dbColumnUnderline" value="true"></property>
     <!-- 全局的主鍵策略 -->
     <property name="idType" value="0"></property>
     <!-- 全局的表前綴策略配置 -->
     <property name="tablePrefix" value="tbl_"></property>
     <!--注入自定義全局操作-->
     <property name="sqlInjector" ref="mySqlInjector"></property>
</bean>
<bean class="com.luo.injector.MySqlInjector" id="mySqlInjector"></bean>

測(cè)試

ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");

private UserMapper userMapper = ioc.getBean("userMapper",UserMapper.class);

@Test
public void testInject(){
    int rs = userMapper.deleteAll();
}

8.2.邏輯刪除

所謂邏輯刪除,就是不真正的刪除數(shù)據(jù)的記錄,而是變?yōu)闊o(wú)效狀態(tài),在MybatisPlus中,給我們提供logicSqlInjector

第一步:數(shù)據(jù)庫(kù)添加邏輯字段

第二步:實(shí)體類添加對(duì)應(yīng)屬性和注解

@TableLogic
private Integer logicFlag;

第三步:MybatisPlus全局配置中加入logicSqlInjector

<bean id ="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
    <!--映射數(shù)據(jù)庫(kù)下劃線字段名到數(shù)據(jù)庫(kù)實(shí)體類的駝峰命名的映射-->
    <property name="dbColumnUnderline" value="true"></property>
    <!-- 全局的主鍵策略 -->
    <property name="idType" value="0"></property>
    <!-- 全局的表前綴策略配置 -->
    <property name="tablePrefix" value="tbl_"></property>
    <!--注入自定義全局操作-->
    <property ref="logicSqlInjector" name="sqlInjector"></property>
    <!--注入邏輯刪除全局值-->
    <property name="logicDeleteValue" value="-1"></property>
    <property name="logicNotDeleteValue" value="1"></property>
</bean>
<!--邏輯刪除-->
<bean class="com.baomidou.mybatisplus.mapper.LogicSqlInjector" id="logicSqlInjector"></bean>

測(cè)試

@Test
public void testLogin(){
    Integer integer = userMapper.deleteById(1);
}

說(shuō)明:我們做的是刪除操作,但是,執(zhí)行的卻是update操作,同時(shí),查詢的時(shí)候自動(dòng)添加了有效判斷

九、公共字段填充

這里涉及到一個(gè)元數(shù)據(jù)處理接口MetaObjectHandler,元對(duì)象是Mybatis提供的一個(gè)用于更加方便,更加優(yōu)雅的訪問對(duì)象的屬性,給對(duì)象的屬性賦值的一個(gè)對(duì)象,本質(zhì)上metaObject獲取對(duì)象的值或者是給對(duì)象的屬性賦值,都是通過(guò)反射獲取到屬性對(duì)應(yīng)方法的Invoker;

9.1.使用實(shí)例

第一步:注解需要填充的字段

@TableField(value = "user_name",fill = FieldFill.INSERT_UPDATE)
private String userName;

第二步:自定義填充處理器

public class MetaHandler extends MetaObjectHandler {
    /**
     * 插入操作:自動(dòng)填充
     * @param metaObject
     */
    public void insertFill(MetaObject metaObject) {
        // 獲取到需要被填充的字段值
        Object userName = getFieldValByName("userName", metaObject);
        if(userName == null){
            setFieldValByName("userName","四川碼醬",metaObject);
        }
    }

    /**
     * 更新操作:自動(dòng)填充
     * @param metaObject
     */
    public void updateFill(MetaObject metaObject) {
        // 獲取到需要被填充的字段值
        Object userName = getFieldValByName("userName", metaObject);
        if(userName == null){
            setFieldValByName("userName","康哥哥",metaObject);
        }
    }
}

第三步:注入全局配置

<bean id ="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
    <!--映射數(shù)據(jù)庫(kù)下劃線字段名到數(shù)據(jù)庫(kù)實(shí)體類的駝峰命名的映射-->
    <property name="dbColumnUnderline" value="true"></property>
    <!-- 全局的主鍵策略 -->
    <property name="idType" value="0"></property>
    <!-- 全局的表前綴策略配置 -->
    <property name="tablePrefix" value="tbl_"></property>
    <!--注入自定義全局操作-->
    <!--<property name="sqlInjector" ref="mySqlInjector"></property>-->
    <property ref="logicSqlInjector" name="sqlInjector"></property>
    <!--注入邏輯刪除全局值-->
    <property name="logicDeleteValue" value="-1"></property>
    <property name="logicNotDeleteValue" value="1"></property>
    <!--注入公共字段填充處理器-->
    <property name="metaObjectHandler" ref="metaHandler"></property>
</bean>
<!--自定義公共字段填充處理器-->
<bean class="com.luo.bandler.MetaHandler" id="metaHandler"></bean>

第四步:測(cè)試

@Test
public void testCom(){
    User user = new User();
    user.setId(11);
    user.setLogicFlag(1);
    user.updateById();
}

十、IEDA開發(fā)插件

10.1.安裝方法

打開IDEA設(shè)置--Plugins--Browse repositories --搜索mybatisx,安裝即可

10.2.支持的功能

根據(jù)mapper接口方法自動(dòng)生成xml文件,接口方法定位xml,xml自動(dòng)定位mapper接口;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 關(guān)于Mongodb的全面總結(jié) MongoDB的內(nèi)部構(gòu)造《MongoDB The Definitive Guide》...
    中v中閱讀 32,328評(píng)論 2 89
  • 1. 簡(jiǎn)介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存儲(chǔ)過(guò)程以及高級(jí)映射的優(yōu)秀的...
    笨鳥慢飛閱讀 6,283評(píng)論 0 4
  • 1、索引的本質(zhì) MySQL官方對(duì)索引的定義為:索引(Index)是幫助MySQL高效獲取數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)。提取句子主...
    北山學(xué)者閱讀 407評(píng)論 0 1
  • 可能是消息沒提醒 可能是你在忙事情 可能你看了不想回 總之 你回復(fù)我的速度 特別慢 特別地慢 我總疑心我手機(jī)的網(wǎng)絡(luò)...
    喜歡吹泡泡閱讀 198評(píng)論 0 0
  • 饞喵之蔥油拌面 材料:手搟面,洋蔥、大蔥、小香蔥,生抽、老抽、糖少許。 1、洋蔥切塊,大蔥切段改絲。小香蔥分蔥白,...
    蟲蟲菲閱讀 297評(píng)論 1 1

友情鏈接更多精彩內(nèi)容