SSM之MyBatis 02 —— 配置文件说明、日志工厂、分页(Limit和RowBounds)

系列文章

SSM之MyBatis 01 —— 第一个MyBatis程序、增删改查(模糊查询)

SSM之MyBatis 02 —— 配置文件说明、日志工厂、分页(Limit和RowBounds)

SSM之MyBatis 03 —— 使用注解开发、Lombok、多对一&一对多处理

SSM之MyBatis 04 —— 动态SQL、缓存Cache



四、配置文件说明

官方文档中也有详细解释:https://mybatis.org/mybatis-3/zh/getting-started.html

配置标签有规定顺序:

  • properties
  • settings
  • typeAliases
  • typeHandlers
  • objectFactory
  • objectWrapperFactory
  • reflectorFactory
  • plugins
  • environments
  • databaseIdProvider
  • mappers

 

1、核心配置文件(mybatis-config.xml)

mybatis-config.xml就是MyBatis的核心配置文件,常把它放在resources目录下。

在这里插入图片描述

在这里插入图片描述
 

2、环境配置(environments)

MyBatis 可以配置成适应多种环境 ,每个environment标签就是一套环境,但但每个 SqlSessionFactory 实例只能选择一种环境(通过default选择默认环境)。 MyBatis默认的事务管理器是JDBC,且默认选择连接池方式。

mybatis-config.xml

<environments default="development">
  <environment id="development">
      .........
      <!-- 事务管理器 包括JDBC(提交和回滚)、MANAGED(这个几乎不做什么) -->
    <transactionManager type="JDBC"/>
      <!-- 数据源:UNPOOLED(无连接池)、POOLED(连接池)、JNDI  -->
    <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>

为了指定创建哪种环境,只要将它作为可选的参数传递给 SqlSessionFactoryBuilder 即可, 如果忽略了环境参数,那么将会加载默认环境。

//加载自选环境
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, properties);
//加载默认环境
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, properties);

 

3、属性(properties)

先在resources目录下创建一个配置文件properteis

db.properties(根据自己数据库)

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8&useSSL=false
username=root
password=123456

在mybatis-config.xml中写properties,通过${}引用properties的变量,注意区别mapper.xml中SQL引入变量使用的是#{}。

  • 通过properties标签,可以直接引入外部文件
  • 可以在properties标签中增加属性,比如下面就是用的标签里的name和pwd
  • 如果引入的外部properties文件和标签增加的属性同名,则先使用外部引入文件里的。
<properties resource="db.properties">
    <property name="name" value="root"/>
    <property name="pwd" 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="${name}"/>
            <property name="password" value="${pwd}"/>
        </dataSource>
    </environment>
</environments>

 

4、类型别名(typeAliases)

<select id="getUserList" resultType="com.zcy.pojo.User">
    select * from mybatis.user;
</select>

在mapper.xml中写SQL时,实体类需要指定完整的包名,这显得比较麻烦,可以通过别名解决。别名有三种方式。

1、mybatis-config.xml中,用User 代替 com.zcy.pojo.User,

<typeAliases>
    <typeAlias type="com.zcy.pojo.User" alias="User"/>
</typeAliases>

2、mybatis-config.xml中,扫描包下所有实体类,用首字母小写的类名作为其别名

<typeAliases>
    <package name="com.zcy"/>
</typeAliases>

3、在方式2的基础上,在对应的类中加上注解,则用注解的别名

@Alias("User")
public User{
    .....
}

一般,实体类较少时用方式一,实体类多时用方式二,如果实体类多但又想自定义别名,就方式三。

同时,MyBatis有一些内置的Java类型别名,它们不区分大小写。(就是基本类型前有下划线,包装类则没有,比如int—>_int,而Integer—>intger)

别名映射的类型
_bytebyte
_longlong
_shortshort
_intint
_integerint
_doubledouble
_floatfloat
_booleanboolean
stringString
byteByte
longLong
shortShort
intInteger
integerInteger
doubleDouble
floatFloat
booleanBoolean
dateDate
objectObject
mapMap
hashmapHashMap
listList
arraylistArrayList

 

5、设置(setting)

主要用下面三种,后面会具体说明,其他的了解一下就行。

在这里插入图片描述

在这里插入图片描述

<settings>
  <setting name="cacheEnabled" value="true"/>
  <setting name="lazyLoadingEnabled" value="true"/>
  <setting name="multipleResultSetsEnabled" value="true"/>
</settings>

 

6、其他配置

 

7、映射器(mappers)

MapperRegister:注册绑定我们的mapper文件

方式一:使用相对于类路径的资源引用【推荐使用】

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D5FJVAWq-1613964565557)(Mybatis.assets/1613912723800.png)]

<mappers>
    <mapper resource="com/zcy/dao/UserMapper.xml"/>
</mappers>

方式二:使用映射器接口实现类的完全限定类名(通俗点就是,利用接口类找到Mapper)

<mappers>
    <mapper class="com.zcy.dao.UserMapper"/>
</mappers>

注意:mapper文件必须和接口类同名,并且要和接口类放在同一个位置

方式三:将包内的映射器接口实现全部注册为映射器(通俗点就是,指定一个包,将旗下全部接口注册)

<mappers>
    <package name="com.zcy.dao"/>
</mappers>

和方式二一样,需要注意mapper文件要和接口类同名且放在一起

 

8、生命周期和作用域

生命周期和作用域是至关重要的,因为错误的使用会导致非常严重的并发问题!!

1613914035945

SqlSessionFactoryBuilder

  • 目的是生成SqlSessionFctory, 一旦创建了 SqlSessionFactory,就不再需要它了 。
  • 最佳作用域是方法作用域 (即作为局部变量)

SqlSessionFactory

  • 可以把它想象为数据库连接池
  • SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。
  • 最佳作用域是应用作用域 (即作为全局变量)
  • 使用单例模式或者静态单例模式(即该变量是唯一的)

SqlSession

  • 它就是连接到连接池的一个请求
  • SqlSession 的实例不是线程安全的,因此是不能被共享的
  • 最佳的作用域是请求或方法作用域 (作为局部变量)
  • 用完之后赶紧关闭,否则资源会被占用
1613914629901

这里面的每一个Mapper就代表一个具体的业务(执行了一件事)!

 

五、解决属性名和字段名不一致问题

之前使用MyBatis的时候,实体类的属性和数据库中的字段都是一一对应的。

在这里插入图片描述

在这里插入图片描述

当实体类属性和数据库字段不一致怎么办呢?将类的成员名改变
在这里插入图片描述

重新查询时就会出错,名称不一致查询出来就会为空!
在这里插入图片描述

具体原因:

/*我们写的SQL*/
<select id="getUserById" parameterType="int" resultType="User">
	select * from mybatis.user where id = #{id};
</select>
/*实际的SQL和我们User中不一致,就无法将name和username匹配上*/
select id, name, password from mybatis.user where id = #{id};

解决方法:

  1. 比较苯的方法是在SQL中也用别名,将nameas username,passwordas pwd来保证一致
select id, name as username, password as pwd from mybatis.user where id = #{id};

​ 2.使用resultMap(结果集映射)

在mapper中增加resultMap标签

<mapper namespace="com.zcy.dao.UserMapper">
    <!-- 结果集映射 id:该resultMap的名称,type:返回的类型-->
    <resultMap id="UserMapper" type="User">
        <!-- 对于实体类中和数据库字段相同的属性,不需要映射,例如它们都有id -->
        <!-- property:类的属性名,column:数据库的字段名  -->
        <result property="username" column="name"/>
        <result property="pwd" column="password"/>
    </resultMap>

    <!-- 此时就不需要指定resultType   -->
    <select id="getUserById" parameterType="int" resultMap="UserMapper">
        select * from mybatis.user where id = #{id};
    </select>
</mapper>

 

六、日志

6.1、日志工厂

如果一个数据库操作出现了异常,我们通常会将其作为日志输出,在之前没用MyBatis的时候,我们在实现类中通过sout输出。

曾经:sout、debug

现在:日志工厂

在这里插入图片描述

  • SLF4J
  • LOG4J 【掌握,需要导入包】
  • LOG4J2
  • JDK_LOGGING
  • COMMONS_LOGGING
  • STDOUT_LOGGING【掌握,标准日志工厂】
  • NO_LOGGING

在MyBatis的核心配置文件中,添加setting标签

<settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

比起没用日志,显然多了很多东西,但这些显得比较杂乱,所以我们用后面的Log4j

在这里插入图片描述

 

6.2、Log4j

什么是Log4j?

  • 可以控制日志信息输送的目的地是控制台、文件、GUI组件…
  • 可以控制每一条日志的输出格式
  • 通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程
  • 这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码

1、先导入log4j的包

<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

2、log4j.properties,log4j的配置文件(这里使用部分,可百度更详细的)

#将等级为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/zcy.log
#如果文件超过10mb,就分到新文件
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、配置log4j为日志的实现

<!-- 配置日志    -->
<settings>
    <setting name="logImpl" value="LOG4J"/>
</settings>

直接使用,和之前没太大区别,但更详细了。

1613958001073

4、简单使用

  1. 在要使用日志的类中导入包 org.apache.log4j.Logger
  2. 创建日志对象 Logger,参数为当前类的class
  3. 控制日志级别进行输出
package dao;

import com.zcy.dao.UserMapper;
import com.zcy.pojo.User;
import com.zcy.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import org.junit.Test;

public class UserMapperTest {

    static Logger logger = Logger.getLogger(UserMapperTest.class);

    @Test
    public void testLogger(){
        //常用这三种
        logger.info("info:进入的testLogger");
        logger.debug("debug:进入的testLogger");
        logger.error("error:进入的testLogger");
    }
}


控制台结果:
在这里插入图片描述

同时之前log4j.properties中配置了输出到文件:

1613958675530

 

七、分页

7.1、Limit 分页

分页是为了减少数据的处理量,在SQL中我们常使用limit进行分页

语法:select * from user limit startIndex, pageSize
例如
select * from user limit 0, 2  表示从第0个数据开始,查两个
select * from user limit 2, 2  表示从第2个数据开始,查两个
select * from user limit 4 表示从第0个数据开始,查到4

使用MyBatis实现分页,其核心仍然是SQL

1、接口

public interface UserMapper {
    //通过limit实现分页,多个参数用Map
    public List<User> getUserByLimit(Map<String, Integer> map);
}

2、UserMappe.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.zcy.dao.UserMapper">
    <!-- 结果集映射 -->
    <resultMap id="UserMapper" type="User">
        <!-- User类中的id和数据库id同名,而username和password不同名 -->
        <result property="username" column="name"/>
        <result property="pwd" column="password"/>
    </resultMap>

    <!-- 通过Limit分页,map是Map的别名    -->
    <select id="getUserByLimit" parameterType="map" resultMap="UserMapper">
        select * from mybatis.user limit #{startIndex}, #{pageSize} ;
    </select>

</mapper>

3、测试

package dao;

import com.zcy.dao.UserMapper;
import com.zcy.pojo.User;
import com.zcy.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import org.junit.Test;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class UserMapperTest {

    static Logger logger = Logger.getLogger(UserMapperTest.class);

    @Test
    public void testLimit(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("startIndex", 0);
        map.put("pageSize", 2);
        List<User> userList = userMapper.getUserByLimit(map);

        for (User user : userList)
            System.out.println(user);
        sqlSession.close();
    }
}

结果:

在这里插入图片描述

 

7.2、RowBounds 分页

不在Mapper的SQL中写分页,而是通过Java代码实现,但这种方式不推荐,因为它不依赖于Mapper了。

1、接口

package com.zcy.dao;

import com.zcy.pojo.User;

import java.util.List;
import java.util.Map;

public interface UserMapper {
    //通过RowBounds
    public List<User> getUserByRowBounds();
}

2、UserMappe.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.zcy.dao.UserMapper">
    <!-- 结果集映射 -->
    <resultMap id="UserMapper" type="User">
        <!-- User类中的id和数据库id同名,而username和password不同名 -->
        <result property="username" column="name"/>
        <result property="pwd" column="password"/>
    </resultMap>

    <!-- 通过RowBounds分页    -->
    <select id="getUserByRowBounds" resultMap="UserMapper">
        select * from mybatis.user;
    </select>
</mapper>

3、测试

package dao;

import com.zcy.dao.UserMapper;
import com.zcy.pojo.User;
import com.zcy.utils.MyBatisUtils;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import org.junit.Test;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class UserMapperTest {

    static Logger logger = Logger.getLogger(UserMapperTest.class);

    @Test
    public void getUserByRowBounds(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();

        //参数:对应于startIndex,pageSize
        RowBounds rowBounds = new RowBounds(0, 2);
        //之所以说RowBounds过时,就是因为现在已经不再直接调用接口方法的方式,而是用getMapper
        //参数:接口的方法,接口方法的参数,rowBounds分页
        List<User> userList = sqlSession.selectList(
                "com.zcy.dao.UserMapper.getUserByRowBounds", null, rowBounds);

        for (User user : userList)
            System.out.println(user);
        sqlSession.close();
    }
}

结果:

在这里插入图片描述

 

7.3、分页插件 PageHelpler

具体使用方法:https://github.com/pagehelper/Mybatis-PageHelper/blob/master/README_zh.md

1、引入分页插件(Jar包或者maven)

<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.1.10</version>
</dependency>

2、在mybatis-config.xml配置PageHelper

<!-- 
    plugins在配置文件中的位置必须符合要求,否则会报错,顺序如下:
    properties?, settings?, 
    typeAliases?, typeHandlers?, 
    objectFactory?,objectWrapperFactory?, 
    plugins?, 
    environments?, databaseIdProvider?, mappers?
-->
<plugins>
    <!-- com.github.pagehelper为PageHelper类所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->
        <property name="param1" value="value1"/>
	</plugin>
</plugins>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老板来碗小面加蛋~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值