一、Mybatis简介
1、Mybatis执行步骤
- 读取配置文件
mybatis-config.xml
,主要是获取数据库连接和运行环境信息 - 加载映射文件mapper.xml,也就是sql映射文件,需要在mybatis-config.xml中加载才能被执行。
- 创建SqlSessionFactory
- 根据SqlSessionFactory创建SqlSession
- 使用SqlSession对象操作数据库,包括增删改查和事务提交
- 关闭SqlSession
二、Mybatis与Maven整合
1、Maven 依赖
org.mybatis
mybatis
3.5.9
mysql
mysql-connector-java
8.0.27
2、mybatis配置文件
src/man/resources/mybatis-config.xml
3、工具类
package org.example.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
// 获取sqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
// 获取SqlSession实例,SqlSession包含了面向数据库执行SQL命令所需的所有方法
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession(true);
}
}
4、Mapper接口
package org.example.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.example.model.SjddSjsctz;
import java.util.List;
@Mapper
public interface SjddSjsctzMapper {
List selectAll();
}
5、Mapper.xml
6、mapper读取数据
@Test
public void testMybatis() {
// 第一步:获得SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
// 第二部:getMapper
SjddSjsctzMapper sjddSjsctzMapper = sqlSession.getMapper(SjddSjsctzMapper.class);
for (SjddSjsctz sjddSjsctz : sjddSjsctzMapper.selectAll()) {
System.out.println(sjddSjsctz);
}
// 第三步:关闭SslSession
sqlSession.close();
}
三、简单CURD操作
1、增、删、改、查 示例
// 一、查询:可以传bean、map、@param修饰的一个或多个参数、顺序传的单个或多个参数
List selectAll();
// 二、插入:可以传bean、map、@param修饰的一个或多个参数、顺序传的单个或多个参数
// id自增,可以手动指定一个id传进去,也可以不传
int insertOne(Map map);
2、模糊查询
两种方式
// Java代码里的模糊查询参数,传递通配符%%
List userList = mapper.getUserLike("%李%");
select * from user where username like '#{username}';
List userList = mapper.getUserLike("李");
select * from user where username like concat('%',#{username},'%');
3、批量插入
@Test
public void testInsert() throws Exception {
SqlSession sqlSession = MybatisUtils.sqlSessionFactory.openSession(ExecutorType.BATCH);
SjddSjsctzMapper mapper = sqlSession.getMapper(SjddSjsctzMapper.class);
for (int i = 0; i < 10; i++) {
User user = new User();
user.setUsername(UUID.randomUUID().toString());
user.setPassword(UUID.randomUUID().toString());
mapper.insertMany(user);
}
sqlSession.commit();
}
4、返回自增主键
当使用insert或update语句时,返回语句影响记录的自增主键值。
-
useGenerateKeys="true/false"
这回让MyBatis使用JDBC的getGenerateKeys方法,来取出由数据库内部生成的主键,默认false。如果设置为 true,将强制使用自动生成主键。 -
keyProperty="id"
,指定返回自增主键的值,将自增主键值赋予入参值实体类的id
属性。
User user = new User();
user.setUsername("username");
user.setPassword("password");
user.setRoles("roles");
user.setEnable((byte) 1);
int i = mapper.insertOne(user);
System.out.println(i);
System.out.println(user.getId()); // 得到返回的主键
int insertOne(User user);
-- 将主键返回给传来的user对象的id属性
insert into user(username, password,enable, roles)
values (#{username}, #{password}, #{enable}, #{roles});
5、SQL执行结束的返回值
- insert、delete、update语句:
用int返回类型,返回执行的SQL语句影响的记录条数,若果是0则表示没有做更改。
- select语句的返回值类型如下:
使用查询语句执行后,数据库返回的实际类型。
- List/map
- javabean
- resultMap
6、mapper.xml接收的参数类型
(1)parameterType
- 接收单个参数,参数类型为基本类型/包装类型时,mapper.xml里的参数名可以随便写都能取到值:#{xx}
- 接收多个参数,参数类型为基本类型/包装类型时,写入对应的参数名;或者按照顺序写#{0}...#{n}
- 接收map、或实体类,mapper.xml里的参数名要和map的key或实体类里的属性名相对应。
int addUser(Map);
insert into sjdd_sjsctz (id, name, password) values(#{name},#{password}) ;
Map map = new HashMap();
map.put("name", "admin");
map.put("password", "123456");
mapper.addUser(map);
(2)parameterMap
用的比较少
7、mapper.xml返回的参数类型
这里的返回参数,一般是select语句用到的返回数据的参数类型。
(1)resultType
- 返回实体类
- 返回map
- 单字段返回基础类型
(2)resultMap
简单用法是解决表字段与实体类属性不一致的问题。
- 方式一:查询语句起别名
- 方式二:返回值类型设置成:
resultMap
四、复杂查询
1、动态SQL
(1)if
(2)foreach
- 查询
- 批量插入
ArrayList
int insertMany(List list);
insert into user(username, password) values
(#{item.username}, #{item.password})
(3)choose、when、otherwise
(4)set
待补充。。。。
2、多表查询
多表查询,xml里返回类型需要用resultMap,自定义返回的字段,对一使用association,对多使用collection。实体类里要加入对一的属性。
- 关联-association【对一】
- 集合-collection 【对多】
javaType 用来指定实体类中属性的类型
ofType 用来指定映射到List或集合中的pojo类型,泛型中的约束类型
(1)一对一
一对一的,使用resultMap和association。可以对javabean添加属性也可以
- 假设一个Article对应一个Author,Article里存放Author的id。在Article的实体类里,增加Author。
@Data
public class Article {
private String articleId;
private String title;
private Integer authorId;
// 加入需要关联的实体类
private Author author;
}
- 编写resultMap
- 编写查询语句
(2)一对多
- 一的实体类
@Data
public class Article {
private String articleId;
private String title;
private Integer authorId;
// 加入需要关联的实体类
private Author author;
// 需要关联的一对多的评论
private List remarks;
}
- resultMap
- SQL语句
- 查询结果
[Article(articleId=1, title=葵花宝典, authorId=1, author=Author(id=1, author=黄药师), remarks=[Remark(id=1, cont=良心教程, articleId=1)])]
除了使用resultMap + collection外,也可以在程序中进行多次查询。
(3)多对一
待补充。。。。
五、mybatis-config.xml 配置
1、属性(properties)
这些属性可以在外部进行配置,并可以进行动态替换。既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。例如:
mybatis-config.xml
database.properties (注意,数据库名用中文报错)
driver = "com.mysql.cj.jdbc.Driver"
url = "jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8"
username = "root"
password = "root"
2、类型别名(typeAliases)
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写,例如:
- 单个别名分别配置:
- 扫描包整个model包
会使用包内 Bean 的首字母小写的非限定类名来作为它的别名,首字母大写也支持。有注解则优先使用注解
- 注解:
@Alias("xxx")
@Alias("author")
public class Author{
...
}
配置完别名之后,才能将resultType="com.example.Modle.Author"
变为 resultType="Author"
3、设置(settings)
(1)驼峰命名转换
默认false,不进行转换。开启后将数据库字段的column_table与实体类的columnTable进行自动对应,这样查出来的数据才能赋给实体类。
(2)日志打印
- STDOUT_LOGGING
- LOG4J
(3)字段为null时处理
默认false,当查询一条记录,某个字段为null时,是否调用映射对象的 setter(map 对象时为 put)方法,默认mybatis不会处理这一字段,也就是不会调用null赋值给返回的对象。
(4)返回null的处理
默认false,当查询到记录,但返回行的所有列
都是null时,MyBatis默认返回 null对象,而不会创建返回对象,当调用返回对象的方法时,容易导致空指针错误。
当开启这个设置时,MyBatis会创建返回对象,但对象是一个null实例,返回的实体类对象的所有属性都是null。
注意:如果表为空,或者根据条件查找不到记录,必定会返回null或空列表[]
上述设置只适用于,当mybatis查找到了表记录,但是返回的列全是null的时候。如果返回的列,不是全部为null,则会正常创建返回对象。
六、缓存
1、一级缓存:
默认开启,存在于SqlSession的生命周期中,什么是SqlSession的生命周期呢,简单的来说,只有同一个请求才会是同一个SqlSession,那么就是说只有同一个请求我查询第二次这个缓存才会生效。
2、二级缓存:
也称为全局缓存,存在于SqlSessionFactory 的生命周期中,可以理解为跨sqlSession;缓存是以namespace为单位的,不同namespace下的操作互不影响,但是在多人开发的环境下,我的不同的namespace完全是有可能操作同一张表的,那么会导致一个namespace的数据修改了一张表,但是另一个namespace的那张表的数据缓存没被修改,这样查询的数据就会错误。
- 开启方式:在Mapper.xml里添加
即可
七、使用注解开发
@select("select * frome user")
List getUsers();
@select("select * from user where id = #{id}")
User findById(@Param("id") long id);
@Insert("insert into user(id,name,password) values(#{id},#{name},#{password})")
int addUser(User user);
@Update("update user set name=#{name},password=#{password} where id = #{id}")
int updateUser(User user);
@Delete("delete from user where id = #{id}")
int delete(@Param("uid") int id);
mybatis-config.xml
八、Mybatis与Spring整合
待补充。。。。
九、Mybatis与SpringBoot整合
待补充。。。。