Mybatis

1 核心配置文件(非必写)

        因为以后会将"Mybatis主配置文件"集成到"Spring配置文件"中,而Spring配置文件又可以被配置类替代

<?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>
	<!--引入配置文件,引用方式${key}-->
	<properties resource="config.properties"/>

	<!--设置Mybatis全局配置-->
	<settings>
		<setting name="logImpl" value="SLF4J"/><!--非必须设置,只要有logback.properties放在resource目录下即可-->
		<!--懒加载开关(默认false),只是针对没有明确申明是否懒加载的关联查询,具体以”映射配置文件”resultMap标签下的<association>或<collection>的fetchType属性为准,注解开发以@One或@Many的fecheType为准-->
		<setting name="lazyLoadingEnabled" value="true"/>
		<!--懒加载的”积极加载”开关(默认false):true表示与字段属性值相关的所有”从查询”都执行-->
		<setting name="aggressiveLazyLoading" value="false"/>
        <!--二级缓存的全局开关(默认true)-->
		<setting name="cacheEnabled" value="false"/>
	</settings>

	<!--给JavaBean起别名(不区分大小写)-->
	<typeAliases>
		<!--给某一JavaBean起别名-->
        <typeAlias type="com.sunner.beans.User" alias="user"/>
		<!--给某一包下的所有JavaBean起别名(类名就是别名)-->
        <package name="com.sunner.beans"/>
    </typeAliases>

    <!--数据库环境信息合集  default属性:选择一个对应的数据库环境的id-->
	<environments default="mysql">
        <environment id="mysql">
            <transactionManager type="JDBC"/>   <!--使用JdbcTransactionManager事务管理器-->
            <dataSource type="POOLED">   <!--配置数据源(类型有3种):POOLED使用连接池(推荐);UNPOOLED不使用连接池;JNDI不在项目里面配置,而是配置在Tomcat里面-->
                <property name="driver" value="${mysql.driver}"/>
                <property name="url" value="${mysql.url}"/>
                <property name="username" value="${mysql.username}"/>
                <property name="password" value="${mysql.password}"/>
            </dataSource>
        </environment>
    </environments>

    <!--映射配置文件合集-->
	<mappers>
        <!--<mapper resource="com/sunner/dao/UserDao.xml"/>-->   <!--使用XML映射配置文件开发(映射配置文件的名称和位置不重要)-->    
        <!--<mapper class="com.sunner.dao.UserDao"/>-->    <!--使用注解开发:在UserDao接口对应的方法上加上@Select("SQL语句")-->
		<package name="com.sunner.dao"/>   <!--将某一包下所有Dao映射器接口注册(如果是XML方式开发:配置文件和dao接口路径和名字相同)   (xml开发和注解开发不能同时存在)-->
    </mappers>
</configuration>

2 映射配置文件

<?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="xyz.aboluo.UserDao">  <!--namespace对应dao接口的全限定类名-->
	<cache/>  <!--让映射配置文件支持二级缓存-->  <!--让该映射配置文件中的SQL标签支持二级缓存:SQL标签体增加属性userCache=”true”-->
    
    <sql id="selectAllUser_sql">   <!--将SQL语句提取出来,用<include refid="sqlLabel"/>引用-->
		select * from user
	</sql>

	<!--查询结果封装(单对象或List<对象>),如果封装成List<Object>,即使查得为0,也会生成长度为0的List集合-->  <!--extends继承其它<resultMap>,避免重复写封装字段-->
	<resultMap id="user" extends=”person” type="user">
        <id column="id" property="userId"/>   <!--<id>标签(区别于<result>):如果查得的该字段为null,结果不会合并:比如查到的2个user信息完全相同(但userId为null),那么它们关联的Account并不会封装在同一个List<Account>中-->
        <result column="user_name" property="userName"/>

		<association property=”userAccount” javaType=”account”>  <!--属性关联的是"单个对象"-->
			<id column="account_id" property="accountId"/>
            <result column="account_name" property="accountName"/>
            <result column="user_id" property="userId"/>
		</association>

        <collection property="userAccounts" ofType="account">  <!--属性关联的是"多个对象",ofType只支持List(不支持数组)-->
            <id column="account_id" property="accountId"/>
            <result column="account_name" property="accountName"/>
            <result column="user_id" property="userId"/>
        </collection>

        <!--分步查询-->
		<!--懒加载(主查询+从查询):主查询只会执行一次,查询的结果封装到一个JavaBean中,每当我们使用(不管是log4j打印,还仅仅是debug查看)该JavaBean指定的"从查询属性",再进行一次从查询
            select:指定"从查询"(的映射配置文件+SQL的id)
            column:将"主查询"的某一个字段,作为"从查询"的参数"-->
        <association property="userAccount" javaType="account" select="com.sunner.dao.AccountDao.findById" column="user_pk" fetchType=”eager”/>   <!--非懒加载:一对一-->
		<collection property="userAccounts" ofType="account" select="com.sunner.dao.RoleDao.findById" column="user_pk" fetchType=”lazy”/>     <!--懒加载:一对多-->     <!--多对多需要创建”中间表”-->
    </resultMap>

	<!--parameterType:  ${}本质是”字符串拼接(要手动加单引号'')”      #{}本质是"占位符(?)赋值(前后会自动加单引号'')",可以防止SQL注入,并会自动类型转换(例如把JAVA中的Date转换为MySQL中的timestamp)
		有1个参数:参数为简单类型:参数类型可以省略java.lang    取值:${固定value},#{随便写}
				 参数为Array或List:参数类型为arraylist      取值:array[0]/list[0]
		有多个参数:不推荐:parameterType不写,mybatis会将多个参数放在一个map集合中(用arg0、arg1...或param1、param2...表示key)    取值:${arg0},#{param1}
                        可以使用@Param("userName")来自定义命名多个参数的key,当然此时的arg0和arg1依旧在map中可以被使用
                  推荐:手动改变到接口方法的参数,将多个参数放在一个pojo类或Map中
		▲模糊查询时,不可以用'%#{aaa}%',因为会被当成一整个字符串,可以用"%"#{aaa}"%"-->
	<insert id="saveUser" parameterType="user">  <!--对于DDL(insert,update,delete)标签,会返回修改的行数int-->
		<!--selectKey查询insert执行后表中的最新的”自增主键”
            resultType查询得到的主键值会被强转成我们指定的数据类型
            keyProperty写的不是字段,而是类属性,将强转后的数据赋值给parameterType属性(即参数可能会被改变)
            order(mysql数据库用AFTER):获取insert之后的最新主键值-->
        <selectKey resultType="int" keyProperty="age" order="AFTER">
            select last_insert_id();
        </selectKey>
        insert into user (username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address});
    </insert>

	<select id="findEligibleUser" parameterType="user" resultMap="userMap">   <!--判断查询的方式:1.使用if标签  2.在SQL中使用IF-->
		<include refid="selectAllUser_sql"/>  
		<where>  <!--where标签,将SQL语句开头的一个and|or|not去掉(标签体中无数据不生效)-->
			<if test="username==’张三’ or userName!=’’ and userName.length>0">  <!--userName.length针对数组/String   userName.size针对集合-->
				and username=#{userName}
			</if>
			<if test="_parameter==-1">  <!--在标签属性中_parameter代表所有参数本身-->
				 order by rand() limit 1;
			</if>
			and sex = if(#{userSex}='男','男','女');
		</where>
	</select>
	
	<select id="findEligibleUser" parameterType="map" resultMap="userMap">
        <include refid="selectAllUser_sql"/>
		<!--先:去掉最前面的prefixOverrides,去掉最后面的suffixOverrides    后:最前面加上prefix,最后面加上suffix-->
        <trim prefixOverrides="and|or|not" suffixOverrides="abcd" prefix="where" suffix=";">
            and username=#{userName} abcd
        </trim>
		<!--foreach标签:collection="(数组/集合)属性名"  open="SQL语句的开始"  close="SQL语句的结束"  item="collection中遍历出来的数据"  separator="标签体中每次循环的SQL最后加分隔符(最后一个值不加)"-->
        <foreach collection="idArray" open="where id in(" close=")" item="aaa" separator=",">
            #{aaa}
        </foreach>
	</select>
</mapper>

3 注意事项

SqlSession对象要不能被共享:因为SqlSession对象线程不安全,要在请求范围(比如方法)内生成并使用,决不能将SqlSession放到静态属性中,所以在SpringIOC容器中的SqlSession用多例对象

        mybatis的事务是通过SqlSession对象的commit方法和rollback方法实现事务的提交和回滚

首先新建一个(或者从SpringIOC获取一个)SqlSession对象,然后通过动态代理根据"映射配置文件"生成一个方法被增强的Dao接口实现类的Mapper对象(同一个SqlSession对象.getMapper(字节码对象)获取的Mapper对象都不同),然后用Mapper对象执行对应的"增强方法"(本质是sqlSession.sql)

一级缓存(默认开启,无法关闭):只要执行的是同一个sqlSession.sql查询,且参数一样,不再和数据库交互,而会从缓存中取数据

        清空一级缓存:sqlSession消失sqlSession.close(),清空sqlSession.clearCache(),提交sqlSession.commit(),执行DML

二级缓存(不常用):多个sqlSession共享的缓存

4 注解开发

(不推荐)

@Insert

@Delete

@Update

@Select

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值