目录
回顾
MyBatis Plus框架学习(一)为什么要学习什么框架,简单的代码实现,查询全部数据
MyBatis Plus 中的CRUD
添加操作
@TableId(type = IdType.AUTO)
这个注解在实体类的字段上面,就是告诉,这个字段是主键,新增的时候主键要自增。
数据库现在有两条数据
@Test
public void testIns(){
//获取Spring容器对象
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationcontext.xml");
//获取StudentMapper接口的实例化对象
StudentMapper studentMapper= (StudentMapper) ac.getBean("studentMapper");
//创建学生对象存储要新增的学生信息
Student student=new Student();
student.setSname("赵六");
student.setSage(40);
student.setSsex("1");
student.setSphone("19988665533");
//新增学生信息
int i = studentMapper.insert(student);
//输出新增结果
System.out.println("新增学生信息:"+i+":"+student);
}
添加到数据库,如果出现 ??? 这种的,那么我们需要改一下配置
mysql.driver=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/mybatisplus?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8
mysql.username=root
mysql.password=123456
url 后面要加
?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8
记住: 新增完成,student实体类里面会自动将主键值加进去,不需要我们重新查一遍。
修改操作
@Test
public void testUp(){
//获取Spring容器对象
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationcontext.xml");
//获取StudentMapper接口的实例化对象
StudentMapper studentMapper= (StudentMapper) ac.getBean("studentMapper");
//创建学生对象存储要修改的信息以及要修改的学生的ID
Student student=new Student();
student.setSid(5);
student.setSname("赵六六");
//修改学生信息
int i = studentMapper.updateById(student);
//输出结果
System.out.println("修改学生信息:"+i);
}
删除操作
通过主键进行删除deleteById()
@Test
public void testDelById(){
//获取Spring容器对象
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationcontext.xml");
//获取StudentMapper接口的实例化对象
StudentMapper studentMapper= (StudentMapper) ac.getBean("studentMapper");
//根据ID删除学生信息
int i = studentMapper.deleteById(5);
//输出结果
System.out.println("根据ID删除结果:"+i);
}
删除:指定条件删除数据,deleteByMap
/** * 删除:指定条件删除数据,deleteByMap */
@Test
public void testDelByMap(){
//获取Spring容器对象
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationcontext.xml");
//获取StudentMapper接口的实例化对象
StudentMapper studentMapper= (StudentMapper) ac.getBean("studentMapper");
//创建map集合存储删除条件
Map<String,Object> map=new HashMap<>();
map.put("s_name","赵六");
map.put("sage",40);
//根据指定的条件删除学生信息
int i = studentMapper.deleteByMap(map);
//输出结果
System.out.println("根据条件删除结果:"+i);
}
删除:多选删除
@Test
public void testDelByIds(){
//获取Spring容器对象
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationcontext.xml");
//获取StudentMapper接口的实例化对象
StudentMapper studentMapper= (StudentMapper) ac.getBean("studentMapper");
//创建List集合存储要删除的数据的Id
List<Integer> list=new ArrayList<>();
list.add(2);
list.add(3);
//删除符合Id要求的数据
int i = studentMapper.deleteBatchIds(list);
//输出结果
System.out.println("多选删除结果:"+i);
查询操作
查询:通过ID查询
@Test
public void testselById(){
//获取Spring容器对象
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationcontext.xml");
//获取StudentMapper接口的实例化对象
StudentMapper studentMapper= (StudentMapper) ac.getBean("studentMapper");
//根据ID查询
Student student = studentMapper.selectById(1);
//输出结果
System.out.println("查询结果:"+student);
}
查询:通过指定的条件完成查询
@Test
public void testselByMap(){
//获取Spring容器对象
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationcontext.xml");
//获取StudentMapper接口的实例化对象
StudentMapper studentMapper= (StudentMapper) ac.getBean("studentMapper");
//创建Map集合存储查询条件
Map<String,Object> map=new HashMap<>();
map.put("s_name","张三");
map.put("sage",20);
//根据指定的条件查询
List<Student> students = studentMapper.selectByMap(map);
//输出结果
System.out.println("查修结果:"+students);
}
查询:根据ID集合获取数据
@Test
public void testselByIds(){
//获取Spring容器对象
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationcontext.xml");
//获取StudentMapper接口的实例化对象
StudentMapper studentMapper= (StudentMapper) ac.getBean("studentMapper");
//创建List集合存储id数据
List<Integer> list=new ArrayList<>();
list.add(1);
list.add(2);
//根据Id的集合查询信息
List<Student> students = studentMapper.selectBatchIds(list);
//输出结果
System.out.println("查询结果:"+students);
}
MyBatis Plus 条件构造器Wrapper的使用
[1]Wrapper条件构造器的介绍
问题:
目前我们可以使用mp完成基本的增删改查操作,但是我们在进行数据操作
时,很多时候Sql语句中的筛选条件是非常复杂的,比如or关键,>,<,模
糊查询等,怎么办?
解决:
mp提供了功能非常强大的Wrapper条件构造器
本质:
条件构造器其实就是一个对象,以方法的形式提供了数据库操作的筛选关键字
我们调用该对象,来拼接我们的筛选条件即可。
实现:
QueryWrapper
使用:
创建QueryWrapper对象,使用该对象中提供的对应的数据库操作的方法,来
完成条件的拼接,QueryWrapper对象最终存储拼接好的Sql片段,将片段
拼接在Sql语句中。
[2]QueryWrapper常用的方法说明
[3]带条件的查询的代码示例
public class TestMybatisPlusWrapper {
/** * * 查询: * 使用条件构造器封装查询条件 * 条件构造器是以java对象的形式将数据操作的筛选条件描述出来,然后由mp * 将其翻译成对应的sql判断拼接在sql语句上。 */
@Test
public void selMpWrapper(){
//获取Spring容器对象
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationcontext.xml");
//获取mapper对象
StudentMapper studentMapper= (StudentMapper) ac.getBean("studentMapper");
//创建条件构造器对象
QueryWrapper<Student> queryWrapper=new QueryWrapper<>();
queryWrapper.eq("sage", 20).or().like("s_name","张");
/*queryWrapper.or(); queryWrapper.eq("s_name","张三");*/
//根据条件查询数据
List<Student> students = studentMapper.selectList(queryWrapper);
//输出结果
System.out.println("查询结果:"+students);
}
}
MybatisPlus的分页查询
[1]MybatisPlus的分页查询介绍
问题:
对于传统的分页Sql语句,需要我们自己在Sql语句中
使用limit关键字来实现分页查询。但是呢,在MybatisPlus
中,Sql语句是动态生成的,那么如何完成数据的分页查询呢?
解决:
使用分页插件。
使用:
1.在配置文件中配置分页插件
2.在代码中调用分页效果
[2]MybatisPlus的分页查询的配置
<bean id="factory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
<!-- <!–配置mp的分页插件–>-->
<property name="plugins">
<array>
<!--配置分页插件:拦截对象-->
<bean class="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor">
<property name="dialectType" value="mysql"></property><!--指明要进行分页操作的数据库,因为不同的数据库的语句写法是不一样的,所以要指明是哪个数据库-->
</bean>
</array>
</property>
</bean>
因为这个查询数据库的xml语句是mybatisplus自动生成的,分页也是人家给我们生成的,所以我们得配置分页,配置好分页之后,在mybatisplus框架生成sql语句的时候,只要我们代码中用了分页,那么就会自动的生成分页sql语句。
[3]MybatisPlus分页查询的使用
@Test
public void testMpPage(){
//获取Spring容器对象
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationcontext.xml");
//获取mapper对象
StudentMapper studentMapper= (StudentMapper) ac.getBean("studentMapper");
//创建Page对象封装分页查询条件
IPage<Student> page=new Page<>(1,2);
//查询
IPage<Student> studentIPage = studentMapper.selectPage(page, null);
//输出结果
System.out.println("分页查询结果:"+studentIPage.getRecords());
System.out.println("分页总共的数据量:"+studentIPage.getTotal());
System.out.println("分页总共的页码数:"+studentIPage.getPages());
}
MybatisPlus的常用注解
[1]MybatisPlus的注解的介绍
问题:
在使用MybatisPlus后,我们不用再声明Sql语句了,只需要我们的Mapper
接口继承BaseMapper接口即可拥有对应的CRUD操作。通过我们之前的学习
我们发现,MyBatisPlus其实在根据我们的实体类来动态的生成对象的Sql语句
默认会按照类名即是对应的表的表名,属性名即是对应的表的字段名。但是如果
实体类名和表名不一致,或者属性名和字段名不一致怎么办?
解决:
在实体类上使用注解表名对应的映射关系。
注意:
建议大家在开发时尽量保证实体类和表之间的对应关系是相同的。这样就不用
声明注解。
[2]常用注解及其作用
1.@TableName注解
作用:表明实体类对应的数据库表
使用:在类名上使用,值为对应的表的表名
2.@TableId
作用:表明类中的某个属性为主键字段对应的属性
使用:在为主键的属性上使用
3.@TableField
作用:表明普通属性映射的表中的字段,值为字段名
使用:在普通属性上使用
[3]MybatisPlus中获取自增的主键值
在Mybatis中需要使用 useGeneratedKeys,keyProperty,keyColumn 设置自增主键值的回返,在实体类对象中获取即可。在MybatisPlus中在进行数据新增时,在新增成功后,会自动的将自增的主键值返回到实体类对象中,前提是需要在实体类中使用@TableId表明主键字段,并且为自增类型。
MybatisPlus的全局配置策略
[1]全局配置策略介绍
问题:
假如我们每个实体类和数据库中的表名都不一致,表的格式都是t_表名
类名呢没有t_字符,比如t_student表和Student类。这样每个实体类
上我们都要使用@TableName注解来表名类和表的映射关系,过于麻烦
怎么办?
解决:
使用MP的全局配置策略。GlobalConfig
作用:
配置表和类名映射关系的前缀。
配置全局主键自增
[2]全局配置策略示例
<!--配置工厂bean-->
<bean id="factory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
开启全局配置
<!-- <!–配置全局策略–>-->
<property name="globalConfig" ref="globalConfig"></property>
<!-- <!–配置mp的分页插件–>-->
<property name="plugins">
<array>
<!--配置分页插件:拦截对象-->
<bean class="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor">
<property name="dialectType" value="mysql"></property><!--指明要进行分页操作的数据库-->
</bean>
</array>
</property>
</bean>
全局的具体配置
<!--配置mp的全局策略-->
<bean id="globalConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig">
<!--配置数据库全局默认的映射关系-->
<property name="dbConfig">
<bean id="dbConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig">
<!--声明全局默认类名的对应的表的前缀-->
<property name="tablePrefix" value="t_"></property>
<!--配置全局主键自增-->
<property name="idType" value="AUTO"></property>
</bean>
</property>
</bean>
Active Record
支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
[1]AR模式和MP的Mapper模式的比较
1.原有MP的Mapper模式
①创建项目完成Spring和MP的集成
②创建数据库表对应的实体类
③创建mapper接口并继承BaseMapper接口
④从Spring容器中获取Mapper接口的实例化对象完成数据库操作
描述:
通过以上流程,MP的操作模式较于原有Mybatis的数据库操作流程
没有任何变化,只是我们在编写代码的时候不用在mapper层声明
Sql语句或者XML文件了,提升开发效率。
2.MP的AR模式
①创建项目完成Spring和MP的集成
②创建数据库表对应的实体类,继续Model类
③在实体类中覆写pkVal方法.
④创建Mapper接口并继承BaseMapper接口
⑤创建Spring对象,让Spring容器完成对Mapper层的实例化扫描
⑥创建实体类对象,直接调用实体类从Model中继承的数据库方法完成
数据库操作。
3.流程比较分析
MP的AR模式其实底层仍然使用的是Mapper层在完成数据库操作。
只不过由我们自己调用Mappe对象操作数据库,变成了通过
实体类对象来调用Mapper完成数据库操作。从代码的物理视图上
我们是看不到实体类调用Mapper的过程的。也就说,本质上仍然
是Mapper层在操作数据库
[2]AR模式的特点
AR模式较于传统的MP模式操作数据库,在代码体系中,
我们不用在获取Mapper对象,然后再将实体类传入给mapper层完成数据库操作
,直接使用实体类即可完成操作。
提升开发效率。
[3] AR模式的使用代码示例
1.创建一个集成了MP的SSM项目
2.在pojo层创建实体类,并继承Model类,覆写pkVal的方法
public class Student extends Model {
@TableId
private Integer sid;
@TableField("s_name")
private String sname;
private Integer sage;
private String ssex;
private String sphone;
@Override
public String toString() {
return "Student{" +
"sid=" + sid +
", sname='" + sname + '\'' +
", sage=" + sage +
", ssex='" + ssex + '\'' +
", sphone='" + sphone + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return Objects.equals(sid, student.sid) &&
Objects.equals(sname, student.sname) &&
Objects.equals(sage, student.sage) &&
Objects.equals(ssex, student.ssex) &&
Objects.equals(sphone, student.sphone);
}
@Override
public int hashCode() {
return Objects.hash(sid, sname, sage, ssex, sphone);
}
public Integer getSid() {
return sid;
}
public void setSid(Integer sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Integer getSage() {
return sage;
}
public void setSage(Integer sage) {
this.sage = sage;
}
public String getSsex() {
return ssex;
}
public void setSsex(String ssex) {
this.ssex = ssex;
}
public String getSphone() {
return sphone;
}
public void setSphone(String sphone) {
this.sphone = sphone;
}
public Student() {
}
public Student(Integer sid, String sname, Integer sage, String ssex, String sphone) {
this.sid = sid;
this.sname = sname;
this.sage = sage;
this.ssex = ssex;
this.sphone = sphone;
}
//复写pkVal方法
@Override
protected Serializable pkVal() {
return sid;
}
}
public class TestMpAR {
/** * 测试Mp的AR模式的查询 */
@Test
public void testAr(){
//获取Spring容器对象
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationcontext.xml");
//获取Student的实体类对象
Student student=new Student();
//使用AR模式操作数据库
//AR的查询的查询所有
List list = student.selectAll();
//输出查询结果
System.out.println("AR模式的查询:"+list);
//AR模式的根据ID查询
student.setSid(1);
Student stu = (Student) student.selectById();
System.out.println("根据Id查询的结果:"+stu);
}
/** * 测试Mp的AR模式的新增 */
@Test
public void testArAdd(){
//获取Spring容器对象
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationcontext.xml");
//获取Student的实体类对象
Student student=new Student();
student.setSname("小特");
student.setSage(70);
student.setSsex("1");
student.setSphone("4564654");
//使用AR模式的新增
boolean insert = student.insert();
System.out.println("新增结果:"+insert);
}
/** * 测试Mp的AR模式的更新 */
@Test
public void testArUp(){
//获取Spring容器对象
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationcontext.xml");
//获取Student的实体类对象
Student student=new Student();
student.setSid(1);
student.setSname("张三三");
//AR的更新
boolean b = student.updateById();
System.out.println("更新结果:"+b);
}
/** * 测试Mp的AR模式的删除 */
@Test
public void testArDel(){
//获取Spring容器对象
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationcontext.xml");
//获取Student的实体类对象
Student student=new Student();
student.setSid(10);
//AR的删除
boolean b = student.deleteById();
System.out.println("删除结果:"+b);
}
}
AutoGenerator代码生成器
作用:
根据数据库中的表动态的生成表对应的mapper,service,pojo,controller层的基础代码,提升开发效率。
MP代码生成器的使用
- 导入代码生成器相关jar包
public class TestCode {
public static void main(String[] args) {
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
//全局配置策略
GlobalConfig gc = new GlobalConfig();
String path = System.getProperty("user.dir");//动态获取当前项目的路径
System.out.println(path);
gc.setFileOverride(false);// 是否覆盖同名文件,默认是false
gc.setActiveRecord(true);// 不需要ActiveRecord特性的请改为false
gc.setEnableCache(false);// XML 二级缓存
gc.setBaseResultMap(true);// XML ResultMap
gc.setBaseColumnList(false);// XML columList
gc.setOutputDir(path+"/03_mp_code/src");
gc.setIdType(IdType.AUTO);//设置主键策略
//数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/mp?useUnicode=true&useSSL=false&characterEncoding=utf8");
// dsc.setSchemaName("public");
dsc.setDriverName("com.mysql.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("1234");
// 包配置
PackageConfig pc = new PackageConfig();
pc.setParent("com")
.setMapper("mapper")
.setService("service")
.setController("controller")
.setEntity("pojo")
.setXml("mapper");
//策略配置
StrategyConfig stConfig = new StrategyConfig();
stConfig.setCapitalMode(true) //全局大写命名
.setNaming(NamingStrategy.underline_to_camel) // 数据库表映射到实体的命名策略
.setTablePrefix("t_")
.setInclude("t_student"); // 生成的表,多个表继续传递即可,String类型的可变参数
//将策略配置对象集成到代码生成器中
mpg.setGlobalConfig(gc);
mpg.setDataSource(dsc);
mpg.setPackageInfo(pc);
mpg.setStrategy(stConfig);
//执行生成
mpg.execute();
}
}