MyBatis是一个优秀的持久层框架,它对jdbc的操作进行了封装,使得数据库的操作不再繁琐,避免大量的代码编写,使开发人员将更多的精力放在sql语句上。
create database mybatis;
use mybatis;
CREATE TABLE user (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
pwd VARCHAR(100) DEFAULT(NULL),
PRIMARY KEY (id)
)ENGINE=Innodb,CHARSET=UTF8;
insert into user(id,name,pwd) VALUES
(1,'孙悟空','666666'),
(2,'御坂美琴','233333'),
(3,'白井黑子','123456');
<dependencies>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.10version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.33version>
dependency>
<dependency>
<groupId>org.junit.jupitergroupId>
<artifactId>junit-jupiter-apiartifactId>
<version>5.10.0version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.junit.jupitergroupId>
<artifactId>junit-jupiter-engineartifactId>
<version>5.10.0version>
<scope>testscope>
dependency>
dependencies>
package com.myLearning.pojo;
import java.io.Serializable;
public class User implements Serializable {
private int id;
private String name;
private String pwd;
public User() {
}
public User(int id, String name, String pwd) {
this.id = id;
this.name = name;
this.pwd = pwd;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<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=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/myLearning/Dao/UserMapper.xml"/>
mappers>
configuration>
package com.myLearning.util;
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 {
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
throw new RuntimeException(e);
}
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
package com.myLearning.Dao;
import com.myLearning.pojo.User;
import java.util.List;
public interface UserDao {
List<User> getUserList();
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.myLearning.Dao.UserDao">
<select id="getUserList" resultType="com.myLearning.pojo.User">
select * from user
select>
mapper>
在配置文件中配置Mapper的路径
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<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=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/myLearning/Dao/UserMapper.xml"/>
mappers>
configuration>
<build>
<resources>
<resource>
<directory>src/main/resourcesdirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>truefiltering>
resource>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>truefiltering>
resource>
resources>
build>
package com.myLearning.Dao;
import com.myLearning.pojo.User;
import com.myLearning.util.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
import java.util.List;
public class UserDaoTest {
@Test
public void test(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
List<User> userList = userDao.getUserList();
for(User user : userList){
System.out.println(user);
}
sqlSession.close();
}
}
package com.myLearning.Dao;
import com.myLearning.pojo.User;
import java.util.List;
public interface UserMapper {
// 获取所有用户列表
List<User> getUserList();
// 插入一个新的用户
int insertUser(User user);
// 更新一个用户
int updateUser(User user);
// 删除一个用户
int deleteUser(int id);
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.myLearning.Dao.UserMapper">
<select id="getUserList" resultType="com.myLearning.pojo.User">
select * from user
select>
<insert id="insertUser" parameterType="com.myLearning.pojo.User">
insert into mybatis.user(id,name,pwd) values(#{id},#{name},#{pwd})
insert>
<update id="updateUser" parameterType="com.myLearning.pojo.User">
update mybatis.user set pwd=#{pwd} where id=#{id}
update>
<delete id="deleteUser" parameterType="int">
delete from mybatis.user where id=#{id}
delete>
mapper>
package com.myLearning.Dao;
import com.myLearning.pojo.User;
import com.myLearning.util.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
import java.util.List;
public class UserMapperTest {
@Test
public void getUserListtest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = userMapper.getUserList();
for(User user : userList){
System.out.println(user);
}
sqlSession.close();
}
@Test
public void insertUserTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User(4,"上条当麻","123666");
int ret = mapper.insertUser(user);
System.out.println(ret);
// 增删改操作一定要提交事务!!!
sqlSession.commit();
sqlSession.close();
}
@Test
public void updateUserTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User(4,"上条当麻","123456789");
int ret = mapper.updateUser(user);
// 增删改需要提交事务
sqlSession.commit();
System.out.println(ret);
sqlSession.close();
}
@Test
public void deleteUserTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int ret = mapper.deleteUser(4);
sqlSession.commit();
System.out.println(ret);
sqlSession.close();
}
}
Map可以用作参数传递
// 更新一个用户(使用Map)
int updateUser2(Map<String,Object> map);
<update id="updateUser2" parameterType="map">
update mybatis.user set pwd=${mima} where id=${key}
update>
@Test
public void updateUserTest2(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String, Object> map = new HashMap<>();
map.put("mima","233333333333");
map.put("key","4");
mapper.updateUser2(map);
sqlSession.commit();
sqlSession.close();
}
mybatis-config.xml,这是MyBatis的核心配置文件,它包含了MyBatis的所有全局配置信息,如数据库连接信息、事务管理、映射文件等。
MyBatis可以配置多个环境,每个环境对应一个数据库连接。在
标签中,可以配置多个
标签,每个
标签对应一个数据库连接。
<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=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
dataSource>
environment>
<environment id="test">
<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=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
dataSource>
environment>
environments>
可以在核心配置文件中引入外部配置文件
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf-8
username=root
passward=123456
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="db.properties">
properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${passward}"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/myLearning/Dao/UserMapper.xml"/>
mappers>
configuration>
可以在核心配置文件中配置别名,方便使用
<typeAliases>
<typeAlias type="com.myLearning.pojo.User" alias="User"/>
typeAliases>
也可以使用包扫描的方式,扫描指定包下的所有类,并自动为这些类注册别名,默认别名为类名,且不区分大小写,如果需要自定义,可以在类上使用@Alias注解自定义别名
<typeAliases>
<package name="com.myLearning.pojo"/>
typeAliases>
<insert id="insertUser" parameterType="user">
insert into mybatis.user(id,name,pwd) values(#{id},#{name},#{pwd})
insert>
常用的setting配置有:mapUnderscoreToCamelCase(开启驼峰命名映射),logImpl(指定日志实现),lazyLoadingEnabled(延迟加载),aggressiveLazyLoading(是否需要立即加载),cacheEnabled(是否开启二级缓存)
mappers配置主要用于指定mybatis映射文件的位置,主要有三种方式:
<mappers>
<mapper resource="com/myLearning/Dao/UserMapper.xml"/>
mappers>
<mappers>
<mapper class="com.myLearning.Dao.UserMapper"/>
mappers>
<mappers>
<package name="com.myLearning.Dao"/>
mappers>
resultMap放在Mapper.xml中进行配置,resultMap用于自定义结果集映射,可以解决实体类属性名和数据库表字段名不一致的问题。
假设数据库表user有id、name、pwd三个字段,实体类User有id、name、password三个属性,id和name属性名一致,password属性名和数据库表字段名不一致,可以使用resultMap自定义结果集映射。
<resultMap id="userMap" type="User">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="password" column="pwd"/>
resultMap>
在select语句中可以使用resultMap属性指定resultMap的id。
<select id="getUserById" resultMap="userMap">
select * from user where id=#{id}
select>
mybatis内置了多种日志实现,可以通过在mybatis配置文件中配置logImpl属性来指定使用的日志实现,常用的日志实现有:
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
settings>
配置完后,mybatis会使用指定的日志实现来记录日志。
<dependency>
<groupId>org.apache.logging.log4jgroupId>
<artifactId>log4j-coreartifactId>
<version>2.20.0version>
dependency>
<dependency>
<groupId>org.apache.logging.log4jgroupId>
<artifactId>log4j-apiartifactId>
<version>2.20.0version>
dependency>
<Configuration status="WARN" shutdownHook="disable">
<Properties>
<Property name="LOG_HOME">./logs/Property>
<Property name="LOG_FILE_NAME">test.logProperty>
<Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%nProperty>
Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${LOG_PATTERN}"/>
Console>
<RollingFile name="RollingFile" fileName="${LOG_HOME}/${LOG_FILE_NAME}"
filePattern="${LOG_HOME}/app-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="10 MB"/>
Policies>
<DefaultRolloverStrategy max="30"/>
RollingFile>
<Async name="Async">
<AppenderRef ref="RollingFile"/>
Async>
Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
<AppenderRef ref="Async"/>
Root>
<Logger name="com.myapp" level="debug" additivity="false">
<AppenderRef ref="Console"/>
Logger>
<Logger name="org.apache" level="off" additivity="false"/>
Loggers>
Configuration>
<settings>
<setting name="logImpl" value="LOG4J2"/>
settings>
// 获取Logger对象
private static final Logger logger = LogManager.getLogger(UserMapper.class);
@Test
public void loggerTest(){
logger.info("测试log4j2的日志使用");
}
分页在mybatis中可以通过sql实现,也可以通过rowbounds实现,现在基本不再使用rowbounds进行分页了
此外,还可以使用插件进行分页
使用注解开发,可以减少配置文件,但是注解开发不能实现动态sql,所以注解开发一般用于简单的sql语句
package com.myLearning.Dao;
import com.myLearning.pojo.User;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface TestMapper {
@Select("select * from user")
public List<User> getUsers();
}
<mappers>
<mapper resource="com/myLearning/Dao/UserMapper.xml"/>
<mapper class="com.myLearning.Dao.TestMapper"/>
mappers>
其他的增删改都是一样的,只是注解不同,@Insert、@Update、@Delete
当接口中的方法参数只有一个时,可以省略@Param注解,但是当接口中的方法参数有多个时且为基本类型或String类型时,必须使用@Param注解,否则会报错
Lombok是一个Java库,可以自动生成一些常见的代码,比如getter、setter、toString、equals、hashCode等,可以减少代码量,提高开发效率
在pom.xml中添加Lombok的依赖
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.30version>
<scope>providedscope>
dependency>
在需要生成代码的类上添加注解,比如@ToString、@Getter、@Setter等,就可以自动生成对应的代码了
生成getter和setter方法
生成toString方法
生成equals和hashCode方法
生成无参构造方法
生成全参构造方法
生成getter、setter、toString、equals、hashCode、无参构造方法
生成Builder模式
生成日志对象
create table student(
id int PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(255) not null,
tid int not null,
FOREIGN KEY (tid) REFERENCES teacher(id)
)ENGINE=INNODB,CHARSET=utf8;
CREATE table teacher(
id int PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(255) not null
)ENGINE=INNODB,CHARSET=utf8;
INSERT INTO teacher(id,name) VALUES(1,"利姆露老师");
INSERT INTO student(id,name,tid) VALUES(1,"三崎剑也",1);
INSERT INTO student(id,name,tid) VALUES(2,"克萝耶.欧贝鲁",1);
INSERT INTO student(id,name,tid) VALUES(3,"盖鲁·吉普森",1);
INSERT INTO student(id,name,tid) VALUES(4,"关口良太",1);
INSERT INTO student(id,name,tid) VALUES(5,"爱丽丝·伦德",1);
package com.myLearning.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student implements Serializable {
private int id;
private String name;
private Teacher teacher;
}
package com.myLearning.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Teacher implements Serializable {
private int id;
private String name;
}
package com.myLearning.Dao;
import com.myLearning.pojo.Student;
import java.util.List;
public interface StudentMapper {
List<Student> getAllStudent();
}
package com.myLearning.Dao;
import com.myLearning.pojo.Teacher;
import java.util.List;
public interface TeacherMapper {
List<Teacher> getAllTeacher();
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.myLearning.Dao.StudentMapper">
<select id="getAllStudent" resultMap="StudentTeacher">
select * from student;
select>
mapper>
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.myLearning.Dao.TeacherMapper">
<select id="getAllTeacher" resultType="teacher">
select * from teacher;
select>
mapper>
<mappers>
<mapper resource="com/myLearning/Dao/StudentMapper.xml"/>
<mapper resource="com/myLearning/Dao/TeacherMapper.xml"/>
mappers>
这里使用多一种查询的方式完成,即在另一个查询中获得teacher的信息,然后使用resultMap进行映射,其中teacher的属性使用association进行映射
association中的select制定了查询teacher的sql语句,column制定了查询teacher的id,property制定了查询teacher的属性
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.myLearning.Dao.StudentMapper">
<resultMap id="StudentTeacher" type="Student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<association property="teacher" column="tid" javaType="Teacher" select="getAllTeacher"/>
resultMap>
<select id="getAllStudent" resultMap="StudentTeacher">
select * from student;
select>
<select id="getAllTeacher" resultType="Teacher">
select * from teacher where id=#{tid};
select>
mapper>
我们也有另一种方法完成任务,就是直接在一个select语句中完成查询,获得构建对象所有需要的信息,使用resultMap进行映射,其中teacher的属性使用association直接进行映射
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.myLearning.Dao.StudentMapper">
<resultMap id="StudentTeacher" type="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacher" javaType="Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
association>
resultMap>
<select id="getAllStudent" resultMap="StudentTeacher">
select s.id sid,t.id tid,s.name sname,t.name tname
from student s,teacher t
where s.tid = t.id;
select>
mapper>
package com.myLearning.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student implements Serializable {
private int id;
private String name;
private int tid;
}
package com.myLearning.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Teacher implements Serializable {
private int id;
private String name;
List<Student> students;
}
package com.myLearning.Dao;
import com.myLearning.pojo.Teacher;
public interface TeacherMapper {
Teacher getTeacherById(int id);
}
我们先查出指定id老师的信息,然后再利用这个信息去查询学生表得到学生信息,使用collection进行结果的映射
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.myLearning.Dao.TeacherMapper">
<select id="getTeacherById" resultMap="teacherWithStudents">
select * from teacher where id=#{id};
select>
<select id="getAllStudent" resultType="Student">
select * from student where tid = #{id}
select>
<resultMap id="teacherWithStudents" type="Teacher">
<collection property="students" column="id" javaType="ArrayList" ofType="Student" select="getAllStudent"/>
resultMap>
mapper>
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.myLearning.Dao.TeacherMapper">
<select id="getTeacherById" resultMap="teacherWithStudents">
select s.id sid, t.id tid, s.name sname, t.name tname from teacher t,student s where s.tid=t.id and t.id=#{id};
select>
<resultMap id="teacherWithStudents" type="Teacher">
<result column="tid" property="id"/>
<result column="tname" property="name"/>
<collection property="students" ofType="Student">
<result column="sid" property="id"/>
<result column="sname" property="name"/>
<result column="tid" property="tid"/>
collection>
resultMap>
mapper>
动态SQL指的是根据不同的条件生成不同的SQL语句
创建所需数据库
create table `blog`(
`id` VARCHAR(50) not null comment '博客ID',
`title` VARCHAR(100) not null,
`author` varchar(30) not null,
`create_time` datetime not null,
`views` int(30) not null
)ENGINE=InnoDB Default charset=utf8;
改动mybatis-config.xml
<settings>
<setting name="logImpl" value="LOG4J2"/>
<setting name="mapUnderscoreToCamelCase" value="true"/>
settings>
创建实体类
package com.myLearning.pojo;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
public class Blog implements Serializable {
private String id;
private String title;
private String author;
private Date createTime;
private int views;
}
创建BlogMapper接口以及对应的xml文件,同时记得在mybatis-config.xml中注册
package com.myLearning.Dao;
import com.myLearning.pojo.Blog;
public interface BlogMapper {
int addBlog(Blog blog) ;
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.myLearning.Dao.BlogMapper">
<insert id="addBlog" parameterType="blog">
insert into blog(id,title,author,create_time,views)
values(#{id},#{title},#{author},#{createTime},#{views})
insert>
mapper>
插入数据
package com.myLearning.Dao;
import com.myLearning.pojo.Blog;
import com.myLearning.util.IDUtils;
import com.myLearning.util.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.Date;
public class BlogMapperTest {
@Test
public void addBlogTest() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
Blog blog = new Blog();
blog.setId(IDUtils.getID());
blog.setAuthor("心理学家");
blog.setCreateTime(new Date());
blog.setViews(100);
blog.setTitle("思考,快与慢");
blogMapper.addBlog(blog);
blog.setId(IDUtils.getID());
blog.setAuthor("物理学家");
blog.setCreateTime(new Date());
blog.setViews(1000);
blog.setTitle("广义相对论");
blogMapper.addBlog(blog);
blog.setId(IDUtils.getID());
blog.setAuthor("哲学家");
blog.setCreateTime(new Date());
blog.setViews(10000);
blog.setTitle("马克思主义");
blogMapper.addBlog(blog);
blog.setId(IDUtils.getID());
blog.setAuthor("经济学家");
blog.setCreateTime(new Date());
blog.setViews(100000);
blog.setTitle("宏观经济学");
blogMapper.addBlog(blog);
blog.setId(IDUtils.getID());
blog.setAuthor("文学家");
blog.setCreateTime(new Date());
blog.setViews(1000);
blog.setTitle("雪国");
blogMapper.addBlog(blog);
sqlSession.commit();
sqlSession.close();
}
}
Mapper内添加接口
List<Blog> getBlogIf(Map<String, Object> map);
xml实现
<select id="getBlogIf" parameterType="map" resultType="blog">
select * from blog where 1=1
<if test="title != null">
and title=#{title}
if>
<if test="author != null">
and author=#{author}
if>
select>
测试类
@Test
public void testGetBlogIf() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("title", "雪国");
// map.put("author", "文学家");
List<Blog> blogs = blogMapper.getBlogIf(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}
where标签可以生成where语句,如果where语句接的第一个是and,会自动去掉第一个and
使用where标签改进刚刚的xml代码
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.myLearning.Dao.BlogMapper">
<insert id="addBlog" parameterType="blog">
insert into blog(id,title,author,create_time,views)
values(#{id},#{title},#{author},#{createTime},#{views})
insert>
<select id="getBlogIf" parameterType="map" resultType="blog">
select * from blog
<where>
<if test="title != null">
title=#{title}
if>
<if test="author != null">
and author=#{author}
if>
where>
select>
mapper>
set标签主要用于update语句,与where标签类似,set标签可以生成set语句,如果set标签生成的sql语句最后一个是‘,’会自动去掉最后一个‘,’
trim标签可以用于生成自定义的sql语句,where标签和set标签可以用trim标签替代
即trim标签可以生成where语句,也可以生成set语句
trim标签的属性:
choose标签类似于java中的switch语句,当choose标签中的when标签中的条件成立时,就会执行when标签中的sql语句,如果所有的when标签中的条件都不成立,就会执行otherwise标签中的sql语句
Mapper类中添加方法
List<Blog> getBlogChoose(Map<String, Object> map);
Mapper.xml中添加sql语句
<select id="getBlogChoose" parameterType="map" resultType="blog">
select * from blog
<where>
<choose>
<when test="author != null">
author=#{author}
when>
<when test="title != null">
title=#{title}
when>
<otherwise>
views=#{views}
otherwise>
choose>
where>
select>
测试
@Test
public void getBlogChooseTest() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
Map<String,Object> map = new HashMap<String,Object>();
// map.put("author","经济学家");
map.put("views",100);
List<Blog> blogs = blogMapper.getBlogChoose(map);
for(Blog blog : blogs){
System.out.println(blog);
}
sqlSession.close();
}
foreach标签主要用于循环遍历集合,常用于in条件中,如in (12,13,14), 可自行指定生成字符串的前缀、后缀、分隔符等。
添加UserMapper接口中的方法
List<Blog> getBlogForeach(Map<String, Object> map);
在mapper.xml中添加sql语句,其中使用foreach标签实现遍历views集合,使得查询结果的views均在在设定的集合内
<select id="getBlogForeach" parameterType="map" resultType="blog">
select * from blog
<where>
<foreach collection="views" item="view" open="views in (" close=")"
separator=",">
#{view}
foreach>
where>
select>
@Test
public void getBlogForeachTest() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
Map<String,Object> map = new HashMap<String,Object>();
// map.put("author","经济学家");
List<Integer> views = new ArrayList<Integer>();
views.add(100);
views.add(1000);
views.add(10000);
map.put("views", views);
List<Blog> blogs = blogMapper.getBlogForeach(map);
for(Blog blog : blogs){
System.out.println(blog);
}
sqlSession.close();
}
sql片段可以用来定义可重用的sql语句,在需要使用的地方使用include标签引入
例如,我们可以使用sql片段将我们写的if标签放在sql片段中,然后在需要使用的地方使用include标签引入
<sql id="if-title-author">
<if test="title != null">
title = #{title}
if>
<if test="author != null">
and author = #{author}
if>
sql>
<select id="getBlogIf" parameterType="map" resultType="com.zhang.pojo.Blog">
select * from blog
<where>
<include refid="if-title-author">include>
where>
select>
在MyBatis中,缓存是一种用于提升数据库查询性能的机制,通过减少对数据库的直接访问来加快数据检索速度。
缓存将查询结果存储在内存中,避免重复查询数据库,从而加快数据访问速度;减少数据库的访问次数,减轻数据库压力;直接从缓存获取数据,比从数据库查询更快。
MyBatis提供了两种类型的缓存:一级缓存和二级缓存。
一级缓存是MyBatis在SqlSession级别维护的缓存,作用于SqlSession级别,默认情况下是开启的。当执行查询操作时,MyBatis会将查询结果存储在一级缓存中,当下一次相同的查询操作时,MyBatis会先从一级缓存中查找结果,如果找到了,就直接返回结果,避免了再次查询数据库。
二级缓存是MyBatis在SqlSessionFactory级别维护的缓存,作用于Mapper级别,默认情况下是关闭的。当执行查询操作时,MyBatis会先将查询结果放在一级缓存中,会话结束后,再存储在二级缓存中,当下一次相同的查询操作时,MyBatis会先从二级缓存中查找结果,如果找到了,就直接返回结果,避免了再次查询数据库。
<settings>
<setting name="cacheEnabled" value="true"/>
settings>
<cache/>
配置时可以设置的属性:
@CacheNamespace(blocking = true)
public interface BlogMapper {
// ...
}
@CacheNamespace(blocking = true)
public class Blog {
// ...
}
MyBatis允许自定义缓存,只需要实现Cache接口即可。除此之外,还可以使用第三方缓存,如Ehcache、Redis等。
public class MyCache implements Cache {
// ...
}
<cache type="com.example.MyCache"/>
笔记总结于视频:https://www.bilibili.com/video/BV1NE411Q7Nx/?vd_source=16bf0c507e4a78c3ca31a05dff1bee4e