Mybatis
什么是Mybaits
Mybatis是一款持久层框架 Mybatis避免了几乎所有的JDBC代码和手动设置参数及获取结果集的过程 Mybatis可以使用简单的XML或注解来配置和映射原生信息,将接口和Java的实体类映射成数据库中的记录
持久化
将程序数据在持久状态和瞬时状态间转换的机制 把数据保存到可永久保存的存储设备中。持久化的主要应用是将内存中的对象存储在数据库中,或者存储在磁盘文件、xml数据文件中。
持久层
完成持久化工作的代码块(dao层 数据访问对象),用来操作数据库
Mybatis第一个程序:
思路流程:搭建环境>导入Mybatis>编写代码>测试
1.搭建数据库
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int NOT NULL,
`name` varchar(30) DEFAULT NULL,
`pwd` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
insert into `user`(`id`,`name`,`pwd`) values (1,'QQQ','123456'),(2,'WWW','abcdef'),(3,'EEE','987654');
2.导入Mybatis依赖
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.24</version>
</dependency>
3.编写mybatis核心配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="com.wwz.pojo"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/wwz/dao/UserMapper.xml"/>
</mappers>
</configuration>
4.User实体类、定义接口(CRUD),编写配置文件
public class User {
private Integer id;
private String name;
private String pwd;
}
public interface UserMapper {
List<User> selectUser();
User selectUserById(int id);
User selectUserNP(@Param("username") String username,@Param("pwd") String pwd);
int addUser(User user);
int deleteUserById(int id);
int upDateUser(User user);
}
xml配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wwz.dao.UserMapper">
<select id="selectUser" resultType="User">
select * from mybatis.user
</select>
<select id="selectUserById" resultType="User">
select * from mybatis.user where id =#{id}
</select>
<select id="selectUserNP" resultType="User">
select * from mybatis.user where name=#{username} and pwd=#{pwd}
</select>
<insert id="addUser" parameterType="User">
insert into user (id,name,pwd) values (#{id},#{name},#{pwd})
</insert>
<delete id="deleteUserById" parameterType="int">
delete from user where id=#{id}
</delete>
<update id="upDateUser" parameterType="User">
update user set name=#{name},pwd=#{pwd} where id=#{id}
</update>
</mapper>
5.编写Mybatis的工具类
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSession(){
return sqlSessionFactory.openSession(true);
}
}
6.测试
public class MyTest {
@Test
public void test01(){
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> users = mapper.selectUser();
for (User user : users) {
System.out.println(user);
}
session.close();
}
@Test
public void test02(){
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUserById(1);
System.out.println(user);
session.close();
}
@Test
public void testSelectUserNP(){
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUserNP("WANG","987");
System.out.println(user);
session.close();
}
@Test
public void test03(){
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
int i = mapper.addUser(new User(4, "zzz", "123123"));
if (i>0){
System.out.println("success");
}else {
System.out.println("no");
}
session.close();
}
@Test
public void test04(){
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
int i = mapper.deleteUserById(4);
if (i>0){
System.out.println("success");
}else {
System.out.println("no");
}
session.close();
}
@Test
public void test05(){
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
int i = mapper.upDateUser(new User(1, "WANG", "987"));
if (i>0){
System.out.println("success");
}else {
System.out.println("no");
}
session.close();
}
}
ResutlMap、ResutlType区别
resultType resultType可以把查询结果封装到pojo类型中,但必须pojo类的属性名和查询到的数据库表的字段名一致。
如果sql查询到的字段与pojo的属性名不一致,则需要使用resultMap将字段名和属性名对应起来,进行手动配置封装,将结果映射到pojo中
resultMap resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。
Demo
public class Admin {
private Integer id;
private String username;
private String password;
}
编写mybatis核心配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="com.wwz.pojo"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/wwz/dao/AdminMapper.xml"/>
</mappers>
</configuration>
dao接口
public interface AdminMapper {
Admin selectAdminById(int id);
}
AdminMapper.xml配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wwz.dao.AdminMapper">
<resultMap id="AdminMap" type="Admin">
<id column="id" property="id"/>
<id column="name" property="username"/>
<id column="pwd" property="password"/>
</resultMap>
<select id="selectAdminById" parameterType="int" resultMap="AdminMap">
select * from mybatis.admin where id=#{id}
</select>
</mapper>
测试
@Test
public void test(){
SqlSession session = MybatisUtils.getSession();
AdminMapper mapper = session.getMapper(AdminMapper.class);
Admin admin = mapper.selectAdminById(1);
System.out.println(admin);
session.close();
}
动态SQL
动态SQL 根据不同的查询条件,生成不同 SQL,通过 if, choose, when, otherwise, trim, where, set, foreach等标签组成灵活的SQL语句
sql 、if语句:如果title不为空,根据title查询,若为空,则根据author查询
<sql id="if-title-author">
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</sql>
<select id="queryBlogIF" parameterType="map" resultType="blog">
select * from blog
<where>
<include refid="if-title-author"/>
</where>
</select>
set语句
<update id="updateBlog" parameterType="map">
update blog
<set>
<if test="title != null">
title = #{title}, /*这里需要用,隔开*/
</if>
<if test="author != null">
author = #{author},
</if>
</set>
where id=#{id}
</update>
choose语句
<select id="queryBlogChoose" parameterType="map" resultType="blog">
select * from blog
<where>
<choose>
<when test="title != null">
title = #{title}
</when>
<when test="author != null">
and author = #{author}
</when>
<otherwise>
and views = #{views}
</otherwise>
</choose>
</where>
</select>
foreach语句
-
collection:指定输入对象中的集合属性 item:每次遍历生成的对象 open:开始遍历时的拼接字符串 close:结束时拼接的字符串 separator:遍历对象之间需要拼接的字符串
<select id="queryBlogForeach" parameterType="map" resultType="blog">
select * from blog
<where>
<foreach collection="ids" item="id" open="(" separator="or" close=")">
id=#{id}
</foreach>
</where>
</select>
mybatis缓存
一级缓存
默认开启,同一个SqlSesion级别共享的缓存,在一个SqlSession的生命周期内,执行2次相同的SQL查询,则第二次SQL查询会直接取缓存的数据,而不走数据库,当然,若第一次和第二次相同的SQL查询之间,执行了DML(INSERT/UPDATE/DELETE),则一级缓存会被清空,第二次查询相同SQL仍然会走数据库
一级缓存在下面情况会被清除:
1.在同一个SqlSession下执行增删改操作时(不必提交),会清除一级缓存
2.SqlSession提交或关闭时(关闭时会自动提交),会清除一级缓存
3.对mapper.xml中的某个CRUD标签,设置属性flushCache=true,这样会导致该MappedStatement的一级缓存,二级缓存都失效(一个CRUD标签在mybatis中会被封装成一个MappedStatement)
4.在全局配置文件中设置 ,这样会使一级缓存失效,二级缓存不受影响
二级缓存
默认关闭,可通过全局配置文件中的<settings name="cacheEnabled" value="true"/>开启二级缓存总开关,然后在某个具体的mapper.xml中增加<cache />,即开启了该mapper.xml的二级缓存。二级缓存是mapper级别的缓存,粒度比一级缓存大,多个SqlSession可以共享同一个mapper的二级缓存。注意开启二级缓存后,SqlSession需要提交,查询的数据才会被刷新到二级缓存当中
|