Mybatis

Mybatis

如何获得Mybatis?

  • Maven仓库:
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.6</version>
</dependency>

第一个Mybatis程序

搭建环境

  1. 新建一个普通的maven项目
  2. 删除src目录
  3. 导入maven依赖
<dependencies>
    <!--mysql驱动-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>
    <!--mybatis-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.2</version>
    </dependency>
    <!--junit-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>

创建一个模块

tip:
war模式:将WEB工程以包的形式上传到服务器
war exploded模式:将WEB工程以当前文件夹的位置关系上传到服务器
  1. 编写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>
    <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&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>

<mappers>
    <mapper resource="com/kuang/dao/UserMapper.xml" />
</mappers>
</configuration>
  1. 编写mybatis工具类
public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            //使用mybatis第一步:获取sqlSessionFactory对象
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //有了sqlSessionFactory,就可以从中获得sqlSession对象
    //sqlSession完全包含了面向数据库执行SQL命令所需的所有方法
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

编写代码

  1. 实体类: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 + '\'' +
                '}';
    }
}
  1. UserDao接口
public interface UserDao {
    public List<User> getUserList();
}
  1. UserMapper.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.kuang.dao.UserDao">
    <select id="getUserList" resultType="com.kuang.pojo.User">
    select * from mybatis.User
  </select>
</mapper>

测试

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();
    }
}

可能遇到的错误:

  1. org.apache.ibatis.binding.BindingException: Type interface com.kuang.dao.UserDao is not known to the MapperRegistry.
  • 在mybatis-config.xml中配置mappers
<mappers>
    <mapper resource="com/kuang/dao/UserMapper.xml" />
</mappers>
  1. Caused by: java.io.IOException: Could not find resource com/kuang/dao/UserMapper.xml
  • maven由于他的约定大于配置,我们可能遇到我们写的配置文件无法被导出或者生效的问题,解决方式
//pom.xml
//在build中配置resources,来防止我们资源导出失败的问题
<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>

        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

如果还不行记得重载一下依赖

  1. 有中文注解会出错:### Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: Error creating document instance. Cause: com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: 1 字节的 UTF-8 序列的字节 1 无效。
  • 解决办法1:将第一行的改为 神奇?
<?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.kuang.dao.UserMapper">
    <!--查询所有用户-->
    <select id="getUserList" resultType="com.kuang.pojo.User">
        select * from mybatis.User
    </select>

</mapper>
  • 解决办法2:在父工程的pom.xml里面配置<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>,与dependences同级标签
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

测试增删改一个用户

@Test
public void testAddUser(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    int res = userMapper.addUser(new User(5, "haha", "1234567"));
    if (res>0){
        System.out.println("插入成功");
    }
    sqlSession.commit();
    sqlSession.close();
}

@Test
public void testUpdateUser(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    int res = userMapper.updateUser(new User(4, "h呵呵", "123"));
    if (res>0){
        System.out.println("修改成功");
    }
    sqlSession.commit();
    sqlSession.close();
}
@Test
public void testDeleteUser(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    int res = userMapper.deleteUser(5);
    if (res>0){
        System.out.println("删除成功");
    }
    sqlSession.commit();
    sqlSession.close();
}

记得要提交事务,否则插入失败

万能的Map

//万能的map
public int updateUser2(Map map);
<!--万能的map-->
<update id="updateUser2" parameterType="map">
    update mybatis.user set name=#{userName} where id=#{userId}
</update>
//万能的map
@Test
public void testUpdateUser2(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("userName","niyun");
    map.put("userId",4);
    int res = userMapper.updateUser2(map);
    if (res>0){
        System.out.println("万能的map修改成功");
    }
    sqlSession.commit();
    sqlSession.close();
}

Map传递参数,直接在sql中取出key即可【parameterType="map"】

对象传递参数,直接在sql中取对象的属性即可【parameterType="com.kuang.pojo.User"】

只有一个基本类型参数的情况下,可以直接在sql中取到 ,也就是【parameterType="int"】可以不写

多个参数用Map,或者注解!

模糊查询怎么写

  1. Java代码执行的时候,传递通配符 %李%
public List<User> getUserListByMatch(String name);
<!--select all user by match-->
<select id="getUserListByMatch" resultType="com.kuang.pojo.User">
    select * from mybatis.User where name like #{name}
</select>
@Test
public void testQueryAllUserByMatch(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    List<User> userList = userMapper.getUserListByMatch("%李%");
    for (User user : userList) {
        System.out.println(user);
    }

    sqlSession.close();
}
  1. 在sql拼接中使用通配符!
<!--select all user by match-->
<select id="getUserListByMatch" resultType="com.kuang.pojo.User">
    select * from mybatis.User where name like "%"#{name}"%"
</select>
@Test
public void testQueryAllUserByMatch(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    List<User> userList = userMapper.getUserListByMatch("李");
    for (User user : userList) {
        System.out.println(user);
    }

    sqlSession.close();
}

环境配置

  • Mybatis可以配置成适应多种环境,不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。
  • 学习使用配置多套运行环境
  • Mybatis默认的事务管理器就是JDBC,连接池:POOLED

属性(properties)

  • 我们可以通过properties属性来实现引用配置文件

  • 这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。

  • 优先使用外部配置文件的root,password

  • properties要配置在最前面

类型别名

  • com.kuang.pojo.user太过于繁琐,在Mybatis-config.xml中配置typeAliases属性

方法一:

<!--别名方式一-->
<typeAliases>
    <typeAlias alias="User" type="com.kuang.pojo.User"/>
</typeAliases>
<!--select all user-->
<select id="getUserList" resultType="User">
    select * from mybatis.User
</select>

方式二:指定一个包名,Mybatis会在包名下面搜索需要的Java Bean,扫描实体类的包,他的默认别名就是这个类的类名,首字母小写!

<!--别名方式二-->
<typeAliases>
    <package name="com.kuang.pojo"/>
</typeAliases>
<!--select all user-->
<select id="getUserList" resultType="User">
    select * from mybatis.User
</select>

方式二还可以通过注解@Alias("别名"),自定义别名

@Alias("helloUser")
public class User {}
<!--select all user-->
<select id="getUserList" resultType="helloUser">
    select * from mybatis.User
</select>
<typeAliases>
    <package name="com.kuang.pojo"/>
</typeAliases>
  • 在实体类少的时候可以使用方式一,多的时候使用方式二

resultMap

  • resultMap元素是Mybatis中最重要最强大的元素
  • resultMap的设计思想是对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了
public class User {
    private int id;
    private String name;
    private String password;//数据库是pwd
}
<!-- 根据id查询用户 -->
<select id="getUserById" parameterType="int" resultMap="UserMap">
    select * from mybatis.User where id = #{id}
</select>
<resultMap id="UserMap" type="User">
    <result column="id" property="id"/>
    <result column="name" property="name"/>
    <result column="pwd" property="password"/>
</resultMap>
@Test
public void testQueryUserById(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    User user = userMapper.getUserById(1);
    System.out.println(user);
    sqlSession.close();
}

日志

日志工厂

LOG4J

STDOUT_LOGGING

<properties resource="db.properties">
    <property name="username" value="root"/>
    <property name="password" value="123456"/>
</properties>
<settings>
    <!--不能有空格,格式严格-->
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--别名方式一-->
<typeAliases>
    <typeAlias alias="User" type="com.kuang.pojo.User"/>
</typeAliases>

LOG4J

  1. 导入依赖
  2. log4j.properties
#将等级为DEBUG的日志信息输出到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/kuang.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
  1. 配置Mybatis-config.xml
<settings>
    <!--不能有空格,格式严格-->
    <setting name="logImpl" value="LOG4J"/>
</settings>
  1. 测试结果
[org.apache.ibatis.logging.LogFactory]-Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
[org.apache.ibatis.logging.LogFactory]-Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
[org.apache.ibatis.datasource.pooled.PooledDataSource]-PooledDataSource forcefully closed/removed all connections.
[org.apache.ibatis.datasource.pooled.PooledDataSource]-PooledDataSource forcefully closed/removed all connections.
[org.apache.ibatis.datasource.pooled.PooledDataSource]-PooledDataSource forcefully closed/removed all connections.
[org.apache.ibatis.datasource.pooled.PooledDataSource]-PooledDataSource forcefully closed/removed all connections.
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Opening JDBC Connection
[org.apache.ibatis.datasource.pooled.PooledDataSource]-Created connection 1558021762.
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@5cdd8682]
[com.kuang.dao.UserMapper.getUserById]-==>  Preparing: select * from mybatis.User where id = ? 
[com.kuang.dao.UserMapper.getUserById]-==> Parameters: 1(Integer)
[com.kuang.dao.UserMapper.getUserById]-<==      Total: 1
User{id=1, name='狂神', password='123456'}
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@5cdd8682]
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@5cdd8682]
[org.apache.ibatis.datasource.pooled.PooledDataSource]-Returned connection 1558021762 to pool.

public class UserDaoTest {
static Logger logger = Logger.getLogger(UserDaoTest.class);
@Test
public void testQueryUserById() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
logger.info("测试进入testQueryUserById方法成功。。。");
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.getUserById(1);
System.out.println(user);
sqlSession.close();
}

@Test
public void testLog4j() {
logger.info("info: 进入log4j");
logger.debug("debug: 进入log4j");
logger.error("error: 进入log4j");
}
}

分页

使用Mybatis实现分页

//分页查询
public List<User> getUserByLimit(Map<String,Integer> map);
<resultMap id="UserMap" type="User">
    <result column="id" property="id"/>
    <result column="name" property="name"/>
    <result column="pwd" property="password"/>
</resultMap>

<!--分页查询-->
<select id="getUserByLimit" parameterType="map" resultMap="UserMap">
    select * from mybatis.User limit #{startIndex},#{pageSize}
</select>
@Test
public void getUserByLimit() {
SqlSession sqlSession = MybatisUtils.getSqlSession();

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("startIndex",1);
map.put("pageSize",3);
List<User> userList = userMapper.getUserByLimit(map);
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}

{} 和 ${}区别

其实就是prestatement和statement区别

多对一查询

方式一:

<?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.kuang.dao.StudentMapper">
    <resultMap id="StudentTeacher" type="Student">
        <result column="id" property="id"/>
        <result column="name" property="name"/>
        <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
    </resultMap>
    <select id="getStudent" resultMap="StudentTeacher">
		select * from mybatis.Student
	</select>
    <select id="getTeacher" resultType="Teacher">
		select * from mybatis.Teacher where id = #{tid}
	</select>
</mapper>

方式二:

<?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.kuang.dao.StudentMapper">
    <select id="getStudent" resultMap="StudentTeacher">
        select s.id,s.name,t.id tid,t.name tname from student s,teacher t where s.tid = t.id
    </select>
    <resultMap id="StudentTeacher" type="Student">
        <result column="id" property="id"/>
        <result column="name" property="name"/>
        <association property="teacher" javaType="Teacher">
            <result column="tid" property="id"/>
            <result column="tname" property="name"/>
        </association>
    </resultMap>
</mapper>

注意:两张表有相同名字的时候要注意加别名

一对多查询:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kuang.dao.TeacherMapper">

    <select id="getTeacher" resultType="Teacher" resultMap="TeacherStudent">
        select t.id tid,t.name tname,age,s.id sid,s.name sname,s.tid stid from teacher t,student s where s.tid = t.id and t.id = #{tid}
    </select>
    <resultMap id="TeacherStudent" type="Teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
        <result property="age" column="age"/>
        <collection property="students" ofType="Student">
            <result column="sid" property="id"/>
            <result column="sname" property="name"/>
            <result column="stid" property="tid"/>
        </collection>
    </resultMap>
</mapper>

小结

  1. 关联 - association 【多对一】

  2. 集合 - collection 【一对多】

  3. javaType & ofType

    • javaType 用来指定实体类中的属性的类型
    • ofType 用来指定映射到List或者集合中的pojo类型,泛型中的约束类型!

动态SQL

动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。

如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach

if

<!-- 根据name或者password查询用户 -->
<select id="getUserByPwdOrName" parameterType="map" resultMap="UserMap">
    select * from mybatis.User where 1=1
    <if test="uname != null">
        and name = #{uname}
    </if>
    <if test="pwd1 != null">
        and pwd = #{pwd1}
    </if>
</select>
@Test
public void getUserByPwdOrName() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    HashMap<String, String> hashMap = new HashMap<String, String>();
    hashMap.put("uname","fasdf");
    hashMap.put("pwd1","1234");
    List<User> userList = userMapper.getUserByPwdOrName(hashMap);
    for (User user : userList) {
        System.out.println(user);
    }
    sqlSession.close();
}

SQL片段

<sql id="if-uname-pwd1">
    <if test="uname != null">
        and name = #{uname}
    </if>
    <if test="pwd1 != null">
        and pwd = #{pwd1}
    </if>
</sql>

<!-- 根据name或者password查询用户 -->
<select id="getUserByPwdOrName" parameterType="map" resultMap="UserMap">
    select * from mybatis.User where 1=1
    <include refid="if-uname-pwd1"></include>
</select>

有的时候,我们可能会将一些功能的部分抽取出来,方便复用!

  1. 使用SQL标签抽取公共的部分
  2. 在需要使用的地方使用include标签引用即可

注意事项:

  • 最好基于单表来定义SQL片段
  • 不要存在where标签

Mybatis缓存

一级缓存

一级缓存默认是开启的,只有一次SqlSession中有效,也就是拿到连接到关闭连接这个区间段!一级缓存就是一个map

二级缓存

  1. 开启缓存
<!--显式开启全局缓存-->
<setting name="cacheEnabled" value="true"/>
  1. 在mapper使用二级缓存
<cache/>
  1. 测试
@Test
public void testTwoLevelCache() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    SqlSession sqlSession2 = MybatisUtils.getSqlSession();
    logger.info("测试进入testQueryUserById方法成功。。。");
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    User user = userMapper.getUserById(1);
    System.out.println(user);
    sqlSession.close();

    UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
    User user2 = userMapper2.getUserById(1);
    System.out.println(user2);
    System.out.println(user==user2);

    sqlSession2.close();
}
[com.kuang.dao.UserDaoTest]-测试进入testQueryUserById方法成功。。。
[com.kuang.dao.UserMapper]-Cache Hit Ratio [com.kuang.dao.UserMapper]: 0.0
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Opening JDBC Connection
[org.apache.ibatis.datasource.pooled.PooledDataSource]-Created connection 1048027629.
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@3e77a1ed]
[com.kuang.dao.UserMapper.getUserById]-==>  Preparing: select * from mybatis.User where id = ? 
[com.kuang.dao.UserMapper.getUserById]-==> Parameters: 1(Integer)
[com.kuang.dao.UserMapper.getUserById]-<==      Total: 1
User(id=1, name=zhangsan , password=123)
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@3e77a1ed]
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@3e77a1ed]
[org.apache.ibatis.datasource.pooled.PooledDataSource]-Returned connection 1048027629 to pool.
[com.kuang.dao.UserMapper]-Cache Hit Ratio [com.kuang.dao.UserMapper]: 0.5
User(id=1, name=zhangsan , password=123)
false

问题:

org.apache.ibatis.cache.CacheException: Error serializing object. Cause: java.io.NotSerializableException: com.kuang.pojo.User

解决方案:如果只是加,没有加readonly=true,系统默认是false,所以报错要将实体类序列化,必须加入配置

<cache
        eviction="FIFO"
        flushInterval="60000"
        size="512"
        readOnly="true"/>

或者实体类实现Serializable接口。将实体类实现Serializable接口,因为实体在二级缓存中,所以需要序列化处理才能方便查找。

public class User implements Serializable
posted @ 2021-04-17 21:16  血^_^月  阅读(57)  评论(0)    收藏  举报