约定大于配置
mp扫描实体类基于反射的方式作为数据库表的信息。
默认的约定
要是不遵循约定的话就需要对应的注解进行修改。
表的名字和 实际的表的名字是不一致的
@TableName(value ="user",schema = "mp")
mp的主键
默认是不支持多个主键的
@TableId(type = IdType.AUTO)
默认的是: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;
更新策略
当什么的时候进行更新
当什么的时候进行不进行插入
类型转换器
常用的可以自动的进行转换的,只是针对比较复杂的是不能直接进行转换的,需要单独指定转换的处理器的
下面是常见的配置
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配置项用于启用或禁用数据访问框架的缓存功能。二级缓存是在数据访问框架层面实现的缓存机制,用于存储数据库查询的结果,从而提高应用程序的性能和响应速度。
实现一些复杂的操作
支持各种复杂的where条件的操作。
Wrapper就是一个条件构造器
Wrapper常见的实现
完成下面的操作
解析:采用得是QueryWrapper得链式编程得方式
@Test
void test7(){
//构建查询条件 支持链式编程的
QueryWrapper wrapper = new QueryWrapper()
.select("id","username","info","balance")
.like("username","o")
.ge("balance",1000)
;
//查询
List 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, <>, 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 wrapper=new QueryWrapper()
.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 wrapper=new UpdateWrapper()
.setSql("balance=balance-200")
.eq("username","Jack");
userMapper.update(null,wrapper);
}
LambdaUpdateWrapper
好处是不把对应得属性进行写死
@Test
void test10(){
//条件 UpdateWrapper是可以不知道准确得值得
LambdaUpdateWrapper wrapper=new LambdaUpdateWrapper()
.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得方法是更加简便得。
并不是自己手写对应得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条件得拼接
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);
}
传入得参数必须是ew
//此处必须是ew
List<User> findUserByUserName(@Param("ew") LambdaQueryWrapper<User> wrapper);
采用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 wrapper);
创建自定义sql
update user set balance = balance-200 ${ew.customSqlSegment}
更新的结果
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='北京';
下面是原先的写法
List findUserByCity(@Param("ids") List ids,@Param("city") String city);
@Test
void test15(){
List ids=new ArrayList();
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, <>, 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, <>, 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 ids=new ArrayList();
ids.add(1L);
ids.add(2L);
ids.add(3L);
QueryWrapper queryWrapper=new QueryWrapper()
.in("u.id",ids)
.eq("addr.city","北京");
userMapper.findUserByCity2(queryWrapper).forEach(System.out::println);
}
//采用mp完成多表查询
List findUserByCity2(@Param("ew") QueryWrapper queryWrapper);
结果
==> 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, <>, 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, <>, 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)
上面的操作本质是用了单表的查询的操作。
完成对单表的Service操作
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 {
}
@Service
public class UserServiceImpl extends ServiceImpl
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)]
@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 list=new ArrayList(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。这个效率是最高的。
@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, <>, 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
//查询用户列表
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]
@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]
避免循环依赖
解决的方法1:
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]
唯一的区别是需要单独多传入一个类的类型的参数。
上面的方法的好处是可以解决服务层类之间循环依赖 之间的调用的关系。