前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Data Access 之 MyBatis(二) - Configuration XML

Data Access 之 MyBatis(二) - Configuration XML

作者头像
RiemannHypothesis
发布2022-08-19 17:05:41
3530
发布2022-08-19 17:05:41
举报
文章被收录于专栏:Elixir

一、MyBatis Configuration XML

MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 configuration(配置)标签下主要有如下配置,配置的顺序要严格遵循列出的顺序

  • properties(属性)
  • settings(设置)
  • typeAliases(类型别名)
  • typeHandlers(类型处理器)
  • objectFactory(对象工厂)
  • plugins(插件)
  • environments(环境配置)
    • environment(环境变量)
      • transactionManager(事务管理器)
      • dataSource(数据源)
  • databaseIdProvider(数据库厂商标识)
  • mappers(映射器)

工程搭建

新建maven工程mybatis-config-xml,引入依赖

代码语言:javascript
复制
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.7</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.16</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.3</version>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.18</version>
    <scope>provided</scope>
</dependency>

增加entity包,新增Employee实体类

代码语言:javascript
复制
@Data
public class Employee {

    private Integer id;
    private String empName;
    private String email;
    private Integer gender;
}

增加dao包,新增EmployeeDao接口

代码语言:javascript
复制
public interface EmployeeDao {

    Employee getEmpById(Integer id);
    int updateEmployee(Employee employee);
    boolean deleteEmployee(Integer id);
    int insertEmployee(Employee employee);
}

在resource目录下增加全局配置文件mybatis-config.xml

代码语言:javascript
复制
<?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="dev">
        <!--配置环境,不同的环境不同的id名字-->
        <environment id="dev">
            <!-- 采用JDBC方式对数据库事务进行commit/rollback -->
            <transactionManager type="JDBC"></transactionManager>
            <!--采用连接池方式管理数据库连接-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/test?useUnicode=true&amp;amp;characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="mappers/employee.xml"/>
    </mappers>
</configuration>

增加mappers文件夹,在其中增加employee.xml

代码语言:javascript
复制
<?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.citi.dao.EmployeeDao">

    <!--参数类型不用写-->
    <select id="getEmpById" resultType="com.citi.entity.Employee">
        select * from t_employee where id = #{id}
    </select>

    <!--增删改不用写返回值类型,增删改返回的是影响了多少行,MyBatis自动判断
        如果是boolean,影响0行自动封装为false,否则为true,
        参数类型也不用写
        #{属性名}-->

    <update id="updateEmployee" parameterType="com.citi.entity.Employee">
        UPDATE t_employee
        SET empname = #{empName},
        gender = #{gender},
        email = #{email}
        WHERE id = #{id}
    </update>

    <delete id="deleteEmployee">
        DELETE FROM t_employee WHERE id = #{id}
    </delete>

    <insert id="insertEmployee" useGeneratedKeys="true" parameterType="com.citi.entity.Employee">
        INSERT INTO t_employee(empname,gender,email) values (#{empName},#{gender},#{email})
    </insert>
</mapper>

在resource目录下增加日志配置

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
   <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
       <encoder>
           <pattern>[%thread] %d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n</pattern>
       </encoder>
   </appender>

    <!--
        日志输出级别(优先级高到低):
        error: 错误 - 系统的故障日志
        warn: 警告 - 存在风险或使用不当的日志
        info: 一般性消息
        debug: 程序内部用于调试信息
        trace: 程序运行的跟踪信息
     -->
    <root level="debug">
        <appender-ref ref="console"/>
    </root>
</configuration>

新增EmployeeDaoTest测试类

代码语言:javascript
复制
public class EmployeeDaoTest {

    SqlSessionFactory sqlSessionFactory = null;
    SqlSession openSession = null;

    @Before
    public void setUp() throws Exception {

        //1、根据全局配置文件创建出一个SqlSessionFactory
        //SqlSessionFactory:是SqlSession工厂,负责创建SqlSession对象;
        //SqlSession:sql会话(代表和数据库的一次会话);
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        openSession = sqlSessionFactory.openSession();

    }

    @Test
    public void getEmpById() throws Exception{

        EmployeeDao employeeDao = openSession.getMapper(EmployeeDao.class);
        Employee employee = employeeDao.getEmpById(1);

        System.out.println(employee);
    }


    @Test
    public void updateEmployee() {
        EmployeeDao employeeDao = openSession.getMapper(EmployeeDao.class);
        Employee updateEmployee = new Employee();
        updateEmployee.setId(1);
        updateEmployee.setEmpName("Tony Stark");
        updateEmployee.setEmail("stark@stark-industry.com");
        updateEmployee.setGender(0);
        employeeDao.updateEmployee(updateEmployee);

        Employee employee = employeeDao.getEmpById(1);
        System.out.println(employee);
    }

    @Test
    public void deleteEmployee() {

        EmployeeDao employeeDao = openSession.getMapper(EmployeeDao.class);
        System.out.println(employeeDao.getEmpById(6));

        boolean isDelete = employeeDao.deleteEmployee(6);
        System.out.println(isDelete);
    }

    @Test
    public void insertEmployee() {

        Employee employee = new Employee();
        employee.setEmpName("peter");
        employee.setGender(0);
        employee.setEmail("peter@gmail.com");

        EmployeeDao employeeDao = openSession.getMapper(EmployeeDao.class);
        employeeDao.insertEmployee(employee);
        System.out.println(employeeDao.getEmpById(2));
    }

    @After
    public void tearDown() throws Exception {

        openSession.close();
    }
}

执行测试方法,验证项目是否可以成功运行

properties属性-引入外部文件

在resource目录下新建db.properties,配置数据库连接信息

代码语言:javascript
复制
jdbc_driver=com.mysql.cj.jdbc.Driver
jdbc_url=jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=utf8&amp;autoReconnect=true&amp;useSSL=false&amp;serverTimezone=Asia/Shanghai
jdbc_username=root
jdbc_password=root

修改mybatis全局配置文件,引入properties,并修改数据库连接配置

在configuration标签下增加properties标签

代码语言:javascript
复制
<properties resource="db.properties" />

properties标签有两个属性,都可以标识引入文件的位置

  • resource:从类路径下开始引用
  • url:引用磁盘或者网络路径下的资源

修改datasource标签下的数据库连接配置,使用${}引用数据库配置文件的配置信息

代码语言:javascript
复制
<dataSource type="POOLED">
    <property name="driver" value="${jdbc_driver}"/>
    <property name="url" value="${jdbc_url}"/>
    <property name="username" value="${jdbc_username}"/>
    <property name="password" value="${jdbc_password}"/>
</dataSource>

执行getEmpById测试方法

image.png
image.png

一定要将properties放在第一个,否则会报错

image.png
image.png

settings属性-改变MyBatis运行时行为

settings是MyBatis中极为重要的配置,它会改变MyBatis的运行时行为。 mapUnderscoreToCamelCase是否开启驼峰命名自动映射,即将数据库字段名 A_COLUMN 映射到实体类属性名 aColumn(数据库字段不区分大小写,但是区分是否有下划线“_”);默认是false即不开启

t_employee表增加一个字段create_time,并给字段赋值为当前时间,同时Employee实体类也需要增加一个属性createTime

image.png
image.png
代码语言:javascript
复制
@Data
public class Employee {

    private Integer id;
    private String empName;
    private String email;
    private Integer gender;
    private Date createTime;
}

执行测试getEmpById()测试方法

image.png
image.png

createTime为空说明在数据库字段中没有找到createTime字段,而我们命名的字段为create_time,解决这个问题可以的办法是可以在修改SQL给查询字段增加别名使其与数据库字段一致害可以在mybatis全局配置中增加settings属性,开启自动驼峰命名转换,注意settings配置一定要在properties配置的下面

代码语言:javascript
复制
<settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
  • name:配置项的Key
  • value:配置项的值 可以配置的Key有很多,具体可以点击此处查看

再次执行测试

image.png
image.png

成功获取到了createTime的值

typeAliases属性-为类型起别名

类型别名可为 Java 类型设置一个缩写名字。 它仅用于MyBatis全局 XML 配置,意在降低冗余的全限定类名书写

代码语言:javascript
复制
<typeAliases>
  <typeAlias alias="Employee" type="com.citi.entity.Employee"/>
</typeAliases>

alias指定一个别名,如果不指定,默认就是类名

在需要起别名的类非常多的时候,可以通过package属性批量起别名

代码语言:javascript
复制
<typeAliases>
    <package name="com.citi.entity"/>
</typeAliases>

批量的时候如果需要对某个类起一个非默认的别名,可以在实体类上增加注解@Alias增加别名 修改映射文件employee.xml中select标签,将返回内容resultType从com.citi.entity.Employee改为Employee,定义类别名之后就可以识别到

代码语言:javascript
复制
<select id="getEmpById" resultType="Employee">
    select * from t_employee where id = #{id}
</select>

再次执行测试

image.png
image.png

推荐使用全类名,可以快速定位

typeHandlers属性-类型处理器

MyBatis 在设置预处理语句(PreparedStatement)中的参数或从结果集中取出一个值时, 都会用类型处理器将获取到的值以合适的方式转换成 Java 类型。

代码语言:javascript
复制
<typeHandlers>
    <!--配置自定义的类型处理器-->
    <typeHandler handler="自定义类型处理器" />
</typeHandlers>

MyBatis已经定义好了大部分的类型处理器,遇到枚举类型可能需要进行自定义类型处理器。该配置使用频次较低

objectFactory(对象工厂)

MyBatis将查询到的数据使用objectFactory利用反射封装成对象,使用频次较低

plugins属性

MyBatis 允许你在映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:

  • Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
  • ParameterHandler (getParameterObject, setParameters)
  • ResultSetHandler (handleResultSets, handleOutputParameters)
  • StatementHandler (prepare, parameterize, batch, update, query)

插件通过动态代理机制,可以介入上面四大对象的任何一个方法的执行

environment属性-支持多环境切换

MyBatis通过environments标签配置多个环境,如开发、测试、生产环境等,可以通过default属性是指默认的环境或者切换环境

每一个environment指一个环境,id属性是这个环境的唯一标识

事务控制会使用Spring的事务控制,数据元配置会使用如druid、c3p0等数据库连接工具,不会使用原生的数据库驱动

databaseProvider-数据库移植

MyBatis 可以根据不同的数据库厂商执行不同的语句,这种多厂商的支持是基于映射语句中的 databaseId 属性。 MyBatis 会加载带有匹配当前数据库 databaseId 属性和所有不带 databaseId 属性的语句

代码语言:javascript
复制
<databaseIdProvider type="DB_VENDOR">
    <property name="MySQL" value="mysql"></property>
    <property name="Oracle" value="orcl"></property>
</databaseIdProvider>

SQL映射文件中可以根据不同的数据库增加不同的SQL语句

代码语言:javascript
复制
<select id="getEmpById" resultType="Employee" databaseId="orcl">
    select * from t_employee where id = #{id}
</select>

使用频次较低

mappers-批量注册

我们需要告诉 MyBatis 到哪里去找到这些语句。 在自动查找资源方面,Java 并没有提供一个很好的解决方案,所以最好的办法是直接告诉 MyBatis 到哪里去找映射文件。 你可以使用相对于类路径的资源引用,或完全限定资源定位符(包括 file:/// 形式的 URL),或类名和包名等

代码语言:javascript
复制
<!-- 使用相对于类路径的资源引用 -->
<mappers>
    <mapper resource="mappers/employee.xml"/>
</mappers>
代码语言:javascript
复制
<!-- 使用完全限定资源定位符(URL) -->
<mappers>
  <mapper url="file:///var/mappers/employee.xml"/>
</mappers>
代码语言:javascript
复制
<!-- 使用映射器接口实现类的完全限定类名,要保证xml文件和接口名相同并在同一目录下-->
<mappers>
  <mapper class="com.citi.dao.EmployeeDao"/>
</mappers>
代码语言:javascript
复制
<!-- 将包内的映射器接口实现全部注册为映射器,要保证xml文件和接口名相同并在同一目录下 -->
<mappers>
  <package name="com.citi.dao"/>
</mappers>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-02-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、MyBatis Configuration XML
    • 工程搭建
      • properties属性-引入外部文件
        • settings属性-改变MyBatis运行时行为
          • typeAliases属性-为类型起别名
            • typeHandlers属性-类型处理器
              • objectFactory(对象工厂)
                • plugins属性
                  • environment属性-支持多环境切换
                    • databaseProvider-数据库移植
                      • mappers-批量注册
                      相关产品与服务
                      数据库
                      云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档