ssm(1-1)mybatis

1.概念

2.完全基于配置

2.1非接口式

mybatisBaseCongfig.xml

<?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>
   <!--不能用classpath:以及/,也不能使用通配符-->  
    <properties resource="dataresouce.properties"></properties>

    <settings>
        <!--驼峰式命名,例如t_id 会变为tId-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>

        <!--设置日志管理文件,log4j的日志名称需要为LOG4J.xml放在类路径下-->
        <setting name="logImpl" value="LOG4J"/>

        <!--默认值为true,假如为false表示整个都不能使用二级缓存-->
        <setting name="cacheEnabled" value="true"/>

        <!--下列两个一起使用在某种程度上可以提高效率,但是懒加载在关闭session之后会存在异常-->
        <!--lazyLoadingEnabled为true 表示延迟加载-->
        <!--<setting name="lazyLoadingEnabled " value="true"/>-->

        <!--"aggressiveLazyLoading "为false表示按需加载,否则加载所有惰性属性-->
        <!--<setting name="aggressiveLazyLoading " value="fasle"/>-->

    </settings>

    <typeAliases>
        <!--别名,在mapper的文件中书写返回值参数和参数时,在其包下的可以是使用别名,类名小写-->
        <package name="cn.mybatis.bean"/>
        <!--单独别名,与上不能一起使用-->
        <!--<typeAlias type="cn.mybatis.bean.Department"  alias="dept"/>-->
    </typeAliases>

    <!--default默认使用哪个environment id-->
    <environments default="mysql">
        <environment id="mysql">
            <!--type 2个值  JDBC 使用jdbc管理   manager 交由其他管理-->
            <transactionManager type="JDBC"/>
            <!--POOLED使用连接池继续  unpooled  不适用连接池  jndi  使用其他的连接池-->
            <dataSource type="POOLED">
                <property name="username" value="${jdbc.user}"/>
                <property name="password" value="${jdbc.password}"/>
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
            </dataSource>
        </environment>
    </environments>

    <!-- type="DB_VENDOR" Vendordatabaseidprovider 作用就是根据不同厂商的标识,来标识执行不同的sql语句,如MYSQL,Oracle-->
    <databaseIdProvider  type="DB_VENDOR">
        <property name="MYSQL" value="mysql"></property>
        <property name="Oracle" value="oracle"></property>
    </databaseIdProvider>

    <mappers>
            <!--mapper接口的包,与其他两种不能共用-->
            <!--<package name="cn.mybatis.dao"/>-->
            <!--mapper.xml的文件,不能用classpath:以及/,也不能使用通配符-->
            <mapper resource="mapper/emp-mapper.xml" />
            <!--mapper接口-->
            <!--<mapper class="cn.mybatis.dao.*"/>-->
    </mappers>

</configuration>

 mapper

<?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">
<!--该配置为非接口的方式,namespace可以随意的写-->
<mapper namespace="a.b">
    <!--默认二级缓存是关闭的,
    eviction缓存回收策略,4个参数如下:
    lru最近最少使用,移除最长时间不用的对象,
    fifo,先进先出的移除策略,
    soft,软引用,
    weak弱引用,默认使用LRU,

    type:使用其他类型的缓存,例如ehcache
    flushinterval:刷新时间,默认新的sql被执行时刷新缓存,insert 、update、delete 后缓存会被刷新清空,
    size缓存对象数量,默认值为1024,
    readonly:为true的话表示只读,不能修改,效率快不安全,false表示利用序列化和反序列化的技术,效率会低一些,但是安全,
    默认是false,假如为false,那么bean需要实现序列化接口,查出的数据默认先放入一级缓存,只有在关闭会话以后才放入二级缓存,
    blocking:默认为false,当指定为true时将采用BlockingCache进行封装,
    使用BlockingCache会在查询缓存时锁住对应的Key,如果缓存命中了则会释放对应的锁,否则会在查询数据库以后再释放锁,
    这样可以阻止并发情况下多个线程同时查询数据。
    -->
    <!--<cache readOnly="true" />-->
    <!--使用ehcache的二级缓存 ,配置文件名称为ehcache.xml,需要放在类路径下-->
    <cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

    <!--一个参数,参数类型可以不写,如下的#{id}的id可以随意写-->
    <!--<< ,>> ,& &, ' ', ""  针对性的特殊字符处理-->
    <!--<![CDATA[<]]> 处理特殊字符-->
    <!--该配置为非接口的方式,id可以随意的写-->
    <!-- 参数:
     resultType:返回值类型,这里在前面写了typeAliases  package所以能这样写,否则全类名
     parameterType:参数类型,可以时bean,可以时map(别名,见官方文档),
     statementType: 默认值prepared,还有statement与callable,
     usecache:true表示使用二级缓存,为false,表示不使用二级缓存
     flushcache:true每次发送新的sql,增删改默认值为true,会刷新一级缓存和二级缓存,查询flushcache默认为false
     clearcache对1级缓存有作用,对二级无作用
     databaseId="",指向databaseIdProvider的别名
     timeout:等待数据库从请求返回的秒数。默认为未设置(依赖于驱动程序)。
     resultMap:使用resultMap,指向resultMap的id
     -->
    <!--动态sql时,empId!=null,empId相当于#{empId}必须为属性-->
    <select id="getAll" resultType="employee"  parameterType="employee" statementType="PREPARED" >
        select * from tab_emp
        <where>
            <choose>
                <when test="empId!=null">
                    and emp_id <![CDATA[<]]> #{empId}
                </when>
                <otherwise>
                    and emp_id > 0
                </otherwise>
            </choose>
        </where>
    </select>
    <!--直接获取参数1,当为数字时,设置参数没用,${id},id需要为对象中的属性-->
    <!--select * from tab_emp where emp_id=1  没有?直接填充-->
    <select id="getDifference1" resultType="employee"    >
        select * from tab_emp  where  emp_id=${1}
    </select>
    <!--select * from tab_emp where emp_id = ?   -->
    <!--一个参数,参数类型可以不写,如下的#{id}的id可以随意写-->
    <select id="getDifference2" resultType="employee"   >
        select * from tab_emp  where  emp_id = #{1}
    </select>

</mapper>

 test

import cn.mybatis.bean.Employee;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import java.io.InputStream;
import java.util.List;

public class MybatisBaseTest {

    SqlSessionFactory ssf;
    @Before
    public void init(){
        InputStream is = MybatisBaseTest.class.getResourceAsStream("/mybatisBaseCongfig.xml");
        SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
        ssf = ssfb.build(is);
    }
    @Test
    public  void testDynamicsql(){
        SqlSession ss = ssf.openSession();
        Employee employee = new Employee();
        employee.setEmpId(3);
        List<Object> list = ss.selectList("a.b.getAll",employee);
        System.out.println(list);
    }

    @Test
    public  void getDifference1(){
        SqlSession ss = ssf.openSession();
        List<Object> list = ss.selectList("a.b.getDifference1",1);
        System.out.println(list);
    }

    @Test
    public  void getDifference2(){
        SqlSession ss = ssf.openSession();
        List<Object> list = ss.selectList("a.b.getDifference2",1);
        System.out.println(list);
    }
}

2.1半接口半配置

mybatisBaseCongfig.xml同上

mapper

<?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">
<!--namespace的cn.mybatis.dao.EmployeeImplMapper,必须与包名.类名一致-->
<mapper namespace="cn.mybatis.dao.EmployeeImplMapper">
    <!--id="getAll"的getAll必须与方法名一致,resultType="employee"多条自动装入集合-->
    <select id="getAll" resultType="employee" >
        select * from tab_emp  where  emp_id > #{1}
    </select>

</mapper>

 接口cn.mybatis.dao.EmployeeImplMapper

public interface EmployeeImplMapper {
    public List<Employee> getAll(Integer  i);
}

3.基于注解

3.1半注解半配置

mybatisBaseCongfig.xml同上,但是mappers中的mapper改为如下

接口

public interface EmployeeImplMapper {
    @Select("select * from tab_emp  where  emp_id > #{1} ")//也可以不是*,那么就是按需注入
    public List<Employee> getAll(Integer  i);
}

 去掉mybatisBaseCongfig.xml的mappers中的mapper,添加如下

<!--mapper接口的包,与其他两种不能共用-->
<package name="cn.mybatis.dao"/>//指定某个包

 也可以使用

<mapper  class=""></mapper>//指定某个类

 备注:<package name="cn.mybatis.dao"/>不能与<mapper class=""></mapper>及<mapper resource="" />一起使用

3.2完全基于注解(需要与spring整合)

 

4.整合spring

4.1基于配置文件的方式整合(顺带整合了分页以及批处理,log4j日志,mgb逆向)

dataresouce.properties

jdbc.user=root
jdbc.password=123456
jdbc.url=jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8&useSSL=false&verifyServerCertificate=false
jdbc.driver=com.mysql.cj.jdbc.Driver

application.xml

<?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"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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/aop http://www.springframework.org/schema/aop/spring-aop.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!--扫描的包-->
    <context:component-scan base-package="cn.mybatis"></context:component-scan>

    <!--添加资源-->
    <context:property-placeholder  location="classpath:dataresouce.properties"></context:property-placeholder>

    <!--c3p0数据源-->
    <bean id="comboPooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="driverClass" value="${jdbc.driver}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <!-- 其他的一些配置.... -->
    </bean>

    <!--mybatis-->
    <bean id="sessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="comboPooledDataSource"></property>
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
        <property name="mapperLocations"  value="classpath:mapper/*.xml"></property>
    </bean>

    <!--mapper接口的加入到适配器中-->
    <bean id="configurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="cn.mybatis.dao"></property>
    </bean>

    <!--批量处理-->
    <bean  id="sessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg  name="sqlSessionFactory" ref="sessionFactoryBean"></constructor-arg>
        <constructor-arg name="executorType" value="BATCH"></constructor-arg>
    </bean>

    <!--事务-->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="comboPooledDataSource"></property>
    </bean>

    <!--基于注解的方式-->
    <!--<tx:annotation-driven transaction-manager="dataSourceTransactionManager"></tx:annotation-driven>-->

    <!--基于配置的方式的事物-->
    <aop:config>
        <aop:pointcut id="pointcut" expression="execution(* cn.mybatis.service.*.*(..))"></aop:pointcut>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"></aop:advisor>
    </aop:config>

    <tx:advice  id="txAdvice" transaction-manager="dataSourceTransactionManager">
        <tx:attributes>
            <tx:method name="*"/>
            <tx:method name="get*" read-only="true"></tx:method>
        </tx:attributes>
    </tx:advice>

</beans>  

mybatis-config.xml

<?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>
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <setting name="logImpl" value="LOG4J"></setting>
    </settings>

    <typeAliases>
        <package name="cn.mybatis"/>
    </typeAliases>

    <!--PageHelper 方法使用了 ThreadLocal ,分页参数和线程是绑定的。只要你可以保证在 PageHelper 方法调用后紧跟 MyBatis 查询方法,这就是安全的。
   因为 PageHelper 在 finally 代码段中自动清除了 ThreadLocal 存储的对象。如果代码在进入 Executor 前发生异常,就会导致线程不可用,这属于人为的 Bug(例如接口方法和 XML 中的不匹配,
   导致找不到 MappedStatement 时), 这种情况由于线程不可用,也不会导致 ThreadLocal 参数被错误的使用。
   -->
    <!--<property name="dialect" value="mysql"/>-->
    <!-- 该参数默认为false 设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用 -->    <!-- 和startPage中的pageNum效果一样 -->
    <!--<property name="offsetAsPageNum" value="false"/>-->
    <!-- 该参数默认为false  设置为true时,使用RowBounds分页会进行count查询 -->
    <!--<property name="rowBoundsWithCount"  value="true"/>-->
    <!-- 设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果
    (相当于没有执行分页查询,但是返回结果仍然是Page类型),
    <property name="pageSizeZero" value="true"/> 3.3.0版本可用 ,分页参数合理化,默认false禁用 ,
     启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页
      ,禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据 -->
    <!--<property name="reasonable" value="true"/>-->
    <!-- 3.5.0版本可用 - 为了支持startPage(Object params)方法.
    增加了一个`params`参数来配置参数映射,用于从Map或ServletRequest中取值 .
    可以配置pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默认值 .
    不理解该含义的前提下,不要随便复制该配置
    <property name="params" value="pageNum=start;pageSize=limit;"/> -->
    <!--参数如上,还有一些键github的pagehelp的文档How to use PageHelper.-->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>

</configuration>

 mgb逆向(官方文档 http://www.mybatis.org/generator/   )

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <!--跟自定义的没关系-->
    <!--<classPathEntry location="/Program Files/IBM/SQLLIB/java/db2java.zip" />-->
    <context id="DB2Tables" targetRuntime="MyBatis3">

        <!--忽略注释-->
        <commentGenerator>
            <property name="suppressAllComments" value="true" />
        </commentGenerator>

        <!--连接数据库-->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&useSSL=false&verifyServerCertificate=false&autoReconnct=true&autoReconnectForPools=true&allowMultiQueries=true&serverTimezone=GMT%2B8"
                        userId="root"
                        password="cgz12345678">
        </jdbcConnection>

        <!--number是否转换为BigDecimal类型-->
        <javaTypeResolver >
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>

        <!--指定bean生成的位置-->
        <javaModelGenerator targetPackage="cn.mybatis.bean" targetProject="./mybatistest/src/main/java">
            <property name="enableSubPackages" value="true" />
            <property name="trimStrings" value="true" />
        </javaModelGenerator>

        <!--指定mapper文件生成的位置-->
        <sqlMapGenerator targetPackage="mapper"  targetProject="./mybatistest/src/main/resources">
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>

        <!--指定mapper接口生成的位置-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="cn.mybatis.dao"  targetProject="./mybatistest/src/main/java">
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>

        <!--<table schema="DB2ADMIN" tableName="ALLTYPES" domainObjectName="Customer" >
            <property name="useActualColumnNames" value="true"/>

            <generatedKey column="ID" sqlStatement="DB2" identity="true" />
        重新取字段名
            <columnOverride column="DATE_FIELD" property="startDate" />
            忽略字段
            <ignoreColumn column="FRED" />
           
            <columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" />
        </table>-->

        <!--生成表,当时是多表关联时,手动的修改相应查询关系,见联表查询-->
        <table tableName="tab_emp" domainObjectName="Employee"></table>
        <table tableName="tab_dept" domainObjectName="Department"></table>
    </context>
</generatorConfiguration>

 log4j日志(LOG4J.xml)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration>
    <!--STDOUT表示输出  org.apache.log4j.ConsoleAppender 表示输出的类,这里表示输出到控制台-->
    <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
        <!--表达式输出的字符集-->
        <param name="Encoding" value="UTF-8"/>
        <!--org.apache.log4j.PatternLayout 对象和与之相关的格式化的日志记录信息转换模式,这里表示表达式-->
        <layout class="org.apache.log4j.PatternLayout">
            <!--ConversionPattern格式 -->
            <param name="ConversionPattern" value="%-5p %d{yyyy/MM/dd HH:mm:ss,SSS} %m  %c (%F:%L) \n"/>
        </layout>
    </appender>
<appender name="file" class="org.apache.log4j.FileAppender"> <!--表达式输出的字符集--> <param name="Encoding" value="UTF-8"/> <!--Threshold=debug:指定日志消息的输出最低层次。--> <param name="Threshold" value="debug"/> <!--append:默认值是true,即将消息增加到指定文件中,false指将消息覆盖指定的文件内容--> <param name="append" value="true"/> <!--File指定消息输出到mylog.txt文件。--> <param name="File" value="D:/logs/log4j.log"/> <!--ImmediateFlush:默认值是true,意谓着所有的消息都会被立即输出。--> <param name="ImmediateFlush" value="true"/> <!--org.apache.log4j.PatternLayout 对象和与之相关的格式化的日志记录信息转换模式,这里表示表达式--> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%-5p %d{yyyy/MM/dd HH:mm:ss,SSS} %m %c (%F:%L) \n"/> </layout> </appender> <!--指定包名下的输出级别--> <logger name="cn.mybatis.dao"> <level value="debug"/> </logger> <!--STDOUT的所有的输出级别 fatal(致命错误) > error (错误) > warn (警告) > info(普通信 息) > debug(调试信息) 如下为相应的name添加级别--> <root> <level value="warn"/> <appender-ref ref="STDOUT"/> <appender-ref ref="file"/> </root> </log4j:configuration>

test

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.exception.XMLParserException;
import org.mybatis.generator.internal.DefaultShellCallback;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class TestMBG {
    public static void main(String[] args) throws Exception{
        String str = "mybatistest\\src\\main\\resources\\mbg.xml";
        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;
        File configFile = new File(str);
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(configFile);
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
        myBatisGenerator.generate(null);
    }
}
import cn.mybatis.bean.Employee;
import cn.mybatis.bean.EmployeeExample;
import cn.mybatis.dao.EmployeeMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.io.File;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:application.xml"})
public class MybatisTest {
    @Autowired
    ComboPooledDataSource comboPooledDataSource;

    @Autowired
    EmployeeMapper employeeMapper;
    @Test//c3p0测试
    public void JdbcTest() throws Exception {
        Connection connection = comboPooledDataSource.getConnection();
        System.out.println(connection);
        connection.close();
    }
    @Test//mgb测试
    public void TestMBGMybatis() throws Exception {
        //添加条件
        EmployeeExample employeeExample = new EmployeeExample();
        EmployeeExample.Criteria criteria = employeeExample.createCriteria();
        criteria.andEmpIdEqualTo(1);
        List<Employee> employees = employeeMapper.selectByExample(employeeExample);
        for (Employee employee : employees) {
            System.out.println(employee);
        }
    }

    @Test//分页,添加了limit不是查询所有
    public void TestPagehelper(){
        PageHelper.startPage(1, 2);
        List<Employee> emps = employeeMapper.selectByExample(null);
        PageInfo<Employee> page = new PageInfo<>(emps);
        System.out.println(page);
    }
}

4.2完全基于注解整合

 

5.连表查询

5.1 association(配置的方式)

非集合

mapper1.xml

<select id="getDept"  resultType="cn.mybatis.bean.Department">
		select  *  from tab_dept where dept_id=#{dept_id}
</select>

 mapper2.xml

<mapper namespace="cn.mybatis.dao.EmployeeMapper">
  <resultMap id="BaseResultMap" type="cn.mybatis.bean.Employee">
    <result column="emp_id" jdbcType="INTEGER" property="empId" />
    <result column="emp_name" jdbcType="VARCHAR" property="empName" />
    <result column="gender" jdbcType="TINYINT" property="gender" />
    <result column="email" jdbcType="VARCHAR" property="email" />
    <result column="dept_id" jdbcType="INTEGER" property="deptId" />
    <association property="dept"  column="dept_id" select="cn.mybatis.dao.DepartmentMapper.getDept"/>/*property属性名,column对应该表的列名的值,
select使用的那条select,是根据查表select * from students where id=#{0}(student)的column="tid"值查询teacher。*/ </resultMap>

 test

@Test
    public void TestPagehelper(){
        PageHelper.startPage(1, 2);//分页插件
        List<Employee> emps = employeeMapper.selectByExample(null);//使用mbg逆向产生的类
        PageInfo<Employee> page = new PageInfo<>(emps);//获取分页信息
        System.out.println(page.getSize());
        System.out.println(page.getStartRow());
        System.out.println(page.isIsFirstPage());
        System.out.println(page.isIsLastPage());
        System.out.println(page.getPages());
        System.out.println(page.getTotal());
        List<Employee> list = page.getList();
        System.out.println(list);
    }

 5.2 集合 collection

<resultMap type="teacher" id="mymap">//resultMap需要与resultMap 的id名称一致,type表示返回值类型
  <id column="id" property="id"/>
  <result column="name" property="name"/>
  <collection property="list" select="com.StudentMapper.selByTid" column="id"></collection>
</resultMap>
<select id="selAll" resultMap="mymap">
  select * from teacher
</select>

 5.3 Auto Mapping

<resultMap type="Student" id="stuMap1">
  <id column="sid" property="id"/>
  <result column="sname" property="name"/>
  <result column="age" property="age"/>
  <result column="tid" property="tid"/>
  <association property="teacher" javaType="Teacher" >
    <id column="tid" property="id"/>
    <result column="tname" property="name"/>
  </association>
</resultMap>
<select id="selAll1" resultMap="stuMap1">
  select s.id sid,s.name sname,age age,t.idtid,t.name tname FROM student s left outer join teacher t on s.tid=t.id
</select>

 备注:对一的关系如上,查集合的时候上述方法不能使用,所以使用resultMap

 5.4 注解

@Results(value={ @Result(id=true,property="id",column="id"), 
@Result(property="name",column="name"), 
@Result(property="list",column="id",many=@Many(select="com.StudentMapper.selByTid"))}) 
@Select("select * from teacher")
List<Teacher> selTeacher();

 

备注:联表注解如上,其他注解类似基于注解的配置的注解

6.动态sql(参数需要是对象,单个参数可以不写参数类型,在配置中写别名减少参数类型的书写)

6.1 If 使用

<select id="selByAccinAccout" resultType="log">
  select * from log where 1=1
  <!-- OGNL 表达式,直接写key 或对象的属性.不需要添加任何特字符号-->
  <if test="accin!=null and accin!=''">
    and accin=#{accin}
  </if>
  <if test="accout!=null and accout!=''">
    and accout=#{accout}
  </if>
</select>

6.2 where

<select id="selByAccinAccout" resultType="log">
select * from log
  <where>
  <if test="accin!=null and accin!=''">
    and accin=#{accin}
  </if>
  <if test="accout!=null and accout!=''">
    and accout=#{accout}
  </if>
  </where>
</select>

 备注:先去除第一个and  后添加where

6.3 <choose> <when> <otherwise>//只能有一个满足条件

<select id="selByAccinAccout" resultType="log">
  select * from log
  <where>
  <choose>
    <when test="accin!=null and accin!=''">
      and accin=#{accin}
    </when>
    <when test="accout!=null and accout!=''">
      and accout=#{accout}
    </when>
  </choose>
  </where>
</select>

 6.4 <set>

<update id="upd" parameterType="log" >
  update log
  <set>
    id=#{id},
    <if test="accIn!=null and accIn!=''">
      accin=#{accIn},
    </if>
    <if test="accOut!=null and accOut!=''">
      accout=#{accOut},
    </if>
  </set>
  where id=#{id}
</update>

 备注:先去除左右的逗号,然后添加set

6.5 Trim

prefix 在前面添加内容,prefixOverrides 去掉前面内容,suffix 在后面添加内容,suffixOverrieds 去掉后面内容执行顺序去掉内容后添加内容

<update id="upd" parameterType="log">
  update log
  <trim prefix="set" suffixOverrides=",">
    a=a,
  </trim>
  where id=100
</update>

6.6 <bind>

<select id="selByLog" parameterType="log"
  resultType="log">
  <bind name="accin" value="'%'+accin+'%'"/>
  #{accin}
</select>

 备注:在形成sql语句时,会在输入的地方添加为"'%'+accin+'%'"

6.7 <foreach>

<select id="selIn" parameterType="list"resultType="log">
  select * from log where id in
  <foreach collection="list" item="abc" open="(" close=")" separator=",">
  #{abc}
  </foreach>
</select>

 备注:主要用于in中,open前添加,close后添加,separator分隔符,效率不高

7.一级缓存和二级缓存

7.1定义

      mybatis 中的一级缓存,mybatis一级缓存的设置的范围是 Sqlsession级别(localCacheScope默认值为session,表示session作用范围,改变作用范围也可以达到关闭session),session的clearcache() 方法或者close 或者执行了 增删改方法则会清除一级缓存,但是对二级缓存没有影响;mybatis 的二级缓存是配置文件范围的或者说命名空间范围,默认是关闭的(不安全),默认insert 、update、delete 后一级和二级缓存会被刷新,查询时sql没变的前提下不会刷新缓存,直接冲缓存中读取数据,不会发送sql,缓存的查找先从二级缓存中寻找后到一级缓存中寻找,缓存的保存先保存在一级缓存后到二级缓存,mybatis使用的二级缓存使用的是map储存,参数及其它含义见前面的配置中的参数说明

7.2自定义二级缓存(ehcache的官方文档   http://www.mybatis.org/ehcache-cache/

由于mybatis使用的二级缓存使用的是map储存不专业,一般我们会交给ehcache来处理二级缓存,不论是ehcahe还是memcached等

配置在mapper.xml中配置相应

 <!--使用ehcache的二级缓存 ,配置文件名称为ehcache.xml,需要放在类路径下-->
 <cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

ehcache.xml(需要放在类路径下)

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
 <!-- 磁盘保存路径 -->
 <diskStore path="D:\cache\ehcache" />
 
 <defaultCache 
   maxElementsInMemory="10000" 
   maxElementsOnDisk="10000000"
   eternal="false" 
   overflowToDisk="true" 
   timeToIdleSeconds="120"
   timeToLiveSeconds="120" 
   diskExpiryThreadIntervalSeconds="120"
   memoryStoreEvictionPolicy="LRU">
 </defaultCache>
</ehcache>
 
<!-- 
属性说明:
diskStore:指定数据在磁盘中的存储位置。
defaultCache:当借助CacheManager.add("demoCache")创建Cache时,EhCache便会采用<defalutCache/>指定的的管理策略
 
以下属性是必须的:
maxElementsInMemory - 在内存中缓存的element的最大数目 
maxElementsOnDisk - 在磁盘上缓存的element的最大数目,若是0表示无穷大
eternal - 设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断
overflowToDisk - 设定当内存缓存溢出的时候是否将过期的element缓存到磁盘上
 
以下属性是可选的:
timeToIdleSeconds - 当缓存在EhCache中的数据前后两次访问的时间超过timeToIdleSeconds的属性取值时,这些数据便会删除,默认值是0,也就是可闲置时间无穷大
timeToLiveSeconds - 缓存element的有效生命期,默认是0.,也就是element存活时间无穷大
diskSpoolBufferSizeMB 这个参数设置DiskStore(磁盘缓存)的缓存区大小.默认是30MB.每个Cache都应该有自己的一个缓冲区.
diskPersistent - 在VM重启的时候是否启用磁盘保存EhCache中的数据,默认是false。
diskExpiryThreadIntervalSeconds - 磁盘缓存的清理线程运行间隔,默认是120秒。每个120s,相应的线程会进行一次EhCache中数据的清理工作
memoryStoreEvictionPolicy - 当内存缓存达到最大,有新的element加入的时候, 移除缓存中element的策略。默认是LRU(最近最少使用),可选的有LFU(最不常使用)和FIFO(先进先出)

 也可以按如下配置

 8.其他

8.1 自定义类型转换器(基本不用)

org.apache.ibatis.type.TypeAliasRegistry   别名的源码类,自定义类转换器可以继承BaseTypeHandler<T>类(已有类型见官方文档),书写可参考,BaseTypeHandler看源码,ctrl+t,找实现的子类,例如StringTypeHandler,参照写,假如看不懂,那么把该源代码复制建立在相同的包下,那么调用的时候会先调用本地的,然后在其中输出相应的参数就可以知道了。

<insert id="insertUser" parameterType="User">  

    insert into t_user(id,accountID,userName,statusDef,statusOrdinal,statusCustom)   

    values(  

    #{id}, #{accountID}, #{userName},   

   #{statusDef},  

   #{statusOrdinal, typeHandler=com.util.typehandler.xxxTypeHandler},  

   #{statusCustom, typeHandler=com.util.typehandler.xxxTypeHandler}  

    ) 

</insert>

8.2 分页:mybatis是不能对ognl表达式进行运算符运算的,如右select * from people limit #{pageStart},#{pageSize}

8.3 Configuration.class文件中含有相应的配置以及别名等(配置文件中的别名)

8.4 获取自增主键<insert id="insertOne" parameterType="cn.mybatis3.test.Person1" useGeneratedKeys="true"  keyProperty="id">,useGeneratedKeys设置为true,默认值为false,keyProperty表示映射到bean的person1的id属性

8.5 collection多值传递

<collection property="list" select="com.StudentMapper.selByTid" column="id"></collection>中的column可以写成 column={key=value,key1=value1...}的形式,
延迟加载可以在其中添加fetchType="lazy",eager表示立即加载

8.6 鉴别器(基本不用)

<discriminator javaType="string" column="age">
			<case value="0" resultType="">
				<collection property=""></collection>
			</case>
			<case value="1" resultType="">
				
			</case>
</discriminator>

8.7关联本地dtd,window ---  references---xml----xmlcatalog--add,在idea中也有类似的关联

附录:maven依赖(批量处理(sqlsessiontemplate),分页(pagehelper),mgb逆向(generator),修改mgb的mapper文件实现联表查询,ehcache缓存,log4j日志)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.mybatis.test</groupId>
    <artifactId>mybatistest</artifactId>
    <version>1.0-SNAPSHOT</version>

   <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <maven.compiler.source>1.8</maven.compiler.source>
      <maven.compiler.target>1.8</maven.compiler.target>
      <springframework.version>5.1.0.RELEASE</springframework.version>
    </properties>

    <dependencies>
    <!--spring-webmvc -->
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${springframework.version}</version>
      </dependency>

      <!--spring-aspects -->
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>${springframework.version}</version>
      </dependency>

      <!--spring-test-->
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>${springframework.version}</version>
        <scope>test</scope>
      </dependency>

        <!--spring-jdbc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${springframework.version}</version>
        </dependency> 

        <!--mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>

        <!--mybatis与spring整合-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.2</version>
        </dependency>

        <!--c3p0 -->
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.2</version>
        </dependency>

        <!--mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.12</version>
        </dependency>

        <!-- junit依赖,scope为test所以是灰色的 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!--mgb逆向-->
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.3.7</version>
        </dependency>

        <!--二级缓存用的不是很多,可以不开启-->
        <dependency>
            <groupId>org.mybatis.caches</groupId>
            <artifactId>mybatis-ehcache</artifactId>
            <version>1.1.0</version>
        </dependency>

        <!--pagehelper分页-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.1.6</version>
        </dependency>

        <!--日志包-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.7.0</version>
                <configuration>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>              
posted @ 2018-09-20 18:41  fatale  阅读(191)  评论(0编辑  收藏  举报