admin 管理员组

文章数量: 1184232


2023年12月24日发(作者:向量知识点与公式总结)

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

MyBatis基础

对原声jdbc程序(单独使用jdbc开发)问题总结

MyBatis入门程序

用户的增、删、改、查

MyBatis开发dao两种方法

原始dao开发(编写dao接口和dao实现类)

MyBatis的mapper(相当于dao接口)代理开发方法

MyBatis配置文件

MyBatis核心

Mybatis输入映射

MyBatis输出映射

Mybatis的动态sql

订单商品数据模型分析

高级结果集映射(一对一、一对多、多对多)

MyBatis延迟加载

MyBatis查询缓存(一级缓存、二级缓存)

MyBatis和Spring整合

MyBatis逆向工程

1 对原生jdbc程序中问题总结

1.1 环境

Java环境:jdk1.7

eclipse:

MySQL:

通过导入脚本,创建数据库和数据。

表结构。

测试数据,在企业开发中,最后提供一个初始化数据脚本。

1.2 jdbc程序

使用jdbc查询MySQL数据库中的用户表的记录。

1

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

创建Java工程,添加数据库驱动jar包。

注意:import导入包下的接口。不同的数据库驱动会对这些接口有不同的实现(多态,面向接口编程)。

import ;

import ;

import ;

import ;

/**

* 通过jdbc程序,总结其中的问题

*

* @author ZBRUI

*

*/

public class JdbcTest {

try {

// 加载数据库驱动

e("");

// 获取数据库连接

connection = nection(

"jdbc:", "zbrui", "zbrui");

// 定义sql语句,使用?占位符

String sql = "select * from user where username = ?";

// 获取预处理Statement

preparedStatement = eStatement(sql);

// 设置参数,占位符从1开始编号

ing(1, "小红");

// 想数据库发出sql执行查询,查询得到结果集

resultSet = eQuery();

// 遍历结果集

while (()) {

"id") + ", "

+ ing("username"));

public static void main(String[] args) {

// 数据库连接

Connection connection = null;

// 预编译的Statement

// 使用预编译的Statement可以提高数据库的性能

PreparedStatement preparedStatement = null;

// 结果集

ResultSet resultSet = null;

2

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

}

}

}

}

tackTrace();

// 释放资源

if (resultSet != null) {

}

// Statement

if (preparedStatement != null) {

}

// Connection

if (connection != null) {

}

try {

}

();

tackTrace();

} catch (Exception e) {

try {

}

();

tackTrace();

} catch (Exception e) {

try {

}

();

tackTrace();

} catch (Exception e) {

} catch (Exception e) {

} finally {

1.3 问题总结

1. 数据库连接,使用时创建,不适用就立即释放,对数据库进行频繁的连接开启和关闭,造成数据库资源的浪费,影响数据库性能。

解决方案:使用数据库连接池来管理数据库连接。

2. 将sql硬编码到Java代码中,如果要修改sql语句,需要重新编译Java代码,不利于系统维护。

设想:将sql语句配置在xml配置文件中,及时sql变化,不需要对Java代码进行重新编译。

3

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

3. 想preparedStatement中设置参数,对占位符号和设置参数数值,硬编码在Java代码中,不利于系统维护。

设想:将sql语句及占位符和参数配置在xml配置文件中。

4. 从resultSet结果集中遍历结果集数据时,将获取表的字段进行硬编码,不利于系统维护。

设想:将查询结果自动映射为Java对象。

2 Mybatis框架

2.1 Mybatis是什么?

Mybatis是一个持久层框架,还Apache下的定级项目。

Mybatis托管到Googlecode下,后来托管到github下(

Mybatis让程序将主要精力放在sql上,通过mybatis提供的映射方式,自由灵活的生成(半自动化,大不分需要程序眼编写sql)满足需求的sql语句。

Mybatis可以想preparedStatement中的输入参数自动进行输入映射,将查询结果集灵活映射成Java对象(输出映射)。

2.2 Mybatis框架

4

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

3 入门程序

3.1 需求分析和环境

需求:

根据用户id(主键)查询用户信息

根据用户名模糊查询用户信息

添加用户

删除用户

更新用户

环境:

Java:1.7

Eclipse:

5

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

MySQL:

MyBat(jar):3.2.7

mybatis:核心包

cglib:动态代理

log4j ,slf4j:日志

mysql-connection:数据库驱动

junit,hamcrest:Junit测试及其依赖包

3.2 ties

配置日志log4j

### set log levels - error, info, debug ###

gger=debug, stdout

### direct log messages to stdout ###

%5p %c{1}:%L - %m%n

### direct messages to file ###

%5p %c{1}:%L - %m%n

3.3 工程结构

新建source folder,保存配置文件。

Sqlmap包放映射文件。

6

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

3.4

配置MyBatis环境,配置数据源、事务、映射文件等。

与Spring整合之后大多数配置将省略。

约束DTD是configuration。

"/">

7

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

3.5 根据用户id(主键)查询用户

根据用户id(主键)查询一条用户信息。

3.5.1 创建pojo

属性名和表中字段名对应。

public class User {

}

private int id;

private String username;

private String sex;

private Date birthday;

private String address;

// get/set

3.5.2 映射文件

映射文件名:

(原始iBatis命名方式),mapper代理开发映射文件名叫。例如。

在映射文件中配置sql语句。

8

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

约束DTD是configuration。

"/">

resultType表示将单条记录映射成的Java对象 -->

是简单类型,参数名可以是value或其他名称 -->

能引起sql注入。如果传入的是简单类型,参数名只能使用value。 -->

3.5.3 在中加载映射文件

9

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

3.5.4 程序代码

返回一条记录,使用selectOne()方法。

// 根据id查询用户信息,得到一条记录结果

@Test

public void findUserByIdTest() throws Exception {

}

String resource = "";

InputStream config = ourceAsStream(resource);

// 创建会话工厂

SqlSessionFactory sqlSessionFactory = new

.build(config);

SqlSessionFactoryBuilder()

// 通过工厂得到SqlSession

SqlSession sqlSession = ssion();

// 通过SqlSession操作数据库

// 第一个参数:映射文件中statement的id,namespace+Statement的id

// 第二个参数:parameterType类型的参数

// 返回值:resultType类型的结果

User user = One("erById", 1);

;

// 释放资源

();

3.6 根据用户名模糊查询用户信息

根据用户名模糊查询用户信息。

3.6.1 映射文件

10

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

3.6.2 程序代码

返回多条,使用selectList()方法。

// 根据用户名查询用户信息

@Test

public void findUserByUsernameTest() throws Exception {

}

String resource = "";

InputStream config = ourceAsStream(resource);

// 创建会话工厂

SqlSessionFactory sqlSessionFactory = new

.build(config);

SqlSessionFactoryBuilder()

// 通过工厂得到SqlSession

SqlSession sqlSession = ssion();

// 通过SqlSession操作数据库

// selectList返回多条记录

List users = sqlSession

.selectList("erByUsername", "小");

for (User u : users) {

}

// 释放资源

();

;

3.7 添加用户

添加一条用户信息。

3.7.1 映射文件

中配置添加用户的Statement。

11

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

insert into user(id, username, birthday, sex, address)

value(#{id}, #{username}, #{birthday}, #{sex}, #{address})

3.7.2 程序代码

通过insert添加用户,这里需要提交事务。

// 根据用户名查询用户信息

@Test

public void insertUserTest() throws Exception {

}

String resource = "";

InputStream config = ourceAsStream(resource);

// 创建会话工厂

SqlSessionFactory sqlSessionFactory = new

.build(config);

SqlSessionFactoryBuilder()

// 通过工厂得到SqlSession

SqlSession sqlSession = ssion();

// 通过SqlSession操作数据库

User user = new User();

rname("张六");

thday(new Date());

("M");

int cou = ("User", user);

;

// 提交事务

();

// 释放资源

();

3.7.3 获取自增主键

应用场景,插入记录后,需要将主键作为其子表的外键添加到数据库中。

MySQL自增主键,执行insert提交之前自动生成一个自增主键。

通过MySQL函数获取自增主键:LAST_INSERT_ID()

注意:Insert之后调用这个函数。

12

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

select LAST_INSERT_ID()

insert into user(id, username, birthday, sex, address)

value(#{id}, #{username}, #{birthday}, #{sex}, #{address})

键 -->

3.7.4 获取非自增主键

使用MySQL的uuid()函数生成主键:

需要修改表中id字段类型为String,长度为32。

执行思路:

1. 先通过uuid()查询到主键。

2. 将查询到的主键设置到到parameterType对象的id中。

3. 在执行insert时,从parameterType对象中取出id属性值。

注意:执行uuid()相对于insert应当是BEFORE,即在insert之前生成主键。

通过Oracle序列生成的主键:

序列名.next()

其余类似。

3.8 删除用户

根据用户id删除一条用户。

13

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

3.8.1 映射文件

update user

set username = #{username}, birthday = #{birthday}, sex = #{sex},

where id=#{id}

address = #{address}

3.8.2 程序代码

使用delete方法

需要提交事务

3.9 更新用户

3.9.1 映射文件

delete

from user

where id=#{id}

3.9.2 程序代码

使用update方法

需要提交事务

14

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

3.10 总结

3.10.1 parameterType

指定输入参数类型,简单类型或包装类型pojo。

3.10.2 resultType

指定sql输出结果的映射的Java对象类型,select自定resultType表示将单条记录映射成的Java对象。

3.10.3 #{}和${}

#{}:表示占位符,其中的id表示接收输入的参数,类型可以是简单类型、pojo、HashMap等。

 如果输入参数是简单类型,参数名可以是value或其他名称 。

 如果输入参数是pojo对象只,通过OGNL(对象导航图)获取对象中的属性值,通过“属性.属性…”的方式获取对象属性值。

${value}:表示拼接sql串,将接收到的参数内容不加任何修饰拼接在sql中,可能引起sql注入。

与#{}用法类似。区别是如果传入的是简单类型,参数名只能使用value。

3.10.4 selectOne和selectList

selectOne:查询出一条结果进行映射。也可以用selectList实现。

selectList:查询出多条记录进行映射。如果插叙结果返回多条记录,不能使用selectOne。

3.11 MyBatis和Hibernate本质区别和应用场景

Hibernate:

15

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

是一个标准的ORM框架(对象关系映射)。入门门槛较高,不需要程序写sql,sql语句自动生成了。

对sql语句进行优化、修改比较困难。

应用场景:使用于需求变化不多的中小型项目。例如,后台管理系统、ERP、ORM、OA等。

MyBatis:

专注sql本身,需要编写sql语句,sql修改、优化比较方便。MyBatis是一个不完全的ORM框架,虽然程序员自己写sql,MyBatis也可以实现映射(输入映射、输出映射)。

应用场景:变化较多的项目。例如,互联网项目。

企业进行技术选型,以低成本高回报作为技术选型的原则,根据项目组的技术力量进行选择。

4 MyBatis开发DAO的方法

4.1 SqlSession使用范围

SqlSession最佳应用场合在方法体内部,定义成局部变量使用。

4.1.1 SqlSessionFactoryBuilder

通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory,将SqlSessionFactoryBuilder当成一个工具类使用即可,不需要使用单例模式管理SqlSessionFactoryBuilder。

在需要创建SqlSessionFactory的时候,只需要创建一次SqlSessionFactoryBuilder即可。

4.1.2 SqlSessionFactory

通过SqlSessionFactory创建SqlSession,使用单例模式来管理SqlSessionFactory(一旦创建,使用一个实力)。将来MyBatis和Spring整合后,使用单例模式管理SqlSessionFactory

4.1.3 SqlSession使用范围

SqlSession是一个面向用户的接口。

SqlSession提供了很多操作数据库的方法。例如,selectOne()方法返回单个对象、selectList()方法返回多个对象、commit()方法提交事务等等。

SqlSession是线程不安全的,在SqlSession实现类中除了有接口中的方法(操作数据库的方法)还有数据域属性。

16

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

SqlSession最佳应用场合在方法体内部,定义成局部变量使用。

4.2 原始DAO开发

需要编写DAO接口和DAO实现类。

4.2.1 思路

需要向DAO实现类中注入SqlSessionFactory,在方法体内通过SqlSessionFactory创建SqlSession。

4.2.3 DAO接口

方法使用throws关键字抛出异常,健壮性。

package ;

import ;

import ;

public interface UserDao {

/**

* 根据用户名模糊查询用户

*

* @param id

* @return

* @throws Exception

/**

* 根据用户id查询用户

*

* @param id

* @return

* @throws Exception

*/

public User findUserById(int id) throws Exception;

17

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

}

/**

* 根据用户id删除一条用户信息

*

* @param id

* @return

* @throws Exception

*/

public int deleteUser(int id) throws Exception;

/**

* 添加一条用户信息

*

* @param user

* @return

* @throws Exception

*/

public int insertUser(User user) throws Exception;

*/

public List findUserByUsername(String username) throws

Exception;

4.2.3 DAO接口实现类

package ;

import ;

import ;

import ;

import ;

import ;

public class UserDaoImpl implements UserDao {

// 向DAO实现类注入SqlSessionFactory

// 这里通过构造方法注入

private SqlSessionFactory sqlSessionFactory;

18

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

}

@Override

public int deleteUser(int id) throws Exception {

}

SqlSession sqlSession = ssion();

int cou = ("UserById", id);

(); // 提交事务

(); // 释放资源

return cou;

@Override

public int insertUser(User user) throws Exception {

}

SqlSession sqlSession = ssion();

int cou = ("User", user);

(); // 提交事务

(); // 释放资源

return cou;

@Override

public List findUserByUsername(String username) throws

}

SqlSession sqlSession = ssion();

List users =

username);

@Override

public User findUserById(int id) throws Exception {

}

SqlSession sqlSession = ssion();

User user = One("erById", 2);

(); // 释放资源

return user;

public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {

}

sionFactory = sqlSessionFactory;

Exception {

List("erByUsername",

(); // 释放资源

return users;

19

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

4.2.4 测试代码

package ;

import ;

import ;

import ;

import ;

import ;

import ;

import ;

import ;

public class UserDaoImplTest {

}

@Test

public void findUserByIdTest() throws Exception {

}

// 创建UserDao对象

UserDao userDao = new UserDaoImpl(sqlSessionFactory);

// 调用UseDao方法

User user = erById(2);

// 输出显示

;

@Before

public void setUp() throws Exception {

}

String resource = "";

InputStream config = ourceAsStream(resource);

// 创建会话工厂

sqlSessionFactory = new

private SqlSessionFactory sqlSessionFactory;

SqlSessionFactoryBuilder().build(config);

20

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

4.2.5 原始DAO开发的问题

1. dao接口实现类方法中存在大量模板方法,设想是否能将这些母版方法提取出来,大大减少程序员工作量。

2.调用SqlSession方法时,将Statement额id硬编码了。

3.调用SqlSession方法时,由于SqlSession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于开发。

4.3 Mapper代理开发DAO

4.3.1 思路和Mapper代理开发规范

开发接口和配置文件,并在MyBatis配置文件中加载。

开发过程需要遵循一些规范:

MyBatis可以自动生成mapper接口实现类代理对象。

1. 在中namespace等于mapper接口地址

2. 接口中的方法名和中Statement的id一致。

3. 接口中方法输入参数类型和中Statement的parameterType指定的类型一致

4. 接口中方法的返回值得类型和映射文件中Statement的resultType指定的类型一致。

例如,

中:

public User findUserById(int id) throws Exception;

中:

总结,以上尅发规范主要是对下面的代码进行统一生成:

User user = One("erById", 2);

int cou = ("User", user);

……

21

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

4.3.2

public interface UserMapper {

}

public User findUserById(int id) throws Exception;

public List findUserByUsername(String username) throws

public int insertUser(User user) throws Exception;

public int deleteUser(int id) throws Exception;

Exception;

4.3.3

"/">

resultType="">

SELECT * FROM user WHERE username LIKE '%${value}%'

resultType="">

SELECT * FROM user WHERE id=#{id}

22

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

update user

set username = #{username}, birthday = #{birthday}, sex =

where id=#{id}

delete

from user

where id=#{id}

select LAST_INSERT_ID()

insert into user(id, username, birthday, sex, address)

value(#{id}, #{username}, #{birthday}, #{sex}, #{address})

#{sex}, address = #{address}

注意,要在MyBatis配置未见中加载配置文件。

4.3.4 在中加载

23

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

4.3.5 测试

@Test

public void findUserByIdTest() throws Exception {

}

// 通过SqlSessionFactory得到SqlSession

SqlSession sqlSession = ssion();

// 创建UserMapper对象

UserMapper userMapper = per();

// 调用UseMapper方法

User user = erById(2);

// 输出显示

;

4.3.6 总结

代理对象内部调用SelectOne或SelectList

如果mapper方法返回单个poji对象(非集合对象),代理对象内部通过selectOne查询数据库。

如果mapper方法返回集合对象,代理对象内部通过selectList查询数据库。

Mapper接口方法参数只能有一个是否影响系统开发

Mapper接口方法参数只能有一个,是否不利于扩展维护。

系统中,dao层代码是被业务层公用的。

即使mapper接口只有一个参数,可以使用包装类型的pojo满足不同业务方法的需求。

注意:持久层方法的参数可以使用包装类型(list、set、map等),但是service方法中建议不要使用包装类型(不利于业务层的可扩展)。

24

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

5

5.1 properties属性

需求:

将数据库连接参数单独配置在ties中,只需要在SqlMapConfig中加载ties的属性值,在中就不需要对数据库连接参数硬编码。

将数据库了解参数只配置在ties中,原因:方便对参数进行统一管理,其他xml可以引用这个ties。

1. ties

2. 加载配置文件

3. 测试,包括正常测试可异常测试。

Properties特性:

注意,MyBatis加载属性的顺序。

1. 在properties元素(xml配置文件的标签)体内定义的属性首先被读取。

2. 然后,读取properties元素中resource或url加载的属性,他会覆盖已经读取的同名属性。

3. 最后,读取parameterType传递的属性,他会覆盖已经读取的同名属性。

一个bug,在中Statement中传入参数parameterType使用占位符“${name}”来绑定,但是ties文件中定义了属性名“name”,最终读取到了ties文件中的“name”属性值。

建议:

不要在properties元素体内添加任何属性

只将属性值定义在properties文件中

在properties文件中定义属性名要有一定的特殊性。例如,

5.2 settings(配置)

MyBatis全局配置参数,全局参数将会影响MyBatis的运行行为。

25

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

5.3 typeAliases(别名)

5.3.1 需求

在中,定义很多的statement,statement需要parameterType指定输入参数的类型、需要resultType指定输出结果的映射类型。

如果在知道哪个类型是输入类型全路径,不方便开发,可以针对parameterType或resultType指定的类型定义别名,在映射文件中通过别名定义,方便开发。

5.3.2 MyBatis默认支持的别名

有基本数据类型等。

(列表略)……

5.3.3 自定义别名

单个别名定义:

使用typeAlias元素,type指定类型路径,alias指定别名。

批量定义别名:

使用package元素,那么指定包名,MyBatis自动扫描包中的po类并自动定义别名,别名就是类名(使用时首字母大写或小写都可以,一般使用首字母小写)。

定义多个包,可以使用多个package元素。

26

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

引用别名:

测试(正常测试和异常测试):

Junit测试。

5.4 typeHandlers(类型处理器)

MyBatis中通过typeHandlers完成jdbc类型和Java类型的映射。MyBatis自带的类型处理器基本上满足日常需求,不需要单独定义。

MyBatis支出的类型处理器:

(列表略)……

5.5 Mapper(映射配置)

5.5.1 通过resource元素加载单个映射文件

5.5.2 通过mapper接口加载单个mapper

使用class方法指定接口路径,加载mapper。

需要遵循规范:

27

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

mapper接口类名和映射文件名称保持一致,且在一个目录

必须使用mapper代理方式

调整目录结构:

将放到同一个目录下,并且名称相同。

5.5.3 批量加载mapper(推荐使用)

使用package元素,name属性指定包名,MyBatis自动扫描包下所有的Mapper接口并加载。

需要遵循规范:

mapper接口类名和映射文件名称保持一致,且在一个目录

必须使用mapper代理方式

6 输入映射

28

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

通过parameterType指定输入参数的类型,类型可以是简单里诶性、HashMap、pojo的包装类型。

6.1 需求

完成用户信息的综合查询,需要传入查询条件(可能包括用户信息和其他信息,比如商品、订单等)。

6.1.2 定义包装类型pojo

针对这个需求,建议使用自定义的包装类型的pojo。在包装类型的pojo中将复杂的查询条件包装进去。

public class UserQueryVo {

}

// 包装所需要查询的条件

// 用户查询条件

private UserCustom userCustom;

// 包装其他条件

// ...

// get/set

6.1.3

在中定义用户信息综合查询(查询条件复杂,通过高级查询进行复杂关联查询)。

通过OGNL方式获取属性值。

6.1.4

接口:

public List findUserList(UserQueryVo userQueryVo) throws

Exception;

6.1.5 测试代码

创建查询条件,调用UserMapper方法,将输入参数传入。

@Test

public void findUserListTest() throws Exception {

}

// 通过SqlSessionFactory得到SqlSession

SqlSession sqlSession = ssion();

// 创建UserMapper对象

UserMapper userMapper = per();

// 创建查询条件

UserCustom userCustom = new UserCustom();

("M");

rname("小");

UserQueryVo userQueryVo = new UserQueryVo();

rCustom(userCustom);

// 调用UseMapper方法

List user = erList(userQueryVo);

// 输出显示

;

30

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

7 输出映射

7.1 resultType

使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一直,该列才可以映射成功。

如果查询出来的列名和pojo中的属性名全部都不一致,没有创建pojo对象。

只要查询出来的列名和pojo中的属性有一个一一致,就会映射到pojo对象中。

7.1.1 输出简单类型

需求:

用户信息额综合查询列表总数,通过查询总数和上边用户综合查询列表才可以实现分页。

/**

* 用户数量查询

*

* @param userQueryVo

* @return

* @throws Exception

*/

public int findUserCount(UserQueryVo userQueryVo) throws Exception;

测试代码:

Junit测试。

小结:

查询出来的结果集只有一行且一列,可以使用简单类型进行输出映射。

31

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

7.1.2 输出pojo对象和pojo列表

不管输出的是pojo单个对象还是一个列表(包括list中包括pojo),在中resultType指定的类型是一样的。

在中指定的方法返回值不一样:

1. 输出单个pojo类型,方法返回值是单个对象类型。

2. 输输pojo对象list,方法返回值是List

生成动态代理对象中是根据mapper方法的返回值类型确定是调用selectOne(返回单个对象调用)还是selectList(返回集合对象调用)。

7.1.3 输出HashMap

输出pojo对象可以改用HashMap输出类型,将输出的字段名作为map的key,输出的字段值作为map的value。

返回值是一个List,list里是返回的map。

7.2 resultMap

MyBatis中使用resultMap完成高级输出结果映射。

7.2.1 resultMap使用方法

如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间做一个映射关系。

1. 定义resultMap

2. 使用resultMap作为Statement的输出映射

7.2.2 需求

将下面sql语句使用User完成映射:select id id_, username username_ from user

where id = 2

第一步,定义resultMap

32

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

第二步,使用resultMap进行输出映射

和测试:

Mapper接口中添加方法,Junit测试。

7.3 小结

使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一直,该列才尅映射成功。

如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间做一个映射关系。

33

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

8 动态SQL

8.1 什么是动态sql

MyBatis核心对sql语句进行灵活操作,通过表达式进行判断,对送起来进行灵活拼接、组装。

8.2 需求

用户信息综合查询列表和用户信息查询列表总数这两个Statement的定义使用动态sql,对查询条件进行判断,如果输入参数不为空才进行查询条件的拼接。

8.3

where:

where可以自动去掉查询条件的第一个and

if:

if可以可以检测,只有满足test条件的语句才会拼接到sql中。

34

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

8.4 和测试

添加相应方法,使用Junit测试。

8.5 SQL片段

8.5.1 需求

将重复的动态sql判断代码块抽取出来,组成一个sql片段,其他的Statement就可以引用这个sql片段。

8.5.2 定义sql片段

and = #{}

and me like '%${me}%'

me != ''">

8.5.3 引用sql片段

8.5.4 测试代码

使用Junit测试。

8.6 foreach

向sql传递数组或List,MyBatis使用foreach解析。

8.6.1 需求

在用户查询列表和查询总数的Statement中增加多个id输入的查询:

select * from user where id = 1 or id = 5

select * from user where id in (1, 5)

需要使用foreach拼接结果:

and (id = 1 or id = 5)

and id in (1, 5)

8.6.2 在输入参数类型中添加List ids传入多个id

在查询条件包装类型UserQueryVo中添加List ids。

8.6.3 修改中的定义的sql片段

添加foreach遍历ids。

36

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

id=#{user_id}

separator=" or ">

8.6.4 和测试代码

添加方法,Junit测试。

37

文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.

38


本文标签: 查询 使用 映射 类型