| 
 MyBatis应用分析与最佳实践A. 传统 JDBC 问题的解决jdbcTemplate.query(sql, new BaseRowMapper(Employee. class));B. ORM
 C. MyBatis 配置文件(mybatis-config.xml)Hibernate 是一个 ORM 框架 
 它解决了创建连接,释放资源的重复代码问题解决了 ResultSet 的映射代码问题提供了查询缓存解决了写 SQL 的问题 
Hibernate 缺点 
 每次操作都是表的所有字段,无法做到制定部分字段自动生成的 SQL 很难进行优化不支持动态 SQL 
MyBatis 
 解决了 ResultSet 问题解决了 SQL 硬编码问题 
MyBatis 特性 
 使用连接池对连接进行管理SQL 和代码分离,集中管理参数映射和动态 SQL结果集映射缓存管理重复 SQL 提取插件机制 
核心对象 
 SqlSessionFactoryBuilder 
SqlSessionFactory(单例) 
SqlSession 
Mapper 
 
 
 <?xml version="1.0" encoding="UTF-8" ?>根标签 <configuration> 
<properties> 
<settings> 
<typeAliases> 
==<typeHandlers>== 
==<objectFactory>== 
<plugins> 
 插件可以拦截 MyBatis 四大对象 
 EcecutorParameterHandlerResultHandlerStatementHandler 
 
<environments> 
<mappers> 
 
 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
 <configuration>
 <properties resource="db.properties"/>
 <settings>
 <!-- 打印查询语句 -->
 <setting name="logImpl" value="STDOUT_LOGGING"/>
 <!-- 控制全局缓存(二级缓存)-->
 <setting name="cacheEnabled" value="true"/>
 <!-- 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。默认 false  -->
 <setting name="lazyLoadingEnabled" value="true"/>
 <!-- 当开启时,任何方法的调用都会加载该对象的所有属性。默认 false,可通过select标签的 fetchType来覆盖-->
 <setting name="aggressiveLazyLoading" value="false"/>
 <!--  Mybatis 创建具有延迟加载能力的对象所用到的代理工具,默认JAVASSIST -->
 <setting name="proxyFactory" value="CGLIB" />
 <!-- STATEMENT级别的缓存,使一级缓存,只针对当前执行的这一statement有效 -->
 <setting name="localCacheScope" value="STATEMENT"/>
 <setting name="localCacheScope" value="SESSION"/>
 </settings>
 
 <typeAliases>
 <typeAlias alias="blog" type="com.gupaoedu.domain.Blog"/>
 </typeAliases>
 
 <typeHandlers>
 <typeHandler handler="com.gupaoedu.type.MyTypeHandler"></typeHandler>
 </typeHandlers>
 
 <!-- 对象工厂 -->
 <objectFactory type="com.gupaoedu.objectfactory.GPObjectFactory">
 <property name="gupao" value="666"/>
 </objectFactory>
 
 <plugins>
 <plugin interceptor="com.gupaoedu.interceptor.SQLInterceptor">
 <property name="gupao" value="betterme"/>
 </plugin>
 <plugin interceptor="com.gupaoedu.interceptor.MyPageInterceptor">
 </plugin>
 </plugins>
 
 <environments default="development">
 <environment id="development">
 <transactionManager type="JDBC"/><!-- 单独使用时配置成MANAGED没有事务 -->
 <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>
 </environment>
 </environments>
 
 <mappers>
 <mapper resource="BlogMapper.xml"/>
 <mapper resource="BlogMapperExt.xml"/>
 </mappers>
 </configuration>public class MyTypeHandler  extends BaseTypeHandler<String> {
 public vo id setNonNullParameter(PreparedStatement ps,  int i, String parameter, JdbcType jdbcType)
 throws SQLException {
 "设置 String 类型的参数的时候调用,Java 类型到 JDBC 类型"
 System. out .println(" " --------------- setNonNullParameter1 :" "+parameter);
 ps.setString(i, parameter);
 }
 public String getNullableResult(ResultSet rs, String columnName)  throws SQLException {
 "根据列名获取 String 类型的参数的时候调用,JDBC 类型到 java 类型"
 System. out .println(" " --------------- getNullableResult1 :" "+columnName);
 return rs.getString(columnName);
 }
 "后面2个方法不用"
 }<typeHandlers>
 <typeHandler  handler ="com.gupaoedu.type.MyTypeHandler"></ typeHandler>
 </typeHandlers><insert id="insertBlog" parameterType="com.gupaoedu.domain.Blog">
 insert into blog (bid, name, author_id)
 values (#{bid,jdbcType=INTEGER},
 #{name,jdbcType=VARCHAR,typeHandler=com.gupaoedu.type.MyTypeHandler},
 #{authorId,jdbcType=INTEGER})
 </insert><result column="name" property="name" jdbcType="VARCHAR" typeHandler="com.gupaoedu.type.MyTypeHandler"/>D. 动态 SQL 配置<if>
 <choose>(<when>,<otherwise>)
 <trim>(<where>,<set>)
 <foreach><select id ="selectDept" parameterType ="int" resultType ="com.gupaoedu.crud.bean.Department">
 select * from tbl_dept where 1 = 1
 <if test="deptId != null">
 and dept_id = #{deptId, jdbcType=INTEGER}
 </if>
 </select><select id="getEmpList_choose" resultMap="empResultMap" parameterType="com.gupaoedu.crud.bean.Employee">    SELECT * FROM tbl_emp e    <where>        <choose>            <when test="empId !=null">                e.emp_id = #{emp_id, jdbcType=INTEGER}            </when>            <when test="empName != null and empName != ''">                AND e.emp_name LIKE CONCAT(CONCAT('%', #{emp_name, jdbcType=VARCHAR}),'%')            </when>            <when test="email != null ">                AND e.email = #{email, jdbcType=VARCHAR}            </when>            <otherwise>            </otherwise>        </choose>    </where></select><update  id ="updateB yPrimaryKeySelective" parameterType ="com.gupaoedu.crud.bean.Employee">    update tbl_emp    <set>        <if test ="empName != null">            emp_name = #{empName,jdbcType=VARCHAR},        </if>        <if test ="gender != null">            gender = #{gender,jdbcType=CHAR},        </if>        <if test ="email != null">            email = #{email,jdbcType=VARCHAR},        </if>        <if test ="dId != null">            d_id = #{dId,jdbcType=INTEGER},        </if>    </set>    where emp_id = #{empId,jdbcType=INTEGER}</update><insert id ="insertSelective" parameterType="com.gupaoedu.crud.bean.Employee">    insert into tbl_emp    <trim prefix ="("suffix=")" suffixOverrides=",">        <if test="empId != null">            emp_id,        </if>        <if test ="empName != null">            emp_name,        </if>        <if test ="dId != null">            d_id,        </if>    </trim>    <trim prefix="values("suffix=")" suffixOverrides=",">        <if test="empId != null">            #{empId,jdbcType=INTEGER},        </if>        <if test ="empName != null">            #{empName,jdbcType=VARCHAR},        </if>        <if test ="dId != null">            #{dId,jdbcType=INTEGER},        </if>    </trim></insert>E. 批量操作<!-- 批量插入 --><insert id="batchInsert" parameterType="java.util.List" useGeneratedKeys="true">    <selectKey resultType="long" keyProperty="id" order="AFTER">        SELECT LAST_INSERT_ID()    </selectKey>    insert into tbl_emp(emp_id, emp_name, gender,email, d_id)     values    <foreach collection="list" item="emps" index="index" separator=",">        (#{emps.empId},#{emps.empName},#{emps.gender},#{emps.email},#{emps.dId})    </foreach></insert>
 SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);F. 嵌套(关联)查询 / N + 1 / 延时加载<select id="selectBlogWithAuthorResult" resultMap="BlogWithAuthorResultMap">    select b.bid, b.name, b.author_id, a.author_id , a.author_name    from blog b    left join author a    on b.author_id=a.author_id    where b.bid = #{bid, jdbcType=INTEGER}</select> <resultMap id="BlogWithAuthorResultMap" type="com.gupaoedu.domain.associate.BlogAndAuthor">    <id column="bid" property="bid" jdbcType="INTEGER"/>    <result column="name" property="name" jdbcType="VARCHAR"/>    <!-- 联合查询,将author的属性映射到ResultMap -->    <association property="author" javaType="com.gupaoedu.domain.Author">        <id column="author_id" property="authorId"/>        <result column="author_name" property="authorName"/>    </association></resultMap><select id="selectBlogWithAuthorQuery" resultMap="BlogWithAuthorQueryMap">    select b.bid, b.name, b.author_id, a.author_id , a.author_name    from blog b    left join author a    on b.author_id=a.author_id    where b.bid = #{bid, jdbcType=INTEGER}</select><!-- 另一种联合查询(一对一)的实现,但是这种方式有“N+1”的问题 --><resultMap id="BlogWithAuthorQueryMap" type="com.gupaoedu.domain.associate.BlogAndAuthor">    <id column="bid" property="bid" jdbcType="INTEGER"/>    <result column="name" property="name" jdbcType="VARCHAR"/>    <association property="author" javaType="com.gupaoedu.domain.Author" column="author_id" select="selectAuthor"/></resultMap><select id="selectAuthor" parameterType="int" resultType="com.gupaoedu.domain.Author">    select author_id authorId, author_name authorName    from author where author_id = #{authorId}</select><!--延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。默认 false --><setting name="lazyLoadingEnabled" value="true"/><!--当开启时,任何方法的调用都会加载该对象的所有属性。默认 false,可通过 select 标签的 fetchType 来覆盖--><setting name="aggressiveLazyLoading" value="false"/><!-- Mybatis 创建具有延迟加载能力的对象所用到的代理工具,默认 JAVASSIST --><setting name="proxyFactory" value="CGLIB"/>G. 翻页Batch Executor 
 定义一个批量操作的执行器在 <settings> 标签里设置 
 SIMPLE(默认)REUSEBATCH(批处理) 
也可以在创建会话的时候指定 
 
 H. 配置太多I. 通用 MapperJ. MyBatis-Plus逻辑翻页与物理翻页的区别 
逻辑翻页的支持:RowBounds 
物理翻页的几种实现方式 
 
 
 |