MyBatis-Plus-入门操作(1)

2023-10-30

MyBatis-Plus-入门操作

2.1常见注解

约定大于配置

mp扫描实体类基于反射的方式作为数据库表的信息。

默认的约定

  • 类名驼峰转下划线
  • 名字为id的是主键
  • 属性名进行驼峰转换成下划线

要是不遵循约定的话就需要对应的注解进行修改。

表的名字和 实际的表的名字是不一致的

@TableName(value ="user",schema = "mp")
  • schema数据库
  • value 表名

mp的主键

默认是不支持多个主键的

 @TableId(type = IdType.AUTO)
  • TableId指定的是主键
  • type指定的主键的生成的策略

默认的是:ASSIGN_ID

AUTO 自增

NONE 无

INOUT:手动编码的方式

ASSIGN_ID:自动分配。采用的是雪花的算法和INOUT是类似的。没生成一个是自动生成的。Long类型的整数的形式

ASSIGN_UUID:分配UUID。这个是随机生成的非常长。 字母和数字混合的

字段不一致

尤其是针对JavaBean的属性是以isXxxx开头的,当进行反射的时候就会自动的去掉前面的is,会导致映射是失败的。此时就需要用到下面的注解进行标注。

当出现关键字和数据库中关键字是冲突的时候也是需要采用对应的TableField注解进行标注的但是需要单独加上``

@TableField("is_Del")
private Boolean isDel;

当出现数据库中的关键字的时候

TableField("`order`")
private Integer order;

当数据库中的字段的名称是实际是不一致的时候需要进行标注出来

@TableField("username")
private Boolean name;

字段不存在

 @TableField(exist = false)
    private static final long serialVersionUID = 1L;

更新策略

当什么的时候进行更新

当什么的时候进行不进行插入

类型转换器

常用的可以自动的进行转换的,只是针对比较复杂的是不能直接进行转换的,需要单独指定转换的处理器的

2.2常见的配置

下面是常见的配置

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true  #开启驼峰命名匹配
    cache-enabled: true #是不是开启二级缓存
  global-config:
    db-config:
      update-strategy: not_null #更新策略,只更新非空的字段
  mapper-locations: classpath:mapper/**/*.xml #文件地址
  type-aliases-package: com.lxz.demo.domain #别名扫描包

补充:二级缓存

减少读取数据库的次数

cache-enabled和二级缓存是与数据访问相关的概念,用于提高应用程序的性能和响应速度。

cache-enabled:
cache-enabled是一个配置选项,通常用于配置数据访问框架(如Spring Data、Hibernate等),以启用或禁用缓存功能。当将cache-enabled配置为true时,表示启用缓存功能,数据访问框架将会自动将查询结果存储在缓存中,以便后续的请求可以直接从缓存中获取数据,而不需要再次访问数据库。

二级缓存:
二级缓存是一种位于数据库和应用程序之间的缓存层,用于存储数据库查询的结果。它是在数据访问框架层面实现的,独立于特定的数据库引擎。当启用了二级缓存后,查询结果会被缓存到内存中,以加快下次相同查询的响应速度。

二级缓存的工作原理如下:

当应用程序发送一个查询请求时,数据访问框架首先检查缓存中是否存在该查询的结果。
如果缓存中存在结果,数据访问框架直接从缓存中获取并返回结果,避免了与数据库的交互操作,从而提高了性能。
如果缓存中不存在结果,数据访问框架会执行查询操作,将结果存储到缓存中,并返回结果给应用程序。
二级缓存通常适用于频繁读取的数据,可以减少数据库的访问次数,提高系统的性能和响应速度。但需要注意的是,如果对于同一份数据的更新频繁,可能会导致缓存与数据库中的数据不一致,因此在使用二级缓存时需要做好缓存的管理和数据的一致性维护。

总结而言,cache-enabled配置项用于启用或禁用数据访问框架的缓存功能。二级缓存是在数据访问框架层面实现的缓存机制,用于存储数据库查询的结果,从而提高应用程序的性能和响应速度。

2.3条件构造器

实现一些复杂的操作

支持各种复杂的where条件的操作。
在这里插入图片描述
Wrapper就是一个条件构造器
Wrapper常见的实现

在这里插入图片描述
完成下面的操作
在这里插入图片描述
解析:采用得是QueryWrapper得链式编程得方式

  • select 指定要查询得字段
  • like 模糊
  • ge 大于得

 @Test
    void  test7(){
        //构建查询条件 支持链式编程的
        QueryWrapper<User>  wrapper = new QueryWrapper<User>()
                .select("id","username","info","balance")
                .like("username","o")
                .ge("balance",1000)
                ;

        //查询
        List<User> list=userMapper.selectList(wrapper);
        list.forEach(System.out::println);

    }

查询结果
JDBC Connection [HikariProxyConnection@1434151479 wrapping com.mysql.cj.jdbc.ConnectionImpl@11b32a14] will not be managed by Spring
==>  Preparing: SELECT id,username,info,balance FROM user WHERE (username LIKE ? AND balance >= ?)
==> Parameters: %o%(String), 1000(Integer)
<==    Columns: id, username, info, balance
<==        Row: 3, Hope, <<BLOB>>, 100000
<==      Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6aa7b67f]
User(id=3, username=Hope, password=null, phone=null, info={"age": 25, "intro": "上进青年", "gender": "male"}, status=null, balance=100000, createTime=null, updateTime=null)
2023-09-02 23:07:26.511  INFO 26960 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...

在这里插入图片描述

  @Test
    void  test8(){
        //更新得数据
        User user=new User();
        user.setBalance(2000);

        //条件
        QueryWrapper<User> wrapper=new QueryWrapper<User>()
                .eq("username","jack");
        //参数1 不是空得数据作为更新得数据
        //参数2 作为查询得条件 要进行更新得数据
        userMapper.update(user,wrapper);
    }



JDBC Connection [HikariProxyConnection@776192909 wrapping com.mysql.cj.jdbc.ConnectionImpl@649f25f3] will not be managed by Spring
==>  Preparing: UPDATE user SET balance=? WHERE (username = ?)
==> Parameters: 2000(Integer), jack(String)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@66deec87]

在这里插入图片描述
采用UpdateWrapper
在这里插入图片描述
解析:下面得是完成如下得操作得

UPDATE user SET balance=balance-200 WHERE (username = ?)
    @Test
    void  test9(){
      

        //条件 UpdateWrapper是可以不知道准确得值得
        UpdateWrapper<User> wrapper=new UpdateWrapper<User>()
                .setSql("balance=balance-200")
                .eq("username","Jack");

        userMapper.update(null,wrapper);
    }

LambdaUpdateWrapper

好处是不把对应得属性进行写死

    @Test
    void  test10(){
        //条件 UpdateWrapper是可以不知道准确得值得
        LambdaUpdateWrapper<User> wrapper=new LambdaUpdateWrapper<User>()
                .setSql("balance=balance+200")
                .eq(User::getUsername,"Jack");

        userMapper.update(null,wrapper);
    }

在这里插入图片描述

或者是采用下面得方式可以得

采用调用lambda得方式

    @Test
    void  test11(){
      
        QueryWrapper<User> wrapper=new QueryWrapper<User>();
        wrapper.lambda()
                .select(User::getUsername)
                .select(User::getBalance)
                .select(User::getInfo)
                .eq(User::getId,1L);


        userMapper.selectList(wrapper).forEach(System.out::println);
    }

或者是直接采用下面得方式

    @Test
    void  test12(){
        LambdaQueryWrapper<User> wrapper=new LambdaQueryWrapper<User>()
                .select(User::getUsername)
                .select(User::getBalance)
                .select(User::getInfo)
                .eq(User::getId,1L);
        userMapper.selectList(wrapper).forEach(System.out::println);
    }

比上面得那种调用lamda得方法是更加简便得。

在这里插入图片描述

2.4自定义SQL

并不是自己手写对应得sql

下面得sql不能出现在下面得语句中是不方便进行维护得。我们需要作出相应得修改得。

   @Test
    void  test10(){
        //条件 UpdateWrapper是可以不知道准确得值得
        LambdaUpdateWrapper<User> wrapper=new LambdaUpdateWrapper<User>()
                .setSql("balance=balance+200")
                .eq(User::getUsername,"Jack");

        userMapper.update(null,wrapper);
    }

采用sql转换得方式

采用where条件得拼接

在这里插入图片描述
下面是自定义sql得案例1

  • 构建自定义sql

LambdaQueryWrapper 就是我们需要查询得where中得条件是后面需要进行拼接得内容。

findUserByUserName是自定义得方法。传入得参数就是Wrapper

    @Test
    void  test13(){
        //构建
        LambdaQueryWrapper<User> wrapper=new LambdaQueryWrapper<User>()
                .like(User::getUsername,"o")
                .ge(User::getBalance,500);
        //查询
        userMapper.findUserByUserName(wrapper).forEach(System.out::println);
    }
    
  • mapper层的方法定义

传入得参数必须是ew

//此处必须是ew
    List<User> findUserByUserName(@Param("ew") LambdaQueryWrapper<User> wrapper);
  • xml文件

采用ew.customSqlSegment进行对应的参数内容的接收

 <select id="findUserByUserName" resultType="User">
        select * from  user ${ew.customSqlSegment}
 </select>

下面是查询的结果

拼接的sql:select * from user WHERE (username LIKE ? AND balance >= ?) 这个sql就是我们原先自己定义的sql的内容

JDBC Connection [HikariProxyConnection@1406324738 wrapping com.mysql.cj.jdbc.ConnectionImpl@5b39a3e6] will not be managed by Spring
==>  Preparing: select * from user WHERE (username LIKE ? AND balance >= ?)
==> Parameters: %o%(String), 500(Integer)
<==    Columns: id, username, password, phone, info, status, balance, create_time, update_time
<==        Row: 3, Hope, 123, 13900112222, <<BLOB>>, 1, 100000, 2023-06-19 22:37:44, 2023-06-19 22:37:44
<==        Row: 4, Thomas, 123, 17701265258, <<BLOB>>, 1, 800, 2023-06-19 23:44:45, 2023-06-19 23:44:45
<==      Total: 2
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@39c96e48]
User(id=3, username=Hope, password=123, phone=13900112222, info={"age": 25, "intro": "上进青年", "gender": "male"}, status=1, balance=100000, createTime=Mon Jun 19 22:37:44 CST 2023, updateTime=Mon Jun 19 22:37:44 CST 2023)
User(id=4, username=Thomas, password=123, phone=17701265258, info={"age": 29, "intro": "伏地魔", "gender": "male"}, status=1, balance=800, createTime=Mon Jun 19 23:44:45 CST 2023, updateTime=Mon Jun 19 23:44:45 CST 2023)

下面是案例2

  • 未更新之前的数据
    在这里插入图片描述
    创建更新的测试方法
    @Test
    void  test14(){
        //构建条件
        LambdaQueryWrapper<User> wrapper=new LambdaQueryWrapper<User>()
                .in(User::getId,1L,2L,3L);
        //执行更新
       int line = userMapper.updateBalanceByWrapper(wrapper);
       System.out.println("line="+line);
    }

创建mapper层的方法

//批量更新
    int updateBalanceByWrapper(@Param("ew") LambdaQueryWrapper<User> wrapper);

创建自定义sql

<update id="updateBalanceByWrapper">
        update user set  balance = balance-200 ${ew.customSqlSegment}
</update>

更新的结果

JDBC Connection [HikariProxyConnection@200760156 wrapping com.mysql.cj.jdbc.ConnectionImpl@16da476c] will not be managed by Spring
==>  Preparing: update user set balance = balance-200 WHERE (id IN (?,?,?))
==> Parameters: 1(Long), 2(Long), 3(Long)
<==    Updates: 3
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2e86807a]
line=3

更新之后的数据
在这里插入图片描述
对于多表的话一般采用的是原生的mybatis的方式进行写sql的操作。对于多表的mp的支持是不好的,但是部分是可以也是可以使用的。

完成部分多表查询的操作
在这里插入图片描述
sql是下面的写法

-- 查询所有的user的信息
SELECT * from user u ;

-- 查询所有地址
SELECT * from address addr;


-- 查询收获地址是北京的并且用户id是 1 2 4  的用户
SELECT * from user u 
JOIN
address addr
ON
u.id=addr.user_id
WHERE
addr.user_id IN(1,2,4)
AND 
addr.city='北京';



下面是原先的写法

    <select id="findUserByCity" resultType="User">
        SELECT * from user u
            JOIN  address addr
              ON u.id=addr.user_id
        WHERE
            addr.user_id
          <foreach collection="ids" separator="," item="id" open="in (" close=")">
                #{id}
           </foreach>
          AND
            addr.city=#{city};
    </select>
    
    
    
List<User> findUserByCity(@Param("ids") List<Long> ids,@Param("city") String city);
@Test
void  test15(){
    List<Long> ids=new ArrayList<Long>();
    ids.add(1L);
    ids.add(2L);
    ids.add(3L);
    userMapper.findUserByCity(ids,"北京").forEach(System.out::println);
}

结果

JDBC Connection [HikariProxyConnection@1709321711 wrapping com.mysql.cj.jdbc.ConnectionImpl@4b1ec694] will not be managed by Spring
==>  Preparing: SELECT * from user u JOIN address addr ON u.id=addr.user_id WHERE addr.user_id in ( ? , ? , ? ) AND addr.city=?;
==> Parameters: 1(Long), 2(Long), 3(Long), 北京(String)
<==    Columns: id, username, password, phone, info, status, balance, create_time, update_time, id, user_id, province, city, town, mobile, street, contact, is_default, notes
<==        Row: 1, Jack, 123, 13900112224, <<BLOB>>, 1, 1800, 2023-05-19 20:50:21, 2023-06-19 20:50:21, 60, 1, 北京, 北京, 朝阳区, 13700221122, 修正大厦, Jack, 0, null
<==        Row: 2, Rose, 123, 13900112223, <<BLOB>>, 1, 300, 2023-05-19 21:00:23, 2023-06-19 21:00:23, 59, 2, 北京, 北京, 朝阳区, 13900112222, 金燕龙办公楼, Rose, 1, null
<==      Total: 2
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@118dcbbd]
User(id=1, username=Jack, password=123, phone=13900112224, info={"age": 20, "intro": "佛系青年", "gender": "male"}, status=1, balance=1800, createTime=Fri May 19 20:50:21 CST 2023, updateTime=Mon Jun 19 20:50:21 CST 2023)
User(id=2, username=Rose, password=123, phone=13900112223, info={"age": 19, "intro": "青涩少女", "gender": "female"}, status=1, balance=300, createTime=Fri May 19 21:00:23 CST 2023, updateTime=Mon Jun 19 21:00:23 CST 2023)

上面是原先的写法,采用的是sql拼接的方式现在我们不采用上面的方式而是采用一种比较新的sql拼接的方式

sql拼接的方式

 @Test
    void  test16(){
        List<Long> ids=new ArrayList<Long>();
        ids.add(1L);
        ids.add(2L);
        ids.add(3L);
        QueryWrapper<User>    queryWrapper=new QueryWrapper<User>()
                .in("u.id",ids)
                .eq("addr.city","北京");
        userMapper.findUserByCity2(queryWrapper).forEach(System.out::println);
    }

//采用mp完成多表查询
List<User> findUserByCity2(@Param("ew") QueryWrapper<User> queryWrapper);
<select id="findUserByCity2" resultType="User">
    SELECT * from user u
    JOIN
    address addr
    ON
    u.id=addr.user_id
     ${ew.customSqlSegment}
</select>

结果

==>  Preparing: SELECT * from user u JOIN address addr ON u.id=addr.user_id WHERE (u.id IN (?,?,?) AND addr.city = ?)
==> Parameters: 1(Long), 2(Long), 3(Long), 北京(String)
<==    Columns: id, username, password, phone, info, status, balance, create_time, update_time, id, user_id, province, city, town, mobile, street, contact, is_default, notes
<==        Row: 1, Jack, 123, 13900112224, <<BLOB>>, 1, 1800, 2023-05-19 20:50:21, 2023-06-19 20:50:21, 60, 1, 北京, 北京, 朝阳区, 13700221122, 修正大厦, Jack, 0, null
<==        Row: 2, Rose, 123, 13900112223, <<BLOB>>, 1, 300, 2023-05-19 21:00:23, 2023-06-19 21:00:23, 59, 2, 北京, 北京, 朝阳区, 13900112222, 金燕龙办公楼, Rose, 1, null
<==      Total: 2
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2e86807a]
User(id=1, username=Jack, password=123, phone=13900112224, info={"age": 20, "intro": "佛系青年", "gender": "male"}, status=1, balance=1800, createTime=Fri May 19 20:50:21 CST 2023, updateTime=Mon Jun 19 20:50:21 CST 2023)
User(id=2, username=Rose, password=123, phone=13900112223, info={"age": 19, "intro": "青涩少女", "gender": "female"}, status=1, balance=300, createTime=Fri May 19 21:00:23 CST 2023, updateTime=Mon Jun 19 21:00:23 CST 2023)

上面的操作本质是用了单表的查询的操作。

2.5Service接口

完成对单表的Service操作

分为常见的8个范围的操作
在这里插入图片描述

save 单个
saveBatch 批量添加
saveOrUpdateBatch 
saveOrUpdate 增或该 要是传入id的话会根据id查询要是有的话就更新没有的话就插入
update
单个和批量

查询一个

getOne
getById
removeById
removeByMap
remove
removeByIds
removeBatchByIds
count

分页

page

链式编程

lambdaQuery
lambdaQUpdate

可以拿到当前的mapper

比如当使用自定义sql的时候可以使用获取mappe的方法

getBaseMapper

编写service

public interface UserService extends IService<User> {

}

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService{

}

测试基本操作

 @Autowired
    private UserService userService;
    //测试增加
    @Test
    void test111(){
        //要么就是insert就是save,创建一个User对象就写入进行就可以的
        User user=new User();
        user.setUsername("李四");
        user.setPassword("123456");
        user.setPhone("13900112224");
        JSONObject jsonObject=new JSONObject();
        //hutool中的
        jsonObject.set("age",29);
        jsonObject.set("intro","伏地魔");
        jsonObject.set("gender","male");
        user.setInfo(jsonObject.toString());
        user.setStatus(1);
        user.setBalance(2000);
        user.setCreateTime(DateTime.now());
        user.setUpdateTime(DateTime.now());
        boolean line=userService.save(user);
        System.out.println("line="+line);
    }
JDBC Connection [HikariProxyConnection@1868288866 wrapping com.mysql.cj.jdbc.ConnectionImpl@3a401749] will not be managed by Spring
==>  Preparing: INSERT INTO user ( username, password, phone, info, status, balance, create_time, update_time ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ? )
==> Parameters: 李四(String), 123456(String), 13900112224(String), {"age":29,"intro":"伏地魔","gender":"male"}(String), 1(Integer), 2000(Integer), 2023-09-03 00:03:46.12(Timestamp), 2023-09-03 00:03:46.12(Timestamp)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2b0e9f30]
line=true

在这里插入图片描述

    @Test
    void test22(){
        LambdaQueryWrapper<User> queryWrapper=new LambdaQueryWrapper<User>()
                .in(User::getId,1L,2L,3L);
        List<User> users= userService.list(queryWrapper);
        System.out.println("users="+users.toString());
    }
JDBC Connection [HikariProxyConnection@2133998394 wrapping com.mysql.cj.jdbc.ConnectionImpl@4f169009] will not be managed by Spring
==>  Preparing: SELECT id,username,password,phone,info,status,balance,create_time,update_time FROM user WHERE (id IN (?,?,?))
==> Parameters: 1(Long), 2(Long), 3(Long)
<==    Columns: id, username, password, phone, info, status, balance, create_time, update_time
<==        Row: 1, Jack, 123, 13900112224, <<BLOB>>, 1, 1800, 2023-05-19 20:50:21, 2023-06-19 20:50:21
<==        Row: 2, Rose, 123, 13900112223, <<BLOB>>, 1, 300, 2023-05-19 21:00:23, 2023-06-19 21:00:23
<==        Row: 3, Hope, 123, 13900112222, <<BLOB>>, 1, 99800, 2023-06-19 22:37:44, 2023-06-19 22:37:44
<==      Total: 3
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@303c55fa]
users=[User(id=1, username=Jack, password=123, phone=13900112224, info={"age": 20, "intro": "佛系青年", "gender": "male"}, status=1, balance=1800, createTime=Fri May 19 20:50:21 CST 2023, updateTime=Mon Jun 19 20:50:21 CST 2023), User(id=2, username=Rose, password=123, phone=13900112223, info={"age": 19, "intro": "青涩少女", "gender": "female"}, status=1, balance=300, createTime=Fri May 19 21:00:23 CST 2023, updateTime=Mon Jun 19 21:00:23 CST 2023), User(id=3, username=Hope, password=123, phone=13900112222, info={"age": 25, "intro": "上进青年", "gender": "male"}, status=1, balance=99800, createTime=Mon Jun 19 22:37:44 CST 2023, updateTime=Mon Jun 19 22:37:44 CST 2023)]

service接口得批量插入
在这里插入图片描述

    @Test
    void tes51(){
        long b =System.currentTimeMillis();
        for (int i = 0; i <100000 ; i++) {
            User user=new User();
            user.setUsername("王五"+i);
            user.setPassword("123456"+i);
            user.setPhone(i+"");
            JSONObject jsonObject=new JSONObject();
            //hutool中的
            jsonObject.set("age",i);
            jsonObject.set("intro","伏地魔"+i);
            jsonObject.set("gender","male");
            user.setInfo(jsonObject.toString());
            user.setStatus(1);
            user.setBalance(2000);
            user.setCreateTime(DateTime.now());
            user.setUpdateTime(DateTime.now());
            userMapper.insert(user);
        }
        long e =System.currentTimeMillis();
        System.out.println("耗时="+(e-b));
    }

下面是插入的结果

...... 省略
JDBC Connection [HikariProxyConnection@1503775440 wrapping com.mysql.cj.jdbc.ConnectionImpl@34be065a] will not be managed by Spring
==>  Preparing: INSERT INTO user ( username, password, phone, info, status, balance, create_time, update_time ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ? )
==> Parameters: 王五99998(String), 12345699998(String), 99998(String), {"age":99998,"intro":"伏地魔99998","gender":"male"}(String), 1(Integer), 2000(Integer), 2023-09-03 14:40:12.668(Timestamp), 2023-09-03 14:40:12.668(Timestamp)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2493a6d]
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@52140522] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@87335674 wrapping com.mysql.cj.jdbc.ConnectionImpl@34be065a] will not be managed by Spring
==>  Preparing: INSERT INTO user ( username, password, phone, info, status, balance, create_time, update_time ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ? )
==> Parameters: 王五99999(String), 12345699999(String), 99999(String), {"age":99999,"intro":"伏地魔99999","gender":"male"}(String), 1(Integer), 2000(Integer), 2023-09-03 14:40:12.671(Timestamp), 2023-09-03 14:40:12.671(Timestamp)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@52140522]
耗时=490293

下面是批量插入的过程

 //批量插入采用1000条的插入,减少内存的消耗
    @Test
    void tes52(){
        long b =System.currentTimeMillis();
        //设置一下初始化的内存
        List<User> list=new ArrayList<User>(1000);
        for (int i = 1; i <= 100000 ; i++) {
            User user=new User();
            user.setUsername("赵六"+i);
            user.setPassword(i+"123456");
            user.setPhone(i+"102");
            JSONObject jsonObject=new JSONObject();
            //hutool中的
            jsonObject.set("age",i);
            jsonObject.set("intro",i+"伏地魔");
            jsonObject.set("gender","female");
            user.setInfo(jsonObject.toString());
            user.setStatus(1);
            user.setBalance(2000);
            user.setCreateTime(DateTime.now());
            user.setUpdateTime(DateTime.now());
            list.add(user);
            if (i%1000==0) {
                userService.saveBatch(list);
                list.clear();
            }
        }
        long e =System.currentTimeMillis();
        System.out.println("耗时="+(e-b));
    }

结果

==> Parameters: 赵六99992(String), 99992123456(String), 99992102(String), {"age":99992,"intro":"99992伏地魔","gender":"female"}(String), 1(Integer), 2000(Integer), 2023-09-03 14:46:53.14(Timestamp), 2023-09-03 14:46:53.14(Timestamp)
==> Parameters: 赵六99993(String), 99993123456(String), 99993102(String), {"age":99993,"intro":"99993伏地魔","gender":"female"}(String), 1(Integer), 2000(Integer), 2023-09-03 14:46:53.14(Timestamp), 2023-09-03 14:46:53.14(Timestamp)
==> Parameters: 赵六99994(String), 99994123456(String), 99994102(String), {"age":99994,"intro":"99994伏地魔","gender":"female"}(String), 1(Integer), 2000(Integer), 2023-09-03 14:46:53.14(Timestamp), 2023-09-03 14:46:53.14(Timestamp)
==> Parameters: 赵六99995(String), 99995123456(String), 99995102(String), {"age":99995,"intro":"99995伏地魔","gender":"female"}(String), 1(Integer), 2000(Integer), 2023-09-03 14:46:53.14(Timestamp), 2023-09-03 14:46:53.14(Timestamp)
==> Parameters: 赵六99996(String), 99996123456(String), 99996102(String), {"age":99996,"intro":"99996伏地魔","gender":"female"}(String), 1(Integer), 2000(Integer), 2023-09-03 14:46:53.14(Timestamp), 2023-09-03 14:46:53.14(Timestamp)
==> Parameters: 赵六99997(String), 99997123456(String), 99997102(String), {"age":99997,"intro":"99997伏地魔","gender":"female"}(String), 1(Integer), 2000(Integer), 2023-09-03 14:46:53.14(Timestamp), 2023-09-03 14:46:53.14(Timestamp)
==> Parameters: 赵六99998(String), 99998123456(String), 99998102(String), {"age":99998,"intro":"99998伏地魔","gender":"female"}(String), 1(Integer), 2000(Integer), 2023-09-03 14:46:53.14(Timestamp), 2023-09-03 14:46:53.14(Timestamp)
==> Parameters: 赵六99999(String), 99999123456(String), 99999102(String), {"age":99999,"intro":"99999伏地魔","gender":"female"}(String), 1(Integer), 2000(Integer), 2023-09-03 14:46:53.14(Timestamp), 2023-09-03 14:46:53.14(Timestamp)
==> Parameters: 赵六100000(String), 100000123456(String), 100000102(String), {"age":100000,"intro":"100000伏地魔","gender":"female"}(String), 1(Integer), 2000(Integer), 2023-09-03 14:46:53.14(Timestamp), 2023-09-03 14:46:53.14(Timestamp)
耗时=23273

490293-23273=467,020;两者时间的时间差是相当多的。

在这里插入图片描述

一条一条插入的是加入的values的方式
下面的方式是采用的预编译的方式进行插入的

修改默认插入的参数

需要打开对应的开关采用达到批处理的方式而不知直接传入参数的方式

参考博客:mybatis的批处理(效率)之rewriteBatchedStatements和allowMultiQueries_suqinyi的博客-CSDN博客

rewriteBatchedStatements=true:批量将数据传给mysql
一个一个的插入:490293
批处理耗时:23273
基于预编译的耗时=6519
底层是重写了一个sql。这个效率是最高的。

2.6IService的Lambda查询

    @Test
    void tes53(){
       User user= userService.lambdaQuery()
                .eq(User::getUsername,"Rose").one();
        System.out.println(user.toString());
    }

JDBC Connection [HikariProxyConnection@535910992 wrapping com.mysql.cj.jdbc.ConnectionImpl@217c23ce] will not be managed by Spring
==>  Preparing: SELECT id,username,password,phone,info,status,balance,create_time,update_time FROM user WHERE (username = ?)
==> Parameters: Rose(String)
<==    Columns: id, username, password, phone, info, status, balance, create_time, update_time
<==        Row: 2, Rose, 123, 13900112223, <<BLOB>>, 1, 300, 2023-05-19 21:00:23, 2023-06-19 21:00:23
<==      Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@19a20bb2]
User(id=2, username=Rose, password=123, phone=13900112223, info={"age": 19, "intro": "青涩少女", "gender": "female"}, status=1, balance=300, createTime=Fri May 19 21:00:23 CST 2023, updateTime=Mon Jun 19 21:00:23 CST 2023)

   @Test
    void tes54(){
        Long count= userService.lambdaQuery()
                .eq(User::getUsername,"Rose").count();
        System.out.println(count);
    }

JDBC Connection [HikariProxyConnection@138010466 wrapping com.mysql.cj.jdbc.ConnectionImpl@76e90da5] will not be managed by Spring
==>  Preparing: SELECT COUNT( * ) FROM user WHERE (username = ?)
==> Parameters: Rose(String)
<==    Columns: COUNT( * )
<==        Row: 1
<==      Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@b5de58f]
1

2.7动态查询参数

在这里插入图片描述

    //查询用户列表

    public List<User> queryUsers(String userName, Integer status, Long min, Long max) {
        List<User>  list= userService.lambdaQuery()
                .like(userName!=null,User::getUsername,userName)
                .eq(status!=null,User::getStatus,status)
                .gt(min!=null,User::getBalance,min)
                .lt(max!=null,User::getBalance,max).list();

        return list;
    }
    @Test
    void tes56(){
        queryUsers("o",1,null,null);
    }

  • 第一个参数是条件就是后面的语句是不是运行的条件
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3eb3232b] was not registered for synchronization because synchronization is not active
2023-09-03 15:28:17.012  INFO 11884 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2023-09-03 15:28:17.168  INFO 11884 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
JDBC Connection [HikariProxyConnection@302007694 wrapping com.mysql.cj.jdbc.ConnectionImpl@5fcd1c5f] will not be managed by Spring
==>  Preparing: SELECT id,username,password,phone,info,status,balance,create_time,update_time FROM user WHERE (username LIKE ? AND status = ?)
==> Parameters: %o%(String), 1(Integer)
<==    Columns: id, username, password, phone, info, status, balance, create_time, update_time
<==        Row: 2, Rose, 123, 13900112223, <<BLOB>>, 1, 300, 2023-05-19 21:00:23, 2023-06-19 21:00:23
<==        Row: 3, Hope, 123, 13900112222, <<BLOB>>, 1, 99800, 2023-06-19 22:37:44, 2023-06-19 22:37:44
<==        Row: 4, Thomas, 123, 17701265258, <<BLOB>>, 1, 1000, 2023-06-19 23:44:45, 2023-06-19 23:44:45
<==      Total: 3
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3eb3232b]

2.8Lambda更新操作

下面将实现动态更新的功能
在这里插入图片描述

 @Test
    void tes57(){
        updateBalance(0L,1L,null);
    }


    public boolean updateBalance(Long balance,Long id,String userName){
        if (id==null&&userName==null){
            throw new RuntimeException("更新条件不能为空!");
        }
        //更新
        boolean flag=userService.lambdaUpdate()
        .set(User::getBalance,balance)
        .set(balance==0,User::getStatus,2)
        .eq(id!=null,User::getId,id)
        .eq(userName!=null,User::getUsername,userName).update();
        return flag;
    }
JDBC Connection [HikariProxyConnection@663925782 wrapping com.mysql.cj.jdbc.ConnectionImpl@4735d6e5] will not be managed by Spring
==>  Preparing: UPDATE user SET balance=?,status=? WHERE (id = ?)
==> Parameters: 0(Long), 2(Integer), 1(Long)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@74d6736]

在这里插入图片描述

2.9静态插件

避免循环依赖

解决的方法1:

  • 直接调用mapper层的方法不去调用service层的方法

在这里插入图片描述

boolean line=Db.save(user);
 Db.saveBatch(list);
 
     @Test
    void tes53(){
       User user= Db.lambdaQuery(User.class)
                .eq(User::getUsername,"Rose").one();
        System.out.println(user.toString());
    }
    @Test
    void tes54(){
        Long count= Db.lambdaQuery(User.class)
                .eq(User::getUsername,"Rose").count();
        System.out.println(count);
    }
    @Test
    void tes55(){
        Long count= Db.lambdaQuery(User.class)
                .eq(User::getUsername,"Rose").count();
        System.out.println(count);
    }
 //查询用户列表

    public List<User> queryUsers(String userName, Integer status, Long min, Long max) {
        List<User>  list= Db.lambdaQuery(User.class)
                .like(userName!=null,User::getUsername,userName)
                .eq(status!=null,User::getStatus,status)
                .gt(min!=null,User::getBalance,min)
                .lt(max!=null,User::getBalance,max).list();

        return list;
    }
    @Test
    void tes56(){
        queryUsers("o",1,null,null);
    }

    @Test
    void tes57(){
        updateBalance(0L,1L,null);
    }
JDBC Connection [HikariProxyConnection@874548138 wrapping com.mysql.cj.jdbc.ConnectionImpl@71370fec] will not be managed by Spring
==>  Preparing: SELECT id,username,password,phone,info,status,balance,create_time,update_time FROM user WHERE (username LIKE ? AND status = ?)
==> Parameters: %o%(String), 1(Integer)
<==    Columns: id, username, password, phone, info, status, balance, create_time, update_time
<==        Row: 2, Rose, 123, 13900112223, <<BLOB>>, 1, 300, 2023-05-19 21:00:23, 2023-06-19 21:00:23
<==        Row: 3, Hope, 123, 13900112222, <<BLOB>>, 1, 99800, 2023-06-19 22:37:44, 2023-06-19 22:37:44
<==        Row: 4, Thomas, 123, 17701265258, <<BLOB>>, 1, 1000, 2023-06-19 23:44:45, 2023-06-19 23:44:45
<==      Total: 3
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5b5a4aed]

唯一的区别是需要单独多传入一个类的类型的参数。

上面的方法的好处是可以解决服务层类之间循环依赖 之间的调用的关系。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MyBatis-Plus-入门操作(1) 的相关文章

随机推荐

  • TypeScript ---- 初识基础篇

    TypeScript 初识基础篇 写在前面 本篇文章篇幅有点长 适合正打算学习TS的小白 如果有一定基础的大神可以忽略本篇文章 文章并非完全原创 大部分内容都是从网上其他文章搬运过来的 再在其中添加上自己的一些理解和总结 如果有涉及侵权请联
  • C语言的基本结构(一)

    目录 1 C语言程序框架 1 1 程序编译的过程 1 2 C语言程序结构分析 1 C语言程序框架 C程序一般由头文件 主函数和函数三部分组成 从最简单的程序开始 对于大多数程序语言 第一个入门编程代码便是 Hello World 一步一步的
  • SQA在线聊天记录三:QA的职责要求和基本素质

    SQA在线聊天记录三 QA的职责要求和基本素质 2005 05 20 来自 CSDN管理频道 共有评论 条 发表评论 嘉宾主持Bluesky 这里涉及到一个问题 在招聘QA的时候 怎么看待QA人员具备的素质 CSDN的调查结果显示 47 的
  • 签名获取错误(错误: java.io.IOException: Invalid keystore format)签名中没打印出MD5信息

    安卓生成签名文件获取信息的小坑 首先我们通过AndroidStudio生成的签名文件 生成时使用的jdk是根据Studio配置的jdk版本 也就是说是根据下图 图一 中的jdk版本 假如这个jdk版本和电脑配置的环境变量的jdk 图二 不是
  • win10应用商店打不开,错误代码0x80131500

    我也突然遇到这个问题 一开始找各种方法也解决不了 然后在外网找到方法 很多人只是把代理开了 只要关了就可以了 这点不累述 都会提到 我的win10应用商店有两个错误代码0x80131500和0x80072efd 0x80131500错误会转
  • 粒子群算法优化策略总结

    粒子群算法优化策略总结 前言 1 对于惯性权重w的优化 1 1 引入混沌Sine映射构造非线性随机递增惯性权重 1 2 采用一种指数型的非线性递减惯性权重 1 3 分策略更改惯性权重 2 对于c1 c2的优化 2 1 引入正余弦函数来构造非
  • 永久一键关闭QQ频道,不用重新安装

    Step1 使用WMIC指令排查QQ相关进程 首先 按住Windows键 R键打开 运行 然后输入CMD 开启CMD工具 然后 输入如下指令 查找QQ相关的进程信息 由于我这里已经卸载了QQGuild 所以查找不到 wmic process
  • 解决VsCode 软件上方菜单栏消失问题

    当软件的页面出现这样的情况 菜单栏消失 变成三个横杠 不要慌 有方法解决 将鼠标放在此位置上 右键会出现选项 点击红色框选的项目 即可将工作区解锁出上方 这样菜单栏就会出现 如果还是没有将 菜单栏 弄出来 使用快捷键Ctrl Shift P
  • 做项目必读的vue3基础知识

    1 响应式 1 1 两者实现原理 vue2 利用es5的 Object defineProperty 对数据进行劫持结合发布订阅模式来实现 vue3 利用es6的 proxy 对数据代理 通过 reactive 函数给每一个对象都包一层 p
  • 华为p40android auto怎么用,华为手机无线投屏到车载导航,华为车机互联教程

    越来越多的车机系统可以与手机互联 不同的系统连接方式不一样 我们主要以华为手机与车机互联的教程说明 华为手机无线投屏到车载导航的方法 车型雷克萨斯18款ES200 手机是华为MATE8 安卓7 0版本 不同的品牌车型连接方式不一样 可以根据
  • String.ToCharArray()方法中的内存优化技巧

    原文发表于CSDN我的Blog http blog csdn net happyhippy archive 2006 10 29 1356088 aspx 先看下Reflector exe反汇编 net framework 2 0中Msco
  • DNS根服务器

    从抓包可以看出 DNS在传输层上使用了UDP协议 那它只用UDP吗 DNS的IPV4根域名只有13个 这里面其实有不少都部署在漂亮国 那是不是意味着 只要他们不高兴了 切断我们的访问 我们的网络就得瘫痪了呢 我们来展开今天的话题 DNS是基
  • PrintWriter out= response.getWriter()失效无法在前端弹出提示框以及乱码问题.

    PrintWriter out response getWriter 失效无法在前端弹出提示框 在后端想弹出提示框最简单的办法就是使用PrintWriter getWriter PrintWriter out response getWri
  • 使用ELK(ES+Logstash+Filebeat+Kibana)收集nginx的日志

    文章目录 引入logstash Nginx日志格式修改 配置logstash收集nginx日志 引入Redis 收集日志写入redis 从redis中读取日志 logstash解析自定义日志格式 引入Filebeat Filebeat简介
  • 七种性能测试方法

    根据在实际项目中的实践经验 我把常用的性能测试方法分为七大类 后端性能测试 Back end Performance Test 前端性能测试 Front end Performance Test 代码级性能测试 Code level Per
  • USB的阻抗匹配问题

    USB的阻抗匹配问题 USB特征阻抗90 总结 低速和全速时最好进行阻抗匹配 源端串联或终端并联90ohm 高速时不需要 USB 可以自动选择HS High Speed 高速 480 Mbps FS Full Speed 全速 12Mbps
  • 【SpringBoot】获取request请求参数,多次读取报错问题 (has already been called for this request)

    应用场景 因项目中接口请求时 需要对请求参数进行签名验证 当请求参数的body中有基本类型时 例 int long boolean等 因为基本类型如果没传值 序列化的时候会有默认值的问题 最后导致实际接口调用生成的签名和项目中进行校验的签名
  • adb通过TCP/IP连接提示 unable to connect to *, Connection refused的解决方法

    通过串口连接板子进入命令行 然后执行 su setprop service adb tcp port 5555 stop adbd start adbd
  • C++:STL的引入和string类

    文章目录 STL STL是什么 STL的六大组件 string string类内成员函数 迭代器 STL STL是什么 什么是STL STL是C 标准库的重要组成部分 不仅是一个可复用的组件库 而且是一个包罗数据结构与算法的软件框架 STL
  • MyBatis-Plus-入门操作(1)

    MyBatis Plus 入门操作 2 1常见注解 约定大于配置 mp扫描实体类基于反射的方式作为数据库表的信息 默认的约定 类名驼峰转下划线 名字为id的是主键 属性名进行驼峰转换成下划线 要是不遵循约定的话就需要对应的注解进行修改 表的