3Mybatis之配置解析和解决属性名与字段名不一致问题

配置解析和解决属性名与字段名不一致问题

1核心配置文件介绍

  • MyBatis的配置文件包含了会深深影响MyBatis行为的设置和属性信息
  • mybatis-config.xml系统核心配置文件
  • 能配置的内容如下
  • properties(属性)
  • settings(设置)
  • typeAliases(类型别名)
  • typeHandlers(类型处理器)
  • objectFactory(对象工厂)
  • plugins(插件)
  • environments(环境配置):environment(环境变量)(包括transactionManager(事务管理器)和dataSource(数据源))
  • databaseIdProvider(数据库厂商标识)
  • mappers(映射器)
  • 注意元素节点的顺序,顺序不对会报错

2环境配置(enviroments)

  • Mybatis可以配置成适合多种环境,不过尽管可以配置多个环境,但每个SqlSessionFactory实例只能选择一种环境
  • 可以通过default指定默认运行环境
  • 子元素结点:enviroment
  • 其中dataSource元素使用标准的JDBC数据源接口来配置 JDBC 连接对象的资源
  • 数据源是必须配置的
  • 有三种内建的数据源类型,type="[UNPOOLED|POOLED|JNDI]")
  • unpooled:这个数据源的实现只是每次被请求时打开和关闭连接
  • pooled:这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来 , 这是一种使得并发 Web 应用快速响应请求的流行处理方式
  • jndi:这个数据源的实现是为了能在如 Spring 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用
  • 数据源也有很多第三方的实现,比如dbcp,c3p0,druid等等
<!--  mybaits-config.xml中  -->
	<environments default="test">
        
        <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&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=UTC"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
        
        <environment id="test">
            <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>

3属性(properties)

  • 我们可以通过properties属性来实现引用配置文件
  • 这些属性是可外部配置且可动态替换的,即可以在典型的java属性文件中配置,也可以通过properties元素的子元素来传递
  • 即可以编写一个配置文件:db.properties(在resources下)
  • 可以直接引入外部文件,也可以在其中增加一些属性配置,如果两个文件有同一字段,优先使用外部配置文件的
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username=root
password=root
<!--  mybaits-config.xml中  -->
<!--所有位置信息一定要确定    -->
    <!--引入外部配置文件    -->
    <properties resource="db.properties">
    <!--下面这个是可选的 不加也不要紧 当外部和下面都有时候 优先外部文件        -->
        <property name="username" value="root"/>
        <property name="pwd" value="root"></property>
    </properties>
   <!--  可以直接<properties resource="db.properties"/>  -->

	<environments default="test">
 		<environment id="test">
            <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>

4类型别名(typeAliases)

  • 类型别名是为 Java 类型设置一个短的名字
  • 它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余
<!-- 可以给实体类起别名   -->
    <typeAliases>
    <!--    方式一    -->
    <!--    当这样配置时,User可以用在任何使用com.fao.pojo.User的地方    -->
            <typeAlias type="com.fao.pojo.User" alias="User"></typeAlias>
    </typeAliases>
  • 也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,比如
  • 每一个在包 comfao.pojo 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。
    <typeAliases>
 	<!--方式二-->
                <package name="com.fao.pojo"/>    
    </typeAliases>
  • 若有注解,则别名为其注解值
@Alias("userZiDingYi")
public class User {
  ...
}

5设置和其他配置(先了解为主)

  • 设置:logImpl:指定MyBatis所用日志的具体实现,未指定时将自动查找。其他还有:LOG4J, LOG4J2, JDK_LOGGING, COMMONS_LOGGING, STDOUT_LOGGING等
  • 其他配置:typeHandlers(类型处理器),objectFactory(对象工厂)

6映射器(mappers)

  • 注册绑定我们的Mapper文件
<!--    每一个Mapper.xml都需要在Mybatis核心配置文件中注册-->
    <mappers>
	<!--  方式一  -->
        <mapper resource="com/fao/dao/UserMapper.xml"/>
	<!--  方式二  -->
<!--        <mapper class="com.fao.dao.UserMapper"></mapper>-->
	<!--  方式三  -->
<!--        <package name="com.fao.dao"/>-->
    </mappers>

​ 方式二,三注意点

  • 接口和它的Mapper配置文件必须同名
  • 接口和他的Mapper配置文件必须在同一个包下
  • 所以还是推荐使用第一个

7生命周期和作用域

  • 理解我们目前已经讨论过的不同作用域和生命周期类是至关重要的,因为错误的使用会导致非常严重的并发问题

  • SqlSessionFactoryBuilder 的作用在于创建 SqlSessionFactory,创建成功后,SqlSessionFactoryBuilder 就失去了作用,所以它只能存在于创建 SqlSessionFactory 的方法中,而不要让其长期存在。因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)
  • SqlSessionFactory 可以被认为是一个数据库连接池,它的作用是创建 SqlSession 接口对象。因为 MyBatis 的本质就是 Java 对数据库的操作,所以 SqlSessionFactory 的生命周期存在于整个 MyBatis 的应用之中,所以一旦创建了 SqlSessionFactory,就要长期保存它,直至不再使用 MyBatis 应用,所以可以认为 SqlSessionFactory 的生命周期就等同于 MyBatis 的应用周期。在一般的应用中我们往往希望 SqlSessionFactory 作为一个单例,让它在应用中被共享。所以说 SqlSessionFactory 的最佳作用域是应用作用域
  • SqlSession 就相当于一个数据库连接(Connection 对象),你可以在一个事务里面执行多条 SQL,然后通过它的 commit、rollback 等方法,提交或者回滚事务。所以它应该存活在一个业务请求中,处理完整个请求后,应该关闭这条连接,让它归还给 SqlSessionFactory,否则数据库资源就很快被耗费精光,系统就会瘫痪,所以用 try...catch...finally... 语句来保证其正确关闭。所以 SqlSession 的最佳的作用域是请求或方法作用域。

8解决属性名和字段名不一致的问题

  • 新建一个项目,将实体类的字段特地设置成不一样的(pwd变成password)
public class User {

   private int id;  //id
   private String name;   //姓名
   private String password;   //密码和数据库不一样!
   
   //构造
   //set/get
   //toString()
}

​ 方法一:起别名

    <select id="getUserById" parameterType="int" resultType="User">
        select id,name,pwd as password from mybatis.user where id=#{id}
    </select>

​ 方法二:resultMap结果映射集(推荐)

    <!--  在UserMapper.xml中设置结果集映射  -->
    <resultMap id="UserMap" type="User">
        <!--  column数据库中的字段 property实体类的属性  -->
		<!--  <result column="id" property="id"/>  -->
		<!--  <result column="name" property="name"/>  -->
        <result column="pwd" property="password"/>
    </resultMap>

    <select id="getUserById" parameterType="int" resultMap="UserMap">
        select id,name,pwd from mybatis.user where id=#{id}
    </select>

9ResultMap

  • resultMap 元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来
  • 实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份 resultMap 能够代替实现同等功能的长达数千行的代码
  • resultMap 的设计思想是,对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了
  • 最简单的映射语句就是之前的万能map,虽然在大部分情况下都够用,但是 HashMap 不是一个很好的模型。你的程序更可能会使用 JavaBean 或 POJO(Plain Old Java Objects,普通老式 Java 对象)作为模型,因此需要要用resultMap手动映射
  • 如果世界总是这么简单就好了。但是肯定不是的,数据库中,存在一对多,多对一的情况,我们之后会使用到一些高级的结果集映射,association,collection这些,现在先理解结果集映射的这个概念就行!
posted @ 2022-05-21 12:15  fao99  阅读(211)  评论(0)    收藏  举报