Data Access 之 MyBatis(八)- MyBatis 通用 Mapper(Part A)(下)

简介: Data Access 之 MyBatis(八)- MyBatis 通用 Mapper(Part A)

在test包下新建测试类PorscheMapperTest

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:application.xml")
public class PorscheMapperTest {
    @Resource
    private PorscheMapper porscheMapper;
    @Test
    public void getPorscheById(){
        Porsche panamera = porscheMapper.getPorscheById(1);
        System.out.println("查询到的内容为:" + panamera);
    }
}
复制代码

执行测试

ad5c5211da684725a60325dae54dcfa6_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

控制台成功查询出id为1的Porsche对象,框架搭建成功

二、通用Mapper实现基本增删改查-BaseMapper

2.1 集成通用Mapper

首先在pom.xml中通用Mapper的依赖

<dependency>
    <groupId>tk.mybatis</groupId>
    <artifactId>mapper</artifactId>
    <version>4.1.5</version>
</dependency>
复制代码

接着需要修改Spring配置文件

<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!--其他内容不变-->
    <!--Mapper XML的配置注销,使用通用Mapper就不再需要Mapper XML了-->
    <!--<property name="mapperLocations" value="classpath:mappers/*.xml"></property>-->
</bean>
<!--Dao层接口加入到Spring容器, 使用tk包下面的MapperScannerConfigurer,原来是org开头-->
<bean id="mapperScannerConfigurer" class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
    <!--其他内容不变-->
    <property name="basePackage" value="com.citi.mapper"></property>
</bean>
复制代码

删除mapper文件夹下的PorscheMapper.xml,因为使用通用Mapper不需要Mapper XML文件

2.2 selectOne () 方法

修改PorscheMapper接口及TeacherMapper接口,需要继承通用Mapper提供的Mapper接口,泛型为实体类类型,删除原有的方法

public interface TeacherMapper extends Mapper<Teacher> {
}
复制代码
public interface PorscheMapper extends Mapper<Porsche> {
}
复制代码

因为需要在声明式事务中调用Service层,新建service及impl两个包,增加PorscheServic接口PorscheServiceImpl实现类

public interface PorscheService {
    Porsche getOne(Porsche record);
}
复制代码
@Service
public class PorscheServiceImpl implements PorscheService {
    @Autowired
    private PorscheMapper porscheMapper;
    @Override
    public Porsche getOne(Porsche record) {
        return porscheMapper.selectOne(record);
    }
}
复制代码

查看看通用Mapper源码

43858fa3b9314b62ab424548b8d46609_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

  • BaseMapper:基本操作
  • ExampleMapper:Example封装查询条件,实现QBC查询,QBC(Query By Criteria)查询
  • RowBoundsMapper是做分页查询的

新建PorscheService接口的测试类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:application.xml")
public class PorscheServiceTest {
    @Autowired
    private PorscheService porscheService;
    @Test
    public void getOne() {
        // 构造查询条件
        Porsche record = new Porsche();
        record.setPorName("Cayenne");
        record.setPorPrice(910000d);
        // 执行查询
        Porsche porsche = porscheService.getOne(record);
        System.out.println("查询到的内容为:" + porsche);
    }
}
复制代码

执行测试

63596e62ba5345389dd288d824f279a5_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

根据控制台输出的SQL语句可以看出设置的查询条件全部生效,继承的通用Mapper的方法可用。

实体类封装查询条件的规则

  • 使用非空的值生成WHERE子句
  • 在条件表达式中使用 “=” 进行比较 如果根据查询条件返回多个结果则会报异常,将PorscheServiceTest中getOne方法中的set语句注释掉,再次执行测试

ee50aebd09ab437f9330a65db561d476_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

selectOne要求只返回一个结果

2.3 @Table和@Column注解

由于通用Mapper根据实体类生成对应的SQL语句,这就要求实体类的类名和属性最好与数据库表名和字段一致,如果不一致则会导致通用Mapper中提供的方法无法使用,以Teacher实体类和t_teacher表为例。

service包中新建TeacherService接口和TeacherServiceImpl实现类,新增getOne方法,调用TeacherMapper的selectOne方法

public interface TeacherService {
    Teacher getOne(Teacher record);
}
复制代码
@Service
public class TeacherServiceImpl implements TeacherService {
    @Autowired
    private TeacherMapper teacherMapper;
    @Override
    public Teacher getOne(Teacher record) {
        return teacherMapper.selectOne(record);
    }
}
复制代码

test包下增加TeacherService接口的测试类TeacherServiceTest

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:application.xml")
public class TeacherServiceTest {
    @Autowired
    private TeacherService teacherService;
    @Test
    public void getOne() {
        // 构造查询条件
        Teacher record = new Teacher();
        record.setGrade("三年二班");
        record.setName("stark");
        Teacher teacher = teacherService.getOne(record);
        System.out.println(teacher);
    }
}
复制代码

执行测试

b6c1f5f4f0464f0989db367004d4cb05_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

控制台输出SQL执行报错信息,可以看到执行的SQL语句中查询的表与字段与数据库中的t_teacher不一致。

通用Mapper可以通过在类名上增加@Table注解使类名和数据库表名保持一致,@Column注解可以使实体类属性和数据库字段名保持一致,使用这两个注解更改Teacher实体类

@Data
@Table(name = "t_teacher")
public class Teacher {
    private Integer id;
    @Column(name = "teacher_name")
    private String name;
    // 执教的年级
    @Column(name = "class_name")
    private String grade;
    private String address;
    private Date birthDate;
}
复制代码

再次执行测试

8936aa7299774711bf3f937cb4a762c5_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

控制台成功输出grade属性为三年二班name为stark的Teacher对象。

plus:实体类属性birthDate与表字段birth_date可以通过mybatis-config.xml中的settings标签配置开启驼峰命名转换解决。

2.4 select 相关方法与 @Id 注解

// 根据实体中的属性值进行查询,返回List列表,查询条件使用等号
List<T> select(T record);
// 查询全部结果,返回List列表
List<T> selectAll();
// 根据实体中的属性查询总数,返回int类型,查询条件使用等号
int selectCount(T record);
// 根据主键字段进行查询,方法参数必须包含完整的主键属性,返回一个实体类,查询条件使用等号
T selectByPrimaryKey(Object key);
// 根据主键字段查询总数,方法参数必须包含完整的主键属性,返回True或者False查询条件使用等号
boolean existsWithPrimaryKey(Object key);
复制代码

2.4.1 测试 selectByPrimaryKey 方法

在PorscheService和PorscheServiceImpl中定义和实现方法getPorscheById

Porsche getPorscheById(Integer id);
复制代码
@Override
public Porsche getPorscheById(Integer id) {
    return porscheMapper.selectByPrimaryKey(id);
}
复制代码

在PorscheServiceTest类中增加getPorscheById测试方法

@Test
public void getPorscheById(){
    Porsche porsche = porscheService.getPorscheById(2);
    System.out.println("查询到的内容为:" + porsche);
}
复制代码

执行测试

4aed541713324ac59cf5e12d06c68207_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

控制台输出查询的内容为null,并且执行的SQL语句中WHERE子句后面跟了全部属性作为条件,跟预想的以por_id作为查询条件不同。这是因为实体类中属性中没有显示的标注哪个属性对应数据库中的主键,通用Mapper把所有的字段集合起来当成了一个联合主键

在Porsche实体类上的por_id属性上增加@Id注解,再次执行测试

5a4b4202095f4fd3be6a9a032a94ab45_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

数据库表的主键与实体类中的por_id属性对应起来,成功查询出数据

2.4.2 测试 existsWithPrimaryKey 方法

在PorscheService和PorscheServiceImpl中定义和实现方法isExists

Boolean isExists(Integer id);
复制代码
@Override
public Boolean isExists(Integer id) {
    return porscheMapper.existsWithPrimaryKey(id);
}
复制代码

在PorscheServiceTest类中增加isExists测试方法

@Test
public void isExists(){
    Integer id = 30;
    Boolean exists = porscheService.isExists(id);
    System.out.println("是否存在主键为" + id + "的记录:" + exists);
}
复制代码

执行测试

c0dce86567a64dd3967160efb830bfd5_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

查看控制台输出的SQL语句,通用Mapper根据count函数计算查询到的个数,如果为0就不存在返回False,如果为1就存在返回True。


相关文章
|
2月前
|
SQL Java 数据库连接
Mybatis系列之 Error parsing SQL Mapper Configuration. Could not find resource com/zyz/mybatis/mapper/
文章讲述了在使用Mybatis时遇到的资源文件找不到的问题,并提供了通过修改Maven配置来解决资源文件编译到target目录下的方法。
Mybatis系列之 Error parsing SQL Mapper Configuration. Could not find resource com/zyz/mybatis/mapper/
|
1月前
|
SQL XML Java
mybatis :sqlmapconfig.xml配置 ++++Mapper XML 文件(sql/insert/delete/update/select)(增删改查)用法
当然,这些仅是MyBatis功能的初步介绍。MyBatis还提供了高级特性,如动态SQL、类型处理器、插件等,可以进一步提供对数据库交互的强大支持和灵活性。希望上述内容对您理解MyBatis的基本操作有所帮助。在实际使用中,您可能还需要根据具体的业务要求调整和优化SQL语句和配置。
30 1
|
2月前
|
XML Java 数据库连接
Mybatis 模块拆份带来的 Mapper 扫描问题
Mybatis 模块拆份带来的 Mapper 扫描问题
33 0
|
3月前
|
SQL
自定义SQL,可以利用MyBatisPlus的Wrapper来构建复杂的Where条件,如何自定义SQL呢?利用MyBatisPlus的Wrapper来构建Wh,在mapper方法参数中用Param注
自定义SQL,可以利用MyBatisPlus的Wrapper来构建复杂的Where条件,如何自定义SQL呢?利用MyBatisPlus的Wrapper来构建Wh,在mapper方法参数中用Param注
|
3月前
|
Java 数据库连接 Maven
Private method ‘getVideoList()‘ is never used,mybatis必须指定Mapper文件和实体目录,在参考其他人写的代码,要认真分析别人的代码,不要丢失
Private method ‘getVideoList()‘ is never used,mybatis必须指定Mapper文件和实体目录,在参考其他人写的代码,要认真分析别人的代码,不要丢失
|
4月前
|
SQL Java 数据库连接
Mybatis如何使用mapper代理开发
Mybatis如何使用mapper代理开发
|
4月前
|
XML 关系型数据库 数据库
使用mybatis-generator插件生成postgresql数据库model、mapper、xml
使用mybatis-generator插件生成postgresql数据库model、mapper、xml
342 0
|
4月前
|
SQL Java 数据库连接
Mybatis中一对多mapper配置
Mybatis中一对多mapper配置
|
4月前
|
Java 数据库连接 mybatis
Mybatis mapper动态代理解决方案
该文介绍了Mybatis中使用Mapper接口的方式代替XML配置执行SQL。Mapper接口规范包括:namespace与接口类路径相同,select ID与接口方法名一致,parameterType和方法参数类型匹配,resultType与返回值类型一致。实现过程中,需配置Mapper.xml,编写Mapper.java接口,并在Mybatis-config.xml中设置。测试类中,通过SqlSession的getMapper方法获取接口的动态代理对象,调用方法执行SQL。
|
4月前
|
Java 数据库连接 mybatis
为什么Mybatis Mapper不需要实现类?
在学习Java动态代理之前,我想让大家先思考这样几个问题。 • JDK动态代理为什么不能对类进行代理? • Mybatis Mapper接口为什么不需要实现类? 如果你还不知道上述问题的答案,那么这篇文章一定能消除你心中的疑惑。