跨数据库查询!在表名前面加 数据库名就好
数据库表字段类型为 datetime,查的时候直接用字符串,不需要用时间戳
mybatisplus的page类型转换可以用page继承的Ipage接口的方法
public Page<SingleAppUseListVo> getSingleAppUseList( Long startTime, Long endTime,
String appName, int page, int limit ) {
Page<TbAppVisitDetailEntity> page1 = new Page<> (page,limit);
Page<TbAppVisitDetailEntity> entities =
this.page (page1,new QueryWrapper<TbAppVisitDetailEntity> ()
.select ("visitTime","visitUserName","visitDeptName")
.between ("visitTime",startTime,endTime));
return (Page<SingleAppUseListVo>) entities.convert (entity ->{
String visitTime = tranDate (entity.getVisitTime ());
SingleAppUseListVo vo = new SingleAppUseListVo ();
BeanUtils.copyProperties (entity,vo);
vo.setVisitTime (visitTime);
return vo;
});
}
乐观锁
在数据库表中加一个version字段,每次修改的时候,version的值增加
查询的时候也把version查出来,更新的时候version要和之前的一样(如果这个值已经被修改,即version的值已经增加,重新查一次再更新)
查询
select id,... ,version
from product_doc
where id=777
更新
update product_doc
set version=version+1,...
where id=777 and version=9
当方法添加了事务,不能在Navicat直接看到数据库表的变化,可以新建查询添加这条命令看到:SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
如果表的 字段名 和数据库中的关键字冲突,不能直接调用mybatisplus的接口,要自己写sql语句最好修改成不冲突的!
自己写sql语句,数据库不设id自增要加id
基础使用:【默认已开启驼峰命名】
依赖:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
安装插件:MybatisX【本机已安装】
配置:【注意下面的日志打印sql】
spring:
datasource:
url: jdbc:mysql://localhost:3306/blog?useUnicode=true&characterEncoding=UTF-8&serverTimeZone=UTC
username: root
password:
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
#打印sql语句
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#表的前缀
global-config:
db-config:
table-prefix: ms_
mapper接口:【mybatisplus 可以只写 dao层的mapper接口,不需要写实现类】
mapper接口中加上 @Mapper注解。或许可以在配置文件中配置扫描包,或者在启动类配置扫描包【推荐加 @Mapper注解】
mapper接口 继承baseMapper,如下:
@Mapper
public interface ArticleBodyMapper extends BaseMapper<ArticleBody> {
}
1.service实现类可以直接用 mapper接口里面的方法 【myplus默认提供】
2.service实现类可以 编写 wrapper条件,进行操作【wrapper在有if语句的时候,比写sql更灵活】
3.service实现类也可以自己写mapper.xml文件
mapper接口:【加 @Param 注解!!!】
List<Tag> findTagsByArticleId(@Param("articleId") long articleId);
mapper接口:对象传参!!!
int insertProdyct(@Param("productEntity") ProductEntity productEntity );
mapper.xml 名称空间:
<?xml version="1.0" encoding="UTF-8" ?>
<!--MyBatis配置文件-->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Mapper的全类名,如com.xxxx.blog.dao.mapper.ArticleMapper">
</mapper>
mapper.xml文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!--MyBatis配置文件-->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
// 写mapper接口 的类路径
<mapper namespace="com.xxxx.blog.dao.mapper.TagMapper">
// parameterType 可以不写,resultType写mapper接口返回的类【如果是数组,写数组元素的类】,#{} 取mapper接口函数中 @Param 注解的标识
// #{} 取值: 比较安全,使用预处理 不能动态改变表名 。${} 不太安全,不是使用预处理,可以取表名
<select id="findTagsByArticleId" parameterType="long" resultType="com.xxxx.blog.dao.pojo.Tag">
select id,avatar,tag_name as tagName from ms_tag
where id in
(select tag_id from ms_article_tag where article_id=#{articleId} )
</select>
</mapper>
mapper.xml文件: 对象传参
<?xml version="1.0" encoding="UTF-8" ?>
<!--MyBatis配置文件-->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xxxx.product.dao.ProductMapper">
<insert id="insertProdyct">
INSERT into product(`name`,price,`describe`,state) VALUES(#{productEntity.name},
#{productEntity.price},
#{productEntity.describe},
#{productEntity.state})
</insert>
</mapper>
使用mybatis,表名做为变量
mapper接口(dao层)【方法】
Article selectArticleById(@Param("radomId") int radomId, @Param("tableName") String tableName);
mapper.xml文件【sql语句】
<select id="selectArticleById" resultType="com.xxxx.zxg.dao.pojo.Article">
select * from ${tableName} where id = ${radomId};
</select>
mybatis-plus 雪花算法:【mybatis-plus 默认使用雪花算法生成id】【注意数据库表 id , pojo id ,vo id 类型!!!】生成的id是15位的长数字,直接传前端会损失精度 数据库的表的id字段设为bigint pojo里面对应id使用Long vo里面可以用String(pojo转vo的时候要小心id有没有转过去)也可以用Long,然后加上@JsonSerialize(using = ToStringSerializer.class)注解
**实体类的属性,使用包装类!!!**原始类型会 赋值 为0包装类型会 赋值 为null用于封装数据库表 的实体类,用原始类型可能会导致 更新出错!
实体类注解:@TableName(“pms_attr_attrgroup_relation”) 将指定的数据库表和 JavaBean 进行映射@TableId 如果表的id名字 和 类的id名字不同,要用此注解【不管怎么样,加上就行】用上一条注解,默认id是自增的,如果需要自己写id,用这个:@TableId(type = IdType.INPUT)@TableField:
非主键字段,value映射表字段名:
@TableField(value = "sort")
private Integer attrSort;
类中属性不存在表中:
@TableField(exist = false)
private Integer attrSort;
逻辑删除:(mybatis-plus功能)(低版本的看官网,要加配置类)
配置文件:
#逻辑已删除值
mybatis-plus.global-config.db-config.logic-delete-value=0
#逻辑未删除值
mybatis-plus.global-config.db-config.logic-not-delete-value=0
在实体类的某个字段加上注解:@TableLogic
或者也可以自定义这个字段的删除值:@TableLogic(value = "1",delval = "0") 显示(逻辑不删除)是1,不显示(逻辑删除)是0
分页插件:配置类
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MybatisPlusConfig {
//分页插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}
创建 Page 对象 ,使用分页【查询条件可以直接new一个,然后放在那里,相当于没有条件】【myplus提供的函数 返回 Page对象,使用getRecords获取查询的结果】
@Service
public class ProductServiceIml extends ServiceImpl<ProductMapper, ProductEntity> implements ProductService {
@Override
public List<ProductVo> getListProduct() {
// 演示一下分页使用
Page<ProductEntity> page1 = new Page<> (1,1);
Page<ProductEntity> page2 = new Page<> (1,2);
Page<ProductEntity> productPage1 = this.baseMapper.selectPage (page1, new QueryWrapper<ProductEntity> ());
System.out.println (productPage1.getRecords ());
Page<ProductEntity> productPage2 = this.baseMapper.selectPage (page2, new QueryWrapper<ProductEntity> ());
System.out.println (productPage2.getRecords ());
return null;
}
}
结果
[ProductEntity(id=1511338905977757697, productName=中华传统文化课本, price=20.0, descript=现在的中华传统文化课还在用的, state=1, createTime=Tue Apr 05 13:44:08 CST 2022)]
[ProductEntity(id=1511338905977757697, productName=中华传统文化课本, price=20.0, descript=现在的中华传统文化课还在用的, state=1, createTime=Tue Apr 05 13:44:08 CST 2022), ProductEntity(id=1511339076446855170, productName=计算机组成原理课本, price=20.0, descript=第5版,附带电子版答案哦, state=1, createTime=Tue Apr 05 13:44:49 CST 2022)]
另一种(如果要写sql语句,不用在意page的封装,返回的是对象)
在config软件包下 配置分页插件:
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableTransactionManagement // 开启事务
@MapperScan("com.xxxx.gulimall.product.dao")
public class MyBatisConfig {
//引入分页插件
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
//设置请求的页面大于最大页后操作,true调回到首页,false继续请求默认false
paginationInterceptor.setOverflow(true);
//设置最大单页限制数量,默认50条,-1不受限制
paginationInterceptor.setLimit(1000);
return paginationInterceptor;
}
}
controller层:
@PostMapping
public Result listArticle(@RequestBody PageParams params){
return articleService.listArticle(params);
}
service层:【主要在这层 使用分页 】【page中的records 属性是查询出的值,可以set和getRecords()】
@Override
public Result listArticle(PageParams pageParams) {
// 设置页面的页码和一页中元素的个数
Page<Article> page = new Page<>(pageParams.getPage(),pageParams.getPageSize());
// 传入page对象 和 查询条件 【也可以写wrapper】
IPage<Article> articleIPage = articleMapper.listArticle(
page,
pageParams.getCatogoryId(),
pageParams.getTagId(),
pageParams.getYear(),
pageParams.getMonth()
);
List<Article> records = articleIPage.getRecords();
return Result.success(copyList(records,true,true,true,true));
}
dao层:
IPage<Article> listArticle(Page<Article> page,
Long categoryId,
Long tagId,
String year,
String month);
mapper:【看不出使用了分页插件,与平常sql语句无异】【常见情况 返回参数写Ipage泛型里的类即可】
<resultMap id="articleMap" type="com.xxxx.blog.dao.pojo.Article">
<id column="id" property="id" />
<result column="author_id" property="authorId"/>
<result column="comment_counts" property="commentCounts"/>
<result column="create_date" property="createDate"/>
<result column="summary" property="summary"/>
<result column="title" property="title"/>
<result column="view_counts" property="viewCounts"/>
<result column="weight" property="weight"/>
<result column="body_id" property="bodyId"/>
<result column="category_id" property="categoryId"/>
</resultMap>
<select id="listArticle" resultMap="articleMap">
select * from ms_article
<where>
1 = 1
<if test="categoryId != null">
and category_id=#{categoryId}
</if>
<if test="tagId != null">
and id in (select article_id from ms_article_tag where tag_id=#{tagId})
</if>
<if test="year != null and year.length > 0 and month != null and month.length > 0">
and (FROM_UNIXTIME(create_date/1000,'%Y')=#{year} and FROM_UNIXTIME(create_date/1000,'%m')=#{month})
</if>
</where>
order by weight,create_date desc
</select>