MyBatis-Plus-入门操作(1)

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]

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

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

猜你喜欢

转载自blog.csdn.net/weixin_41957626/article/details/132792505