官方文档:https://mybatis.org/mybatis-3/zh/index.html
MyBatis 是一款优秀的持久层框架
它支持自定义 SQL、存储过程以及高级映射
MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作
MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.11version>
dependency>
CREATE DATABASE mybatis;
USE mybatis;
CREATE TABLE `user` (
`id` INT(20) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
`pwd` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY(`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO `user`(`id`,`name`,`pwd`) VALUES
(1,'张三','123123'),
(2,'李四','111111'),
(3,'王五','121212');
创建一个普通的maven项目
删除src目录使其变成一个父工程
导入依赖
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.49version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.11version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
dependency>
之后我们的项目都是一个个模块
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://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.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/daban/dao/UserMapper.xml"/>
mappers>
configuration>
package com.daban.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 {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
org.apache.ibatis.binding.BindingException: Type interface com.daban.dao.UserDao is not known to the MapperRegistry.
意思是没有在mybatis的配置文件中注册mapper,需要在配置文件中添加注册
<mappers>
<mapper resource="com/daban/dao/UserMapper.xml"/>
mappers>
org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource com/daban/dao/UserMapper.xml
不能找到mapper.xml文件,因为在构建的时候没有导出该文件,如下代码到pom中可以解决
src/main/java
**/*.xml
true
是因为xml文件中的注释使用了中文,去掉即可,或者将encoding="UTF-8"改为encoding=“UTF8”(原因不明)
package com.daban.pojo;
public class User {
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;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", pwd='" + pwd + '\'' +
'}';
}
}
package com.daban.dao;
import com.daban.pojo.User;
import java.util.List;
public interface UserDao {
List<User> getUserList();
}
(由之前的实现类转变成一个Mapper配置文件)
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.daban.dao.UserDao">
<select id="getUserList" resultType="com.daban.pojo.User">
select * from mybatis
select>
mapper>
package com.daban.dao;
import com.daban.pojo.User;
import com.daban.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class UserMapperTest {
@Test
public void test(){
//获取sqlSession
SqlSession sqlSession = MybatisUtils.getSqlSession();
//得到UserDao的Mapper
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.getUserList();
for (User user: userList) {
System.out.println(user);
}
sqlSession.close();
}
}
类 | 作用域 | 备注 |
---|---|---|
SqlSessionFactoryBuilder | 最佳作用域是方法作用域(也就是局部方法变量) | |
SqlSessionFactory | 最佳作用域是应用作用域 | 想象为数据库连接池 |
SqlSession | 最佳的作用域是请求或方法作用域 | 连接到连接池的一个请求,用完关闭 |
记住,在增删改的时候需要提交事务才可以生效sqlSession.commit();
1、编写接口
//通过id查询用户
User getUserById(int id);
2、编写对应mapper中的sql语句
<select id="getUserById" resultType="com.daban.pojo.User" parameterType="int" >
select * from mybatis.user where id = #{id}
select>
3、测试
public void getUserById(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User userById = mapper.getUserById(1);
System.out.println(userById);
sqlSession.close();
}
1、编写接口
//增加一个用户
void addUser(User user);
2、编写对应mapper中的sql语句
<insert id="addUser" parameterType="com.daban.pojo.User">
insert into mybatis.user values(#{id},#{name},#{pwd})
insert>
3、测试
public void addUser(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.addUser(new User(5,"嫦娥","333333"));
//增删改必须要提交事务
sqlSession.commit();
sqlSession.close();
}
1、编写接口
//修改一个用户
void updateUser(User user);
2、编写对应mapper中的sql语句
<update id="updateUser" parameterType="com.daban.pojo.User">
update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id}
update>
3、测试
public void updateUser(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.updateUser(new User(5,"大圣","888888"));
sqlSession.commit();
sqlSession.close();
}
1、编写接口
//删除一个用户
void deleteUser(User user);
2、编写对应mapper中的sql语句
<delete id="deleteUser" parameterType="com.daban.pojo.User">
delete from mybatis.user where id=#{id}
delete>
3、测试
public void deleteUser(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.deleteUser(new User(5));
sqlSession.commit();
sqlSession.close();
}
1、编写接口
//通过name查询用户
List<User> getUserByName(String name);
2、编写对应mapper中的sql语句
<select id="getUserByName" resultType="com.daban.pojo.User" parameterType="string" >
select * from mybatis.user where name like #{name}
select>
3、测试
public void getUserByName(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.getUserByName("%张%");
for (User user: userList) {
System.out.println(user);
}
sqlSession.close();
}
首先配置文件中标签是有顺序的,写反会报错
properties>settings>typeAliases>typeHandlers>objectFactory>objectWrapperFactory>reflectorFactory>plugins>environments>databaseIdProvider>mappers
引入一个配置文件,使mybatis的核心配置文件可以引用该配置文件里面的参数
<properties resource="config.properties">
<property name="username" value="root"/>
<property name="password" value="123456"/>
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="${password}"/>
dataSource>
environment>
environments>
如果一个属性在不只一个地方进行了配置,那么,MyBatis 将按照下面的顺序来加载:
因此,通过方法参数传递的属性具有最高优先级,resource/url 属性中指定的配置文件次之,最低优先级的则是 properties 元素中指定的属性。
这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为
官网查找https://mybatis.org/mybatis-3/zh/configuration.html
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写
<typeAliases>
<typeAlias alias="user" type="com.daban.pojo.User"/>
typeAliases>
可以通过包来起别名,包下的所有实体类,都可以使用类名的首字母小写来代替全名,给实体类加注解,可以diy
<typeAliases>
<package name="com.daban.pojo"/>
typeAliases>
<environments default="development">默认使用的环境
<environment id="development">定义的环境标识,可随意标识,保证默认的环境 ID 要匹配其中一个环境 ID
<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="${password}"/>
dataSource>
environment>
environments>
在 MyBatis 中有两种类型的事务管理器(也就是 type=“[JDBC|MANAGED]”)
如果你正在使用 Spring + MyBatis,则没有必要配置事务管理器,因为 Spring 模块会使用自带的管理器来覆盖前面的配置
有三种内建的数据源类型(也就是 type=“[UNPOOLED|POOLED|JNDI]”),
UNPOOLED– 这个数据源的实现会每次请求时打开和关闭连接。虽然有点慢,但对那些数据库连接可用性要求不高的简单应用程序来说,是一个很好的选择
POOLED(常用)– 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间
JNDI – 这个数据源实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的数据源引用
告诉 MyBatis 到哪里去找到sql语句
方式一、【推荐使用】
<mappers>
<mapper resource="com/daban/dao/UserMapper.xml"/>
mappers>
方式二、
<mappers>
<mapper class="com.daban.dao.UserMapper"/>
mappers>
注意点:
接口和他的mapper配置文件必须同名
接口和他的mapper配置文件必须在同一个包下
方式三、
<mappers>
<package name="com.daban.dao"/>
mappers>
注意点:
接口和他的mapper配置文件必须同名
接口和他的mapper配置文件必须在同一个包下
方式四、【不建议使用】
<mappers>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
mappers>
<select id="getUserById" resultType="com.daban.pojo.User" parameterType="int" >
select * from mybatis.user where id = #{id}
select>
select元素的属性
<select
id="selectPerson" dao接口中的方法名字
parameterType="int" 参数的类全限定名或别名。这个属性是可选的
parameterMap="deprecated" 废弃了
resultType="hashmap" 返回结果的类全限定名或别名,如果是集合,写集合泛型
resultMap="personResultMap" 对实体类和字段名字不一样时的处理,结果映射
flushCache="false" 每次sql执行,都刷新清除一二级缓存
useCache="true" 开启二级缓存
timeout="10" 在抛出异常之前,驱动程序等待数据库返回请求结果的秒数
fetchSize="256" 尝试让驱动程序每次批量返回的结果行数等于这个设置值
statementType="PREPARED" 可选 STATEMENT,PREPARED 或 CALLABLE
resultSetType="FORWARD_ONLY">
<insert id="insertAuthor">
insert into Author (id,username,password,email,bio)
values (#{id},#{username},#{password},#{email},#{bio})
insert>
<update id="updateAuthor">
update Author set
username = #{username},
password = #{password},
email = #{email},
bio = #{bio}
where id = #{id}
update>
<delete id="deleteAuthor">
delete from Author where id = #{id}
delete>
属性
<insert
keyProperty="" 设置自增主键的字段
keyColumn=""
useGeneratedKeys="" 开启自增主键
timeout="20">
ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了
方式一、起别名
<select id="getUserById" resultType="com.daban.pojo.User" parameterType="int" >
select user_id as id,
user_name,
user_pwd
from mybatis.user where id = #{id}
select>
方式二、使用resultMap
<resultMap id="userResultMap" type="User">
<id property="id" column="user_id" />
<result property="username" column="user_name"/>
<result property="password" column="user_password"/>
resultMap>
<select id="getUserById" resultMap="userResultMap" parameterType="int" >
select from mybatis.user where id = #{id}
select>
标签 | 解释 | 备注 |
---|---|---|
id | 当前命名空间中的一个唯一标识,用于标识一个结果映射。 | 和select标签中的 resultMap绑定 |
type | 类的完全限定名, 或者一个类型别名。 | 不用结果集映射时,select标签中的resultType的值 |
autoMapping | 如果设置这个属性,MyBatis 将会为本结果映射开启或者关闭自动映射 |
标签 | 解释 | 备注 |
---|---|---|
constructor | 用于在实例化类时,注入结果到构造方法中 | |
id | 标记出作为 ID 的结果可以帮助提高整体性能 | |
result | 注入到字段或 JavaBean 属性的普通结果 | |
association | 个复杂类型的关联;许多结果将包装成这种类型 | 相当于对象 |
collection | 一个复杂类型的集合 | 相对于集合 |
discriminator | 使用结果值来决定使用哪个 |
这个元素可以用来定义可重用的 SQL 代码片段,以便在其它语句中使用
<sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password sql>
<include refid="userColumns"><property name="alias" value="t1"/>include>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
settings>
设置里设置logImpl的值:
SLF4J
LOG4J(3.5.9 起废弃)
LOG4J2
JDK_LOGGING
COMMONS_LOGGING
STDOUT_LOGGING
NO_LOGGING
1、先导包
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
2、配置log4j的配置文件
resources下新建一个log4j.properties
#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file
#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/logFile.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
3、使用
import org.apache.log4j.Logger;
Logger logger = Logger.getLogger(UserTest.class);//获得logger对象,参数为当前类的class
logger.info("我是info");
logger.debug("我是调试信息");
logger.error("我是error");
原理就是使用map来传递limit的参数
1、接口方法
List<User> getUserListLimit(Map<String,Object> map);
2、mapper配置文件
<mapper namespace="com.daban.dao.UserMapper">
<resultMap id="userMap" type="user">
<result property="password" column="pwd"/>
resultMap>
<select id="getUserListLimit" resultMap="userMap" parameterType="map">
select * from mybatis.user limit #{startIndex},#{pageSize}
select>
mapper>
3、测试
public void test(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String, Object> map = new HashMap<>();
map.put("startIndex",2);
map.put("pageSize",3);
List<User> userList = mapper.getUserListLimit(map);
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
使用注解来映射简单语句会使代码显得更加简洁,但对于稍微复杂一点的语句,Java 注解不仅力不从心,还会让本就复杂的 SQL 语句更加混乱不堪。 因此,如果你需要做一些很复杂的操作,最好用 XML 来映射语句
1、删除接口的mapper文件
2、接口中使用注解
@Select("select * from mybatis.user")
List<User> getUserList();
3、mybatis核心配置文件中使用类绑定
<mappers>
<mapper class="com.daban.dao.UserMapper"/>
mappers>
这样会发现无法进行结果集映射,这是使用注解的弊端
SqlSession sqlSession = factory.openSession(true);//参数为是否自动提交,设置true后,不需要手动提交
//但是在使用注解时,会自动提交
public interface UserMapper {
//查询所有
@Select("select * from mybatis.user")
List<User> getUserList();
//查询,一个参数可以省略@Param
@Select("select * from mybatis.user where id = #{id}")
User getUserById(int id);
//查询俩个参数,不能省略@Param
@Select("select * from mybatis.user where id = #{id} and name = #{name}")
User getUserByIdAndName(@Param("id") int id,@Param("name") String name);
//增加
@Select("insert into mybatis.user values(#{id},#{name},#{password})")
void addUser(User user);
//修改
@Select("update mybatis.user set name=#{name},pwd=#{password} where id = #{id} ")
void updateUser(User user);
//删除
@Select("delete from mybatis.user where id = #{id}")
void deleteUser(User user);
}
1、idea中的plugin中安装lombok
2、导入lombok的jar包
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.24version>
<scope>providedscope>
dependency>
3、使用
在实体类上加注解就行
@Getter//get方法
@Setter//set方法
@ToString//ToString方法
@EqualsAndHashCode//EqualsAndHashCode方法
@NoArgsConstructor//无参构造方法
@Data//以上都创建了
@AllArgsConstructor//所有参数构造方法
其实就是解决属性名和字段名不一致的问题,因为联表查询把其他表的字段放在了该表里,名称类型可能不一致
准备sql
CREATE TABLE teacher(
`id` INT(20) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY (`id`)
)ENGINE INNODB DEFAULT CHARSET=utf8;
INSERT INTO teacher(`id`,`name`) VALUES(1,"张老师");
CREATE TABLE student(
`id` INT(20) NOT NULL,
NAME VARCHAR(30) DEFAULT NULL,
`tid` INT(10) DEFAULT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`tid`) REFERENCES `teacher`(`id`)
)ENGINE INNODB DEFAULT CHARSET = utf8;
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);
实体类
@Data
public class Student {
private int id;
private String name;
private Teacher teacher;
}
@Data
public class Teacher {
private int id;
private String name;
}
mapper文件
<mapper namespace="com.daban.dao.StudentMapper">
<resultMap id="getStudentListMap1" type="com.daban.pojo.Student">
<result property="id" column="s_id"/>
<result property="name" column="s_name"/>
<association property="teacher" javaType="com.daban.pojo.Teacher" >
<result property="name" column="t_name"/>
<result property="id" column="t_id"/>
association>
resultMap>
<select id="getStudentList1" resultMap="getStudentListMap1">
select s.id as s_id,
s.name as s_name,
t.name as t_name,
t.id as t_id
from mybatis.student s , mybatis.teacher t
where t.id = s.tid
select>
<resultMap id="getStudentListMap2" type="com.daban.pojo.Student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<association property="teacher" column="tid" javaType="com.daban.pojo.Teacher"
select="getTeacherList"/>
resultMap>
<select id="getStudentList2" resultMap="getStudentListMap2">
select * from mybatis.student
select>
<select id="getTeacherList" resultType="com.daban.pojo.Teacher">
select * from mybatis.teacher where id = #{id}
select>
mapper>
其实就是解决属性名和字段名不一致的问题,因为联表查询把其他表的字段放在了该表里,名称类型可能不一致
实体类
@Data
public class Teacher {
private int id;
private String name;
private List<Student> student;
}
@Data
public class Student {
private int id;
private String name;
private int tid;
}
mapper文件
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.daban.dao.TeacherMapper">
<resultMap id="getTeacherListMap1" type="com.daban.pojo.Teacher">
<result property="id" column="t_id"/>
<result property="name" column="t_name"/>
<collection property="student" column="t_id" ofType="com.daban.pojo.Student">
<result property="id" column="s_id"/>
<result property="name" column="s_name"/>
<result property="tid" column="s_tid"/>
collection>
resultMap>
<select id="getTeacherList1" resultMap="getTeacherListMap1">
select t.id as t_id,
t.name as t_name,
s.id as s_id,
s.name as s_name,
s.tid as s_tid
from mybatis.teacher t,mybatis.student s where s.tid=t.id;
select>
<resultMap id="getTeacherListMap2" type="com.daban.pojo.Teacher">
<result property="id" column="id"/>
<result property="name" column="name"/>
<collection property="student" column="id" ofType="com.daban.pojo.Student"
javaType="ArrayList" select="getStudentList"/>
resultMap>
<select id="getTeacherList2" resultMap="getTeacherListMap2">
select * from mybatis.teacher
select>
<select id="getStudentList" resultType="com.daban.pojo.Student">
select * from mybatis.student where tid = #{tid}
select>
mapper>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
开启数据库下划线命名和实体类属性驼峰命名的对应
<setting name="mapUnderscoreToCamelCase" value="true"/>
settings>
根据不同的条件生成不同的sql语句
sql准备
CREATE TABLE blog(
`id` INT(50) NOT NULL,
`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;
表中插入数据:
<insert id="addBlog" parameterType="blog">
insert into mybatis.blog(`id`,`title`,`author`,`create_time`,`views`)
values (#{id},#{title},#{author},#{createTime},#{views});
insert>
public void addBlog(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
mapper.addBlog(new Blog(IDUtils.getID(),"庆祝二十大顺利召开","中央视频",new Date(),9999));
mapper.addBlog(new Blog(IDUtils.getID(),"中纪委公布查处中央委员人数","中央视频",new Date(),500));
mapper.addBlog(new Blog(IDUtils.getID(),"小学生捡到“十万元”组团交派出所","华商报",new Date(),2344));
mapper.addBlog(new Blog(IDUtils.getID(),"浪漫同框!中国空间站飞越北京上空","华商报",new Date(),555));
mapper.addBlog(new Blog(IDUtils.getID(),"中国要搞自给自足?发改委:误解","四川观察",new Date(),1234));
sqlSession.commit();
sqlSession.close();
}
注意map中的key要和if里面的title对应上(名称一致)
当sql语句中包含小于号时,不被识别。只能使用大于号,解决办法,前后颠倒要比较的值
<select id="queryBlogIf" resultType="blog" parameterType="map">
select * from mybatis.blog where 1=1
<if test="title!=null">
and title like #{title}
if>
<if test="views!=null">
and #{views} > views
if>
select>
public void queryBlogIf(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
Map<String, Object> map = new HashMap<>();
map.put("title","%中%");
map.put("views",1000);
List<Blog> blogs = mapper.queryBlogIf(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
}
类似与java的switch case语句:第一个满足条件后面都不执行了,都不满足执行otherwise
<select id="queryBlogChoose" resultType="blog" parameterType="map">
select * from mybatis.blog where 1=1
<choose>
<when test="title!=null">
and title like #{title}
when>
<when test="author!=null">
and #{author} = author
when>
<otherwise>
and #{views} > views
otherwise>
choose>
select>
public void queryBlogChoose(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
Map<String, Object> map = new HashMap<>();
// map.put("title","%中%");
map.put("author","华商报");
map.put("views",1000);
List<Blog> blogs = mapper.queryBlogChoose(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
}
where 元素自动插入 “WHERE” 。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除
set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)
where和set都可以使用trim实现,只不过,trim更可以自定义
<select id="queryBlogForeach" parameterType="map" resultType="blog">
select * from mybatis.blog
<where>
<foreach collection="viewsList" item="view" open="(" separator="or" close=")">
views = #{view}
foreach>
where>
select>
public void queryBlogForeach(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
Map<String, Object> map = new HashMap<>();
ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(9999);
arrayList.add(2344);
map.put("viewsList",arrayList);
List<Blog> blogs = mapper.queryBlogForeach(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
}
查询的结果放在内存中,我们再次查询相同数据时,就可以走缓存,从而减少数据库的连接,减低资源损耗
经常查询且不经常改变的数据,可以使用缓存
创建实体类时,要实现序列化,这样对象才能被缓存,不然报错
mybatis默认两级缓存:
缓存失效的情况:
1、查询不同的数据
2、增删改操作,可能会改变原来的数据,所以必定会刷新缓存
3、查询不同的mapper.xml
4、手动清理缓存(sqlSession.clearCache();)
打开方式:在mapper文件中加入标签即可开启二级缓存
会话关闭时,就会将一级缓存中的数据保存到二级缓存,新的会话查询就会从二级缓存查询
java的分布式缓存
1、先导包
<dependency>
<groupId>org.mybatis.cachesgroupId>
<artifactId>mybatis-ehcacheartifactId>
<version>1.2.2version>
dependency>
2、mapper文件中设置
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
3、增加配置文件ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<diskStore path="java.io.tmpdir/ehcache"/>
<defaultCache
maxElementsInMemory="10"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600"
overflowToDisk="true"
memoryStoreEvictionPolicy="LRU"/>
<cache name="deptrole"
maxElementsInMemory="10"
eternal="false"
timeToIdleSeconds="86400"
timeToLiveSeconds="86400"
overflowToDisk="true"
memoryStoreEvictionPolicy="LRU"/>
ehcache>
用mybatis重新写smbms项目