Mybatisplus的使用Mapper的CRUD、AR、条件构造器、代码生成器

Mybatiplus是mybatis增强工具包,制作增强,不做改变。

官网:http://mp.baomidou.com

注解:

//@TableName    实体类的类名和数据库表名不一致

//@TableId    实体类的主键名称和表中主键名称不一致,和主键策略,type是主键策略。

//@TableField   实体类中的成员名称和表中字段名称不一致,value是数据库字段名,fill是自动插入、更新等,exist表示存不存在(如果数据库没有把它设置为false,就不会出现在数据库语句中)

 

javaBean中的成员变量的类型使用时尽量使用包装类型(如Integer、String),这样当不存在的时候会返回null,有利于判断。

 .propertises文件相关配置:https://blog.csdn.net/weixin_42873160/article/details/94622555

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://localhost:3306/school?serverTimezone=Hongkong&useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.dbcp2.min-idle=5
spring.datasource.dbcp2.initial-size=5
spring.datasource.dbcp2.max-total=5
spring.datasource.dbcp2.max-wait-millis=200
#mybatis-plus
# 如果是放在src/main/java目录下 classpath:/com/yourpackage/*/mapper/*Mapper.xml
# 如果是放在resource目录 classpath:/mapper/*Mapper.xml
mybatis-plus.mapper-locations=classpath:/com/springboot/study/mapper/*Mapper.xml
#实体扫描,多个package用逗号或者分号分隔
mybatis-plus.type-aliases-package=com.springboot.study.entity
#主键类型  0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
mybatis-plus.global-config.id-type=3
#字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
mybatis-plus.global-config.field-strategy=2
#驼峰下划线转换
mybatis-plus.global-config.db-column-underline=true
#mp2.3+ 全局表前缀 mp_
#mybatis-plus.global.table-prefix: mp_
#刷新mapper 调试神器
mybatis-plus.global-config.refresh-mapper=true
#数据库大写下划线转换
mybatis-plus.global-config.capital-mode=true
# Sequence序列接口实现类配置
mybatis-plus.global-config.key-generator=com.baomidou.mybatisplus.incrementer.OracleKeyGenerator
#逻辑删除配置(下面3个配置)
mybatis-plus.global-config.logic-delete-value=1
mybatis-plus.global-config.logic-not-delete-value=0
mybatis-plus.global-config.sql-injector=com.baomidou.springboot.MyMetaObjectHandler
#配置返回数据库(column下划线命名&&返回java实体是驼峰命名),自动匹配无需as(没开启这个,SQL需要写as: select user_id as userId)
mybatis-plus.configuration.map-underscore-to-camel-case=true

 

 

***在po m.xml中引入,mybatis和mybatis-spring不需要加入,mybatisplus会自动维护。

 <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.3.1.tmp</version>
    </dependency>

***创建mybatisplus的配置文件:

可以用xml文件,也可以使用Java类配置。

****Mapper层CRUD******

***插入

一定更要在id前面加一个主键策略,否则数据库表中id会乱。
	@TableId(type=IdType.AUTO)
     private Long id;




*****
@RequestMapping("/add")
	public R insertUser() {
            User user=new User();
            user.setId(null);
			user.setAge(18);
			user.setName("lmabo");
			user.setToken("mytoken");
			Integer   result =  userMapper.insert(user);
			//获取新插入数据字数据库中的主键值
			Long i=user.getId();
		System.out.println("新插入的主键值"+i);
		return R.ok().data("add",result);
	}
		
	

 

***更新

//更新,根据id修改user对象
	@RequestMapping("/updatebyid")
	public R updateUser() {
            User user=new User();
            user.setId(3L);
			user.setAge(18);
			user.setName("lambo001");
			user.setToken("mytoken");
			Integer   result =  userMapper.updateById(user);
		return R.ok().data("updatebyid",result);
	}
	
	

***查询

//查询,通过id
		@RequestMapping("/selectbyid")
		public R selectUser0() {
				User   user =  userMapper.selectById(6);
			return R.ok().data("selectById",user);
		}
		//查询,通过id
				@RequestMapping("/selectall")
				public R selectUser01() {
					List<User> users = userMapper.selectList(null);
					return R.ok().data("selectById",users);
				}
//		//通过多个列查询
//		@RequestMapping("/selectbycolumns")
//		public R selectUser02() {
//			
//			 User user=new User();
//	            user.setId(3L);
//				user.setAge(18);
//				User   resuser =  userMapper.selectOne(queryWrapper)
//			return R.ok().data("selectbycolumns",resuser);
//		}
		
		      //根据ID批量查询
				@RequestMapping("/selectBatchIds")
				public R selectUser03() {
					List<Integer> idlist=new ArrayList<>();
					idlist.add(3);
					idlist.add(4);
						List<User>   userlist =  userMapper.selectBatchIds(idlist);
					return R.ok().data("selectById",userlist);
				}
				//通过map查询
				@RequestMapping("/selectByMap")
				public R selectUser04() {
					Map<String,Object> columnMap=new HashMap<>();
					columnMap.put("name", "lambo001");
					List<User>   userlist =  userMapper.selectByMap(columnMap);
					return R.ok().data("selectById",userlist);
				}
				
				//通过page查询
				@RequestMapping("/selectpage")
				public R selectUser05() {
					Page<User> page=	new Page<User>(1,5);
					Page<User> usepage=userMapper.selectPage(page, null);
						long current=usepage.getCurrent();
						long pages=usepage.getPages();
						long total=usepage.getTotal();
						long size=usepage.getSize();
						System.out.println(total);
						List<User>users=usepage.getRecords();
						users.forEach(System.out::println);
					return R.ok().data("selectpage",users);
				}
				
				
				

			

***删除

	/**
				 * 根据id删除
				 * **/
				@RequestMapping("/deletebyid")
				public R deletebyid() {
					 int result=userMapper.deleteById(2L);
					 System.out.println(result);
					 return R.ok().data("deletebyid",result);
				}
				
				/**
				 * 批量删除
				 * **/
				@RequestMapping("/deletebatch")
				public R deleteBatch() {
					 int result=userMapper.deleteBatchIds(Arrays.asList(1,2,3));
					 System.out.println(result);
					 return R.ok().data("deletebatch",result);
				}
				
				/**
				 * 简单条件 查询删除
				 * */
				@RequestMapping("/deletebymap")
				public R DeleteByMap() {
					HashMap<String,Object>map=new HashMap<>();
					map.put("name","lambo");
					map.put("age", 35);
					int result=userMapper.deleteByMap(map);
					System.out.println(result);
					return R.ok().data("deletebymap",result);
				}

***mybatis全局策略配置:

下划线和驼峰命名对应(如:数据库中a_c字段可以对应java类中的aC属性;)

可以全局配置主键的策略;

全局表前缀配置;

***mybatisplus启动注入sql的原理:

mybatis的执行流程:

***条件构造器:

mybatisplus通过QueryWrapper(以前是EntityWrapper)封装一个查询条件构造器,后者用condition来让用户自由的构建查询条件。

用的是数据库字段,不是java属性;

QueryWrapper(以前是EntityWrapper)、updateWrapper继承Wrapper;

语法糖是计算机语言中添加的某种语法,这种语法对语言的功能没有影响,可以避免出错机会,帮助开发者更好的调试。

		//删除
			public void testone1() {
				
				QueryWrapper<User> queryWrapper=new QueryWrapper<>();
				queryWrapper.isNull("name").ge("age",23).isNotNull("phoneNum");
					int result=userMapper.delete(queryWrapper);		
					
				}

		
	//查询
			public void testselectOne2() {
					QueryWrapper<User> queryWrapper=new QueryWrapper<>();
				queryWrapper.eq("name", "tom");
			User user=userMapper.selectOne(queryWrapper);
		
		}

			//selectPage
			public  R selectPage() {
				Page<User> page=	new Page<User>(1,5);
				QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
				queryWrapper.between("id", 1,3).eq("age", 18);
				Page<User> pag=userMapper.selectPage(page, queryWrapper);
                 List<User> res=	pag.getRecords();
				 return R.ok().data("data", res);
			}

			public R testselectList4() {
					QueryWrapper<User> queryWrapper=new QueryWrapper<>();
			Map<String,Object> map=new HashMap<>();
			map.put("id",22);
			map.put("name","jack");
			map.put("age",38);
			queryWrapper.allEq(map);
			List<User> users=userMapper.selectList(queryWrapper);
			 return R.ok().data("data",users);
			}
			
			
			public R testselectList04() {
				QueryWrapper<User> queryWrapper=new QueryWrapper<>();
		queryWrapper.eq("age", 18).orderByAsc("age");
		List<User> users=userMapper.selectList(queryWrapper);
		 return R.ok().data("data",users);
		}

		public R testselectMap5() {
				QueryWrapper<User> queryWrapper=new QueryWrapper<>();
			queryWrapper.notLike("id",22).
			likeRight("name","l");
				List<Map<String,Object>> users=userMapper.selectMaps(queryWrapper);
				 return R.ok().data("data",users);
		}
	


		public R testselectObjects6() {
				QueryWrapper<User> queryWrapper=new QueryWrapper<>();
			queryWrapper.inSql("id", "select id from user where id>11");
			List<Object> users=userMapper.selectObjs(queryWrapper);
			 return R.ok().data("data",users);
				}

//		//这个貌似现在不用了
//		public R conditionselect() {
//			Page<User> page=	new Page<User>(1,5);
//			Page<User> users=userMapper.selectPage(page,Condition.create().between("age",1,20));
//			 return R.ok().data("data",users);
//
//		}
		
     
 //更新
			public R testUpdates7() {
				//要修改的值
				User user=new User();
				user.setAge(20);
				user.setName("lamboo");
				
				//修改的条件
				UpdateWrapper<User> updateWrapper=new UpdateWrapper<>();
					updateWrapper.notLike("id",22).or().
					likeRight("name","l");
				updateWrapper.notLike("id",22).or(
			i->i.eq("name","l").ne("age",20));
		
						int result=userMapper.update(user,updateWrapper);
						 return R.ok().data("data",result);
		}


			public R testselectSet8() {
				User user=new User();
					user.setAge(20);
				user.setName("lamboo");
					
				//修改的条件
				UpdateWrapper<User> updateWrapper=new UpdateWrapper<>();
					updateWrapper.like("name","name").set("name","lisi").setSql("phoneNum='1333333'");
				int result=userMapper.update(user,updateWrapper);
				 return R.ok().data("data",result);
			}

 

***ActiveRecord活动记录

一种领域模型模式,特点是一个模型对应关系型数据库中的一个表,一个模型类的一个实例对应对应表中的一行记录。

/*
			 * AR操作
			 * */
			
			//插入
			public R ar1() {
				User user=new User();
				user.setAge(20);
			user.setName("lamboo");
		boolean res=user.insert();
				 return R.ok().data("data",res);
			}
			
			//update
			public R ar2() {
				User user=new User();
				user.setId(3L);
				user.setAge(20);
			user.setName("lamboo");
			boolean res=user.updateById();
				 return R.ok().data("data",res);
			}
			
			//查询
			public R ar3() {
				User user=new User();
				
				User res=user.selectById(3L);
				 return R.ok().data("data",res);
			}
			
			public R ar4() {
				User user=new User();
				user.setId(3L);
			User res=user.selectById();
				 return R.ok().data("data",res);
			}
			
			//查询全表
			public R ar5() {
				User user=new User();
			List<User>  res=user.selectAll();
				 return R.ok().data("data",res);
			}
			
			public R ar6() {
				User user=new User();
			QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
			queryWrapper.between("id", 1,3).eq("age", 18);
			List<User>  res=user.selectList(queryWrapper);
				 return R.ok().data("data",res);
			}
			
			
			//查询统计
			public R ar7() {
				User user=new User();
				QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
				queryWrapper.between("id", 1,3).eq("age", 18);
			Integer res=user.selectCount(queryWrapper);
				 return R.ok().data("data",res);
			}
			
			//分页的复杂操作
			public R ar11() {
				User user=new User();
				Page<User> page=	new Page<User>(1,5);
				QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
				queryWrapper.between("id", 1,3).eq("age", 18);
				Page<User> pag=user.selectPage(page, queryWrapper);
			List<User> res=	pag.getRecords();
				 return R.ok().data("data",res);
			}
			
			
			//删除
			
			public R ar8() {
				User user=new User();
				user.setId(3L);
			boolean res=user.deleteById();
				 return R.ok().data("data",res);
			}
			
			public R ar9() {
				User user=new User();
			boolean res=user.deleteById(3);
				 return R.ok().data("data",res);
			}
			
			public R ar10() {
				User user=new User();
				QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
				queryWrapper.between("id", 1,3).eq("age", 18);
			boolean res=user.delete(queryWrapper);
				 return R.ok().data("data",res);
			}
			

***代码生成器:https://mybatis.plus/guide/generator.html#编写配置

mybatisplus的代码生成器是基于java代码生成的,mybatis 的代码生成器MBG是基于xml文件进行代码生成的。

mybaitis代码生成器可生成:实体类、mapper接口、mapper映射文件;

mybaitisplus代码生成器可生成:实体类(可以选择是否支持AR)、mapper接口、mapper映射文件、service层、controller层;

表及字段命名的策略选择,建议数据库表明和表字段名采用驼峰命名,如果使用下划线命名,需要开启下划线开关。如果表名和字段名方式不一致,需要用注解。

代码生成器需要加入的依赖:mybatisplus生成器默认是用的是Apache的Velocity模板,淡然也可以更改为其他模版,如freemarker。

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.3.1.tmp</version>
</dependency>
 <!--		添加 模板引擎-->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.1</version>
        </dependency>

//1.全局配置

    //2.数据源配置

    //3.策略配置

    //4.包名配置

    //5.整合配置

//6.执行

以下只是参照,引入GlobalConfig包的时候要注意,选择generator的那个;

AutoGenerator mpg = new AutoGenerator();

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        gc.setOutputDir("D:\\generation");//输出文件路径
        gc.setFileOverride(true); // 是否文件覆盖
        gc.setActiveRecord(false);// 不需要ActiveRecord(实体类继承Model)特性的请改为false
        gc.setEnableCache(false);// XML 二级缓存
        gc.setBaseResultMap(true);// XML ResultMap
        gc.setBaseColumnList(true);// XML ColumnList
        gc.setAuthor("lizhan");// 作者

        // 自定义文件命名,注意 %s 会自动填充表实体属性!
        gc.setControllerName("%sController");
        // 默认service接口名IXXXService 自定义指定之后就不会用I开头了
        gc.setServiceName("%sService");
        gc.setServiceImplName("%sServiceImpl");
        gc.setMapperName("%sMapper");
        gc.setXmlName("%sMapper");
        mpg.setGlobalConfig(gc);

        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setDbType(DbType.MYSQL);
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("xxx");
        dsc.setPassword("xxx");
        dsc.setUrl("jdbc:mysql://localhost:3306/xxx");
        mpg.setDataSource(dsc);

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        // strategy.setTablePrefix(new String[] { "sys_" });// 此处可以修改为您的表前缀
        strategy.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略(下划线转驼峰)
        strategy.setInclude("user"); // 需要生成的表名

        strategy.setSuperServiceClass(null);
        strategy.setSuperServiceImplClass(null);
        strategy.setSuperMapperClass(null);

        mpg.setStrategy(strategy);

        // 包配置
        PackageConfig pc = new PackageConfig();
        pc.setParent("com.xxx");
        pc.setController("controller");
        pc.setService("service");
        pc.setServiceImpl("impl");
        pc.setMapper("mapper");
        pc.setEntity("entity");
        pc.setXml("xml");
        mpg.setPackageInfo(pc);

        // 执行生成
        mpg.execute();

****IService

在ServiceImpl中已经完成了mapper对象的注入,可以直接使用CRUD;

@Service

public interface TeacherService extends IService<Teacher>

public class TeacherServiceImpl extends ServiceImpl implements TeacherService

 

***插件

mybatis插件机制:可以做拦截四大对象,Excutor,StatementHandler,ParameterHandler,ResultSetHandler;

插件原理:四大对象每个在创建的时候,都会执行interceptorChain.pluginAll();会经过每个插件对象的plugin()方法,

目的是为当前的四大对象创建代理对象,通过代理来执行;

分页插件:

在MybatisPlusConfig配置文件中实现以下的方法:

@Configuration

@EnableTransactionManagement

@MapperScan("com.example.demo.mapper")

@Api("配置")

public class MybatisPlusConfig {  }

/**
 * 分页插件
 * */

@ApiOperation(value="分页插件")
@Bean
public PaginationInterceptor paginationInterceptor() {
	
	 PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
     // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
     // paginationInterceptor.setOverflow(false);
     // 设置最大单页限制数量,默认 500 条,-1 不受限制
     // paginationInterceptor.setLimit(500);
     // 开启 count 的 join 优化,只针对部分 left join
     paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
     return paginationInterceptor;
}

乐观锁插件:@Version用于注解实体字段,必须要有。在数据库表中要有version这个字段。

@Version

private Integer  version;

@Bean
public OptimisticLockerInterceptor  optimisticLockerInterceptor() {
	return new OptimisticLockerInterceptor();
}

****执行效率插件

/**
 * sql执行效率插件
 * */
@Bean
@Profile({"dev","test"}) 
public  PerformanceMonitorInterceptor  performanceMonitorInterceptor() {
	PerformanceMonitorInterceptor p= new  PerformanceMonitorInterceptor();

	return p;
}

***快速开发插件MybatisX

MybatisX 是一款基于 IDEA 的快速开发插件,为效率而生。

安装方法:打开 IDEA,进入 File -> Settings -> Plugins -> Browse Repositories,输入 mybatisx 搜索并安装

可实现java和xml的跳转;根据mapper接口中的方法自动生成xml;

 

 

***mybatisplus中sql注入器https://www.cnblogs.com/liuyangfirst/p/9744011.htmlhttps://blog.csdn.net/Fire_Sky_Ho/article/details/104110352

*根据DefaultSqlInjector自定义各种sql注入;

/*1.在Mapper接口中定义相关的crud方法

*2.自定义一个继承AbstractMethod的类,重写相关的方法,在方法中实现自定义的sql语句。

    *3.创建注入器,新建一个类继承DefaultSqlInjector,实现,mapper接口中要注入的sql方法

    *4.在mybatisplus全局策略配置中配置自定义注入器。

*5.直接调用第一步在Mapper中注入的方法;

    **/

import org.springframework.stereotype.Repository;

/*这个是数据库操作的类,操作的是User实体类对应的数据库表*/

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.entity.User;
@Repository
public interface UserMapper extends BaseMapper<User>{
	/**
     *  自定义deleteAll操作
     *  在启动时 就自动注入,和BaseMapper里面的其他方法一样
     */
    int deleteAll();
}


***
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
//创建定义方法的类
public class DeleteAll   extends AbstractMethod {

	@Override
	public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
		 /* 执行 SQL ,动态 SQL 参考类 SqlMethod */
        String sql = "select age from " + tableInfo.getTableName();
        /* mapper 接口方法名一致 */
        String method = "deleteAll";
        SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
        return this.addDeleteMappedStatement(mapperClass, method, sqlSource);

	}

}


**
mport com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
//创建注入器
@Component
public class Mysqlinject extends DefaultSqlInjector{
	 /**
     * 如果只需增加方法,保留MP自带方法
     * 可以super.getMethodList() 再add
     */
    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
        List<AbstractMethod> methodList = super.getMethodList(mapperClass);
        methodList.add(new DeleteAll());
        return methodList;
    }


}


***
配置sql注入器


***调用mapper中定义的方法;

 

*逻辑删除:不是真正的删除,把被删除的这条数据中逻辑删除字段logic_flag置为删除状态,其实只是更新了logic_flag这个字段的值;

在数据库表中要有一个逻辑删除字段如logic_flag;

在java类中逻辑删除对应字段的属性上添加@TableLogic注解;

配置全局删除值,

 

*

***公共字段自动填充

更新插入都会自动填充
@TableField(value="update_time",fill = FieldFill.INSERT_UPDATE)
private Date updateTime;

//插入自动填充
@TableField(value="create_time",fill = FieldFill.INSERT)
private Date createTime;
//自定义字段自动填充处理器
@Component
public class MyMetaObjectHandler implements MetaObjectHandler{

	@Override
	public void insertFill(MetaObject metaObject) {
		//获取需要被填充的字段的值
		Object fieldValue=getFieldValByName("createTime",metaObject);
		if(fieldValue==null) {
			// 插入时自动更新的字段,这里面的第二个参数new Date()就是自动填充的值。
			this.setFieldValByName("createTime", new Date(), metaObject);
			this.setFieldValByName("updateTime", new Date(), metaObject);
		}
	}

	@Override
	public void updateFill(MetaObject metaObject) {
			//获取需要被填充的字段的值
				Object fieldValue=getFieldValByName("createTime",metaObject);
				if(fieldValue==null) {
		this.setFieldValByName("updateTime", new Date(), metaObject);
				}
	}
	

}

***Oracle   sequence主键策略

mysql支持主键自增,

Oracle不支持主键自增,通过序列Sequence;

因为授权的问题,无法从maven仓库中下载Orcale的驱动,需要从官方下载;

类之前添加注解@KeySequence(value="seq_user",clazz="Integer.class")

//主键策略@TableId(type=IdType.INSERT),或者作全局配置,在全局策略中注入;

可将@KeySequence定义在父类中,可实现多个子类对应多个表;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值