Mybatis-Day02

1、Mybatis别名

内置别名

常用基本类型、包装类型、集合类型

自定义别名

​ 第一种形式:直接配置类

<typeAlias type="cn.itsource.mybatis.query.ProductQuery" 
           alias="productQuery"></typeAlias>
<typeAlias type="cn.itsource.mybatis.domain.Product" 
           alias="product"></typeAlias>

​ 第二种形式:配置包名(推荐使用)

<typeAliases>
	<package name="cn.itsource.mybatis.query"></package>
    <package name="cn.itsource.mybatis.domain"></package>
</typeAliases>

2、映射器

ProductMapper(接口)不写实现类,Mybatis底层采用动态代理模式 自动实现

(1)创建项目

(2)创建ProductMapper接口,定义抽象方法

package cn.itsource._01Mapper.mapper;

import cn.itsource._01Mapper.domain.Product;
import java.util.List;

public interface ProductMapper {
    List<Product> findAll();
}

(3)在对应的ProductMapper.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="cn.itsource._01Mapper.mapper.ProductMapper">
    <select id="findAll" resultType="product">
        select * from product
    </select>
</mapper>

(4)测试接口方法

 @Test
    public void testQuery(){
        //映射器
        ProductMapper productMapper = myBatisUtil.INTANCE.getSqlSession().
        getMapper(ProductMapper.class);
        List<Product> all = productMapper.findAll();
        for (Product product : all) {
            System.out.println(product);
        }
    }

3、高级查询(模糊查询)

 <select id="findByQuery" parameterType="productQuery" resultType="product">
        select * from product
        <where>
            这种方式存在sql注入问题
           <!-- <if test="productName!=null">
                and productName like '%${productName}%'
            </if>-->
            最佳写法(推荐)
            <if test="productName!=null">
                and productName like concat('%',#{productName},'%')
            </if>
            <!--<if test="minPrice != null and  maxPrice != null">
                and salePrice > #{minPrice} and salePrice &lt;#{maxPrice}
            </if>-->
            特殊符号转义问题解决:大小写等符号不被转义
            <if test="minPrice != null and  maxPrice != null">
                <![CDATA[
                  and salePrice > #{minPrice} and salePrice <= #{maxPrice}
                ]]>
            </if>
        </where>

    </select>

4、结果映射

解决数据表的和对象的字段不统一的情况

方案一:取别名就可以解决
<select id="findAll"  resultType="product">
            select id,productName pName,salePrice,costPrice,cutoff from product
</select>
方案二:返回Map解决映射问题
<mapper namespace="cn.itsource._02result.mapper.ProductMapper">
    <!--结果映射处理-->
    <select id="findAll" resultMap="productMap">
        select id,productName,salePrice,costPrice,cutoff from product
    </select>
    <!--
    id:主键
    property:类里面的属性
    column:查询列名称
    -->
    <resultMap id="productMap" type="product">
        <id property="id" column="id"></id>
        <result property="pName" column="productName"></result>
        <result property="salePrice" column="salePrice"></result>
    </resultMap>
</mapper>

5、关系处理

关系

一对一:一个主管对应一个部门

一对多:一个部门对应多个员工

多对一:多个员工对应一个部门

多对多:用户角色 角色权限

处理一方

(多对一/一对多)

<resultMap id="productMap" type="product">
        <id property="id" column="id"></id>
        <result property="pName" column="productName"></result>
        <result property="salePrice" column="salePrice"></result>
        <result property="costPrice" column="costPrice"></result>
        <result column="cutoff" property="cutoff"></result>
        <!--方式一 嵌套结果 发送一条sql语句-->
        <!--<association property="productDir" javaType="productDir">
         <id column="did" property="id"></id>
         <result column="dname" property="dirName"></result>
        </association>-->
        <!--方式二-->
        <result property="productDir.id" column="did"></result>
        <result property="productDir.dirName" column="dname"></result>
        <!--嵌套查询 发送多条sql语句-->
       <!-- <association property="productDir" column="dir_id" 
			javaType="productDir" select="selectDir">
        </association>-->
    </resultMap>
    <!-- <select id="selectDir" parameterType="long" resultType="ProductDir">
        select * from productDir where id = #{dir_id}
    </select>-->
处理多方

(一对多/多对多)

<mapper namespace="cn.itsource._04one2many.mapper.ProductMapper">
    <!--结果映射处理-->
    <!-- 一对多的嵌套结果会有一个问题:查询结果是子集合分类而不是查询结果集合分类-->
    <select id="findAll" resultMap="productDirMap">
        select dir.id ,dir.Name dirName,
                p.id pid,p.productName pName,p.salePrice,p.costPrice,p.cutoff
        from productDir dir join product p
        on dir.id = p.dir_id limit 0,2
    </select>
    <resultMap id="productDirMap" type="productDir">
        <id property="id" column="id"></id>
        <result property="dirName" column="dirName"></result>
        <collection property="products" ofType="product">
            <id property="id" column="pid"></id>
            <result property="pName" column="pName"></result>
            <result property="salePrice" column="salePrice"></result>
            <result property="costPrice" column="costPrice"></result>
        </collection>
    </resultMap>  
</mapper>
Mybatis缓存
一级缓存

​ 默认开启

​ 属于sqlSession级别缓存(entityManager类似)

​ 命中条件:

​ mybatis一级缓存 命中(同一个SqlSessionFactory 同一个SqlSession 同一个ID)

@Test
    public void testMapper(){//一级缓存
        //得到mapper --映射器 (动态代理)
        SqlSession sqlSession =  myBatisUtil.INTANCE.getSqlSession();
        //mybatis一级缓存 命中(同一个SqlSessionFactory 同一个SqlSession 同一个ID)
        ProductMapper mapper1 = sqlSession.getMapper(ProductMapper.class);
        System.out.println(mapper1.findOne(19L));
        ProductMapper mapper2 = sqlSession.getMapper(ProductMapper.class);
        System.out.println(mapper2.findOne(19L));

    }
二级缓存

​ 需要开启条件 1、在ProductMapper.xml中配置cache 2、序列化对应的doamin

​ 命中条件: 同一个SqlSessionFactory 不同的SqlSession 同一个ID

@Test
    public void testSecondCacheMapper(){//二级缓存
        //得到mapper --映射器 (动态代理)
        SqlSession sqlSession1 =  myBatisUtil.INTANCE.getSqlSession();
        //mybatis一级缓存 命中(同一个SqlSessionFactory 同一个SqlSession 同一个ID)
        ProductMapper mapper1 = sqlSession1.getMapper(ProductMapper.class);
        System.out.println(mapper1.findOne(19L));
        sqlSession1.close();

        SqlSession sqlSession2 =  myBatisUtil.INTANCE.getSqlSession();
        ProductMapper mapper2 = sqlSession2.getMapper(ProductMapper.class);
        System.out.println(mapper2.findOne(19L));
        sqlSession2.close();

    }

ProductMapper.xml配置cache

<mapper namespace="cn.itsource._05cache.mapper.ProductMapper">
    <select id="findOne" parameterType="long"  resultType="product">
        select id,productName pName,salePrice,costPrice,cutoff from product 
        where id = #{id}
    </select>
    <!--开启二级缓存需要的配置-->
    <cache></cache>
</mapper>

序列化Product(实现Serializable接口)

public class Product implements Serializable{
    
}

6、扩展

扩展一

处理一方的第二种方式

<resultMap id="productMap" type="product">
        <id property="id" column="id"></id>
        <result property="pName" column="productName"></result>
        <result property="salePrice" column="salePrice"></result>
        <result property="costPrice" column="costPrice"></result>
        <result column="cutoff" property="cutoff"></result>
        <!--方式一 处理一方-->
        <!--<association property="productDir" javaType="productDir">
         <id column="did" property="id"></id>
         <result column="dname" property="dirName"></result>
        </association>-->
        <!--方式二 相当于直接把查询出来的列的值直接赋给属性对象的属性-->
        <result property="productDir.id" column="did"></result>
        <result property="productDir.dirName" column="dname"></result>     
    </resultMap>
扩展二

解决一对多查询存在的小问题

<mapper namespace="cn.itsource._04one2many.mapper.ProductMapper">
    <!--结果映射处理-->
    <!-- 一对多的嵌套结果会有一个问题:查询结果是子集合分类而不是查询结果集合分类-->
    <!--<select id="findAll" resultMap="productDirMap">
        select dir.id ,dir.Name dirName,
                p.id pid,p.productName pName,p.salePrice,p.costPrice,p.cutoff
        from productDir dir join product p
        on dir.id = p.dir_id limit 0,2
    </select>
    <resultMap id="productDirMap" type="productDir">
        <id property="id" column="id"></id>
        <result property="dirName" column="dirName"></result>
        <collection property="products" ofType="product">
            <id property="id" column="pid"></id>
            <result property="pName" column="pName"></result>
            <result property="salePrice" column="salePrice"></result>
            <result property="costPrice" column="costPrice"></result>
        </collection>
    </resultMap>-->

    <!--解决嵌套查询结果的问题,相当于先分页查询分类,然后再根据分类id查询相应产品-->
    <select id="findAll" resultMap="productDirMap">
        select dir.id ,dir.name from productDir dir limit 0,2
    </select>

    <resultMap id="productDirMap" type="productDir">
        <id property="id" column="id"></id>
        <result property="dirName" column="dirName"></result>
        <collection property="products" column="id" ofType="product" select="selectProducts">
        </collection>
    </resultMap>
    <select id="selectProducts" parameterType="long" resultType="product">
        select id,productName pName,salePrice,costPrice,cutoff
         from product where dir_id = #{dir_id}
    </select>

</mapper>

7、ssm集成

常用开发框架整合:

​ sss – springmvc+spring+springjdbc (项目一)

​ sssdj – springmvc+spring+springdatajpa(项目二) 中小型的项目

​ ssm – springmvc+spring+mybatis(项目三/项目四) 中型项目/大型项目

ssm框架整合步骤
(1)创建项目

​ web项目 (maven/普通web)

(2)导入三个框架的jar包
(3)配置文件
applicationContext.xml

​ (配置spring+mybatis)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
">
    <!--扫描包-->
    <context:component-scan base-package="cn.itsource.ssm.service"></context:component-scan>

    <!--引入jdbc.properties-->
    <context:property-placeholder location="classpath:db.properties"/>

    <!--创建数据库连接池DataSource-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!--配置sqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="mapperLocations" value="classpath:cn/itsource/ssm/domain/*Mapper.xml"></property>
        <property name="typeAliasesPackage">
            <value>
                cn.itsource.ssm.domain
            </value>
        </property>
    </bean>

    <!--把mapper交给spring管理-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="cn.itsource.ssm.mapper"></property>
    </bean>

    <!--配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
    <!--开启事务注解的支持,默认会去找一个名称叫做transactionManager的事务管理器 -->
    <tx:annotation-driven transaction-manager="transactionManager" />

</beans>
applicationCotnext-mvc.xml

​ (配置springmvc)

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--扫描controller-->
    <context:component-scan base-package="cn.itsource.ssm.web.controller" />
    <!--静态资源处理-->
    <mvc:default-servlet-handler />
    <!--开启注解支持-->
    <mvc:annotation-driven />
    <!--配置视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/" />
        <property name="suffix" value=".jsp" />
    </bean>
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <!--spring核心-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <!--监听器-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!--springMvc核心控制器-->
    <servlet>
        <servlet-name>dispatchServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatchServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <!--编码过滤器-->
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>
db.properties

​ (配置数据库连接信息)

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///mybatis
jdbc.username=test
jdbc.password=123
log4j.properties

​ (配置日志信息)

log4j.rootLogger=ERROR, stdout
#log4j.rootLogger=NONE
log4j.logger.cn.itsource=TRACE

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值