MyBatis总结

  • 主配置文件
 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 
 3 <!DOCTYPE configuration
 4         PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 5         "http://mybatis.org/dtd/mybatis-3-config.dtd">
 6 
 7 <configuration>
 8     <!--
 9     属性
10     属性文件或property标签都能设置,一般就在属性文件里好了
11     -->
12     <properties resource="myBatisConf.properties">
13         <property name="driverClass" value="com.mysql.jdbc.Driver"/>
14     </properties>
15 
16     <!--设置MyBatis的运行方式-->
17     <settings>
18         <!--日志框架-->
19         <setting name="logImpl" value="LOG4J2"/>
20         <!--超时时间-->
21         <setting name="defaultStatementTimeout" value="50000"/>
22     </settings>
23 
24     <!--别名-->
25     <typeAliases>
26         <!--除了可以自己定义别名外,MyBatis内部对常用类型也有别名 主要就是 map  hashmap等-->
27         <typeAlias alias="AcReport" type="org.zln.domain.AcReport" />
28         <typeAlias alias="StudCard" type="org.zln.domain.StudCard" />
29         <typeAlias alias="Student" type="org.zln.domain.Student" />
30         <typeAlias alias="Teacher" type="org.zln.domain.Teacher" />
31     </typeAliases>
32 
33     <!--类型处理器 用于数据库数据类型和Java数据类型的转化一般不需要自己重写
34     要重写的话,实现 TypeHandler 接口
35     -->
36     <!--<typeHandlers>-->
37         <!--<typeHandler handler="" jdbcType="" javaType=""/>-->
38     <!--</typeHandlers>-->
39 
40     <!--对象工厂
41     每次创建结果对象新的实例的时候回用到 可以通过集成 DefaultObjectFactory 来自己重写
42     -->
43     <!--<objectFactory type=""></objectFactory>-->
44 
45     <!--MyBatis 允许你在某一点拦截已映射语句执行的调用。默认情况下,MyBatis 允许使用 插件来拦截方法调用-->
46     <!--<plugins>-->
47         <!--<plugin interceptor=""></plugin>-->
48     <!--</plugins>-->
49 
50     <!--环境-->
51     <environments default="development">
52         <!--环境变量 可以配置多个,要用哪个,由 environments 决定-->
53         <environment id="development">
54             <!--事务管理器  JDBC或MANAGED
55             JDBC:直接简单使用了 JDBC 的提交和回滚设置。它依赖于从数据源得到的连接来管理事务范围。
56             MANAGED:它从来不提交或回滚一个连接。而它会让
57 容器来管理事务的整个生命周期(比如 Spring 或 JEE 应用服务器的上下文)。默认 情况下它会关闭连接。然而一些容器并不希望这样,因此如果你需要从连接中停止 它,将 closeConnection 属性设置为 false。例如:
58 <transactionManager type="MANAGED">
59     <property name="closeConnection" value="false"/>
60 </transactionManager>
61             -->
62             <transactionManager type="JDBC" />
63             <!--数据源  type指明了数据源类型
64 
65             UNPOOLED    这个数据源的实现是每次被请求时简单打开和关闭连接。它有一点慢,这是对简单应用程序的一个很好的选择,因为它不需要及时的可用连接。不同的数据库对这 个的表现也是不一样的,所以对某些数据库来说配置数据源并不重要,这个配置也是闲置的
66             POOLED  这是 JDBC 连接对象的数据源连接池的实现,用来避免创建新的连接实例 时必要的初始连接和认证时间。这是一种当前 Web 应用程序用来快速响应请求很流行的方法。
67             JNDI
68 
69             不同type类型支持的配置属性是不一样的
70             -->
71             <dataSource type="POOLED">
72                 <property name="driver" value="${driverClass}" />
73                 <property name="url" value="${url}" />
74                 <property name="username" value="${username}" />
75                 <property name="password" value="${password}" />
76             </dataSource>
77         </environment>
78     </environments>
79 
80     <!--配置映射文件-->
81     <mappers>
82         <mapper resource="org/zln/mapper/AcReportMapper.xml" />
83         <mapper resource="org/zln/mapper/StudCardMapper.xml" />
84         <mapper resource="org/zln/mapper/StudentMapper.xml" />
85         <mapper resource="org/zln/mapper/TeacherMapper.xml" />
86     </mappers>
87 </configuration>

 

  • 初始化
 1 package org.zln.utils;
 2 
 3 import org.apache.ibatis.io.Resources;
 4 import org.apache.ibatis.session.SqlSession;
 5 import org.apache.ibatis.session.SqlSessionFactory;
 6 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 7 import org.apache.logging.log4j.LogManager;
 8 import org.apache.logging.log4j.Logger;
 9 
10 import java.io.IOException;
11 
12 /**
13  * Created by sherry on 16/7/15.
14  */
15 public class DBAccess {
16 
17     private static Logger logger = LogManager.getLogger(DBAccess.class);
18 
19     private static final String myBatisConfStr = "mybatis-config.xml";
20     private static SqlSessionFactory sqlSessionFactory;
21     static {
22         try {
23             /**
24              * SqlSessionFactoryBuilder 一旦实例化出SqlSessionFactory后就没用了
25              * SqlSessionFactory    其生命周期应该是整个应用,因为要不停从中获获取SqlSession 最好的方式就是使用Spring容器,哪里使用哪里注入
26              */
27             sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader(myBatisConfStr));
28         } catch (IOException e) {
29             logger.error(e.getMessage(),e);
30         }
31     }
32 
33     public static SqlSession getSqlSession() throws IOException {
34         /**
35          * SQLSession
36          * 每个线程都该有自己的SqlSession实例,它是线程不安全的,不能共享使用.所以SqlSession得最佳范围就应该是方法内,哪里使用哪里创建,创建完立马销毁
37          * 如果SqlSession如果被Spring管理,使用SqlSessionTemplate,则不需要,也不能人工close,具体原因百度:SqlSessionTemplate是否需要close
38          */
39         return sqlSessionFactory.openSession();
40     }
41 }

 

  • 映射文件
<?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="org.zln.mapper.StudentMapper">

    <!--配置给定命名空间的缓存-->
    <!--<cache></cache>-->

    <!--从其他命名空间引用缓存配置-->
    <!--<cache-ref namespace=""/>-->

    <!--结果集映射-->
    <resultMap id="StudentResultMap" type="Student">
        <id property="studId" column="stud_id" jdbcType="INTEGER"/>
        <result property="name" column="name" jdbcType="VARCHAR"/>
        <result property="email" column="email" jdbcType="VARCHAR"/>
        <result property="dob" column="dob" jdbcType="DATE"/>
    </resultMap>

    <!--可重用的SQL片段-->
    <sql id="selectStudents">
        SELECT stud_id,name,email,dob
    </sql>


    <select id="findAllStudents" resultMap="StudentResultMap">
        <include refid="selectStudents"/>
        FROM Student
    </select>
    <!--
    select详解
        id:查询id,如果使用Mapper形式编写,那么id值就是Mapper接口的方法名
        parameterType:参数类型,一般就是一个pojo对象 或者 基本数据类型 或者 map 等
        resultType:结果集映射类型
        resultMap:结果集映射类型
        flushCache:默认false,如果为true:无论语句何时被调用,都会导致缓存情况
        timeout:超时时间
        fetchSize:默认由驱动决定,每次批量返回的行数
        statementType:STATEMENT,PREPARED 或 CALLABLE 的一种。这会让 MyBatis 使用选择使用 Statement,PreparedStatement 或 CallableStatement。 默认值:PREPARED。
        resultSetType:FORWARD_ONLY|SCROLL_SENSITIVE|SCROLL_INSENSITIVE中的一种。默认是不设置(驱动自行处理)。
    -->
    <!--
    #{property,javaType=int,jdbcType=NUMERIC},用这种方式来指定参数类型,一般如果是pojo,MyBatis是能够自动获取的
    和iBatis一样,也有
    ${} 这种写法,一般用于 order by
    -->
    <!--
    一对一映射:在resultMap中配置association
    一对多映射:配置collection
    -->

    <!--
    缓存:默认情况没开启缓存
    SQL映射文件中加上 <cache/> 就会开启二级缓存
    -->


    <!--
    if标签 where标签 trim标签

    <select id="selectBySelective" resultType="xxx.UserInfo">
        select
        <include refid="Base_Column_List"/>
        from uc_user
        <where>
            (
            <if test="userName != null">
                user_name = #{userName}
            </if>
            <if test="email != null">
                or email = #{email}
            </if>
            <if test="phone != null">
                or phone = #{phone}
            </if>
            <if test="weiboId != null">
                or weibo_id = #{weiboId}
            </if>
            <if test="wxId != null">
                or wx_id = #{wxId}
            </if>
            <if test="qqId != null">
                or qq_id = #{qqId}
            </if>)
        </where>
        and status = 1
    </select>
    这样代码看似没有什么问题但是其实是有问题的。为什么呢?
    如果userName 为空,后面某字段不为空,最后的sql语言会成为这样:
    select * from uc_user where(or email = "xxx") and status = 1

    使用mybatis < where > 标签就是为了防止这种情况,mybatis会在第一个
userName 为空的情况下,帮我们去掉后面的语句的第一个”or”

但是我加了where标签中加入()后,语句会报错。因为自动去掉”or”会失效。

查看了mybatis官方文档发现了另一个标签 < trim >可以通过自定义 trim 元素来定制我们想要的功能

trim标签包围的内容可以设置几个属性:
prefix :内容之前加的前缀
suffix :内容之后加的后缀
prefixOverrides: 属性会忽略通过管道分隔的文本序列(注意此例中的空格也是必要的,多个忽略序列用“|”隔开)。它带来的结果就是所有在 prefixOverrides 属性中指定的内容将被移除。


-->
    <!--
    <select id="selectBySelective" resultType="xxx.UserInfo">
        select
        <include refid="Base_Column_List"/>
        from uc_user
        <trim prefix="WHERE (" suffix=")" prefixOverrides="AND |OR ">
            <if test="userName != null">
                user_name = #{userName}
            </if>
            <if test="email != null">
                or email = #{email}
            </if>
            <if test="phone != null">
                or phone = #{phone}
            </if>
            <if test="weiboId != null">
                or weibo_id = #{weiboId}
            </if>
            <if test="wxId != null">
                or wx_id = #{wxId}
            </if>
            <if test="qqId != null">
                or qq_id = #{qqId}
            </if>
        </trim>
        and status = 1
    </select>
-->

    <!--choose  when  -->
    <!--
    <select id="getStudentListChooseEntity" parameterType="StudentEntity" resultMap="studentResultMap">
        SELECT * from STUDENT_TBL ST
        <where>
            <choose>
                <when test="studentName!=null and studentName!='' ">
                    ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')
                </when>
                <when test="studentSex!= null and studentSex!= '' ">
                    AND ST.STUDENT_SEX = #{studentSex}
                </when>
                <when test="studentBirthday!=null">
                    AND ST.STUDENT_BIRTHDAY = #{studentBirthday}
                </when>
                <when test="classEntity!=null and classEntity.classID !=null and classEntity.classID!='' ">
                    AND ST.CLASS_ID = #{classEntity.classID}
                </when>
                <otherwise>

                </otherwise>
            </choose>
        </where>
    </select>
    -->

    <!--foreach 循环标签-->
    <!--
    <select id="getStudentListByClassIDs" resultMap="studentResultMap">
        SELECT * FROM STUDENT_TBL ST
        WHERE ST.CLASS_ID IN
        <foreach collection="list" item="classList"  open="(" separator="," close=")">
            #{classList}
        </foreach>
    </select>
    -->


    <!--SET 更新-->
    <!--
    <update id="updateUserInfoBySet" parameterType="userInfo">
        update userInfo
        <set>
            <if test="mobile!=null">
                mobile=#{mobile},
            </if>
            <if test="gender!=null">
                gender=#{gender},
            </if>
            <if test="position!=null">
                position = #{position},
            </if>
        </set>
        where userid=#{userid}
    </update>
    a.SQL语句的set被<set>标签替代。
    b.每个<if>中语句最后都带有逗号,如果有写过SQL语句的同学就一定知道,最后的逗号是不能有的,因此,这里的<set>标签能够帮助我们自动的移除最后一个<if>中的逗号。
    c.<trim>是一个非常强大的标签,因此,我们也可以通过<trim>来实现<set>的功能,如下:【这种写法的运行效果与<set>等价】
    -->
    <!--
    <update id="updateUserInfoBySet" parameterType="userInfo">
        update userInfo
        <trim prefix="SET" suffixOverrides=",">
            <if test="mobile!=null">
                mobile=#{mobile},
            </if>
            <if test="gender!=null">
                gender=#{gender},
            </if>
            <if test="position!=null">
                position = #{position},
            </if>
        </trim>
        where userid=#{userid}
    </update>
    -->
</mapper>

 

Mapp接口

 1 package org.zln.mapper;
 2 
 3 import org.apache.ibatis.annotations.Insert;
 4 import org.apache.ibatis.annotations.Select;
 5 import org.zln.domain.Student;
 6 
 7 import java.util.List;
 8 
 9 /**
10  * Created by sherry on 16/7/15.
11  * Student的Mapper接口
12  */
13 public interface StudentMapper {
14 
15     List<Student> findAllStudents();
16 
17     @Select("SELECT stud_id AS studId, name, email, dob FROM Student WHERE STUD_ID=#{Id}")
18     Student findStudentById(Integer id);
19 
20     @Insert("INSERT INTO Student(stud_id,name,email,dob) VALUES(#{studId},#{name},#{email},#{dob})")
21     void insertStudent(Student student);
22 
23 }

 

Dao

package org.zln.dao;

import java.io.IOException;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.zln.domain.Student;
import org.zln.mapper.StudentMapper;
import org.zln.utils.DBAccess;

/**
 * Created by sherry on 16/7/15.
 */
public class StudentDao {

    public List<Student> findAllStudents() throws IOException {
        SqlSession sqlSession = DBAccess.getSqlSession();
        try{
            StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
            return studentMapper.findAllStudents();
        } finally{
            sqlSession.close();
        }
    }
    public Student findStudentById(Integer studId) throws IOException {
        SqlSession sqlSession = DBAccess.getSqlSession();
        try {
            StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
            return studentMapper.findStudentById(studId);
        } finally {
            sqlSession.close();
        }
    }
    public void createStudent(Student student) throws IOException {
        SqlSession sqlSession = DBAccess.getSqlSession();
        try {
            StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
            studentMapper.insertStudent(student);
            sqlSession.commit();
        }finally{
            sqlSession.close();
        }
    }




}

 

 

与Spring集成

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.1.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">


    <context:component-scan base-package="org" resource-pattern="**/*Dao.class"/>
    <context:component-scan base-package="org" resource-pattern="**/*Service.class"/>

    <!--开启注解注入-->
    <context:annotation-config/>

    <bean class="org.zln.utils.des.EncryptPropertyPlaceholderConfigurer"
          p:location="classpath:db.properties"
          p:fileEncoding="UTF-8"/>
    <!--配置数据源-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
          p:driverClassName="com.mysql.jdbc.Driver"
          p:url="jdbc:mysql://localhost:3306/zln?useSSL=false"
          p:username="${username}"
          p:password="${password}"/>

    <!--JDBC模板类-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
          p:dataSource-ref="dataSource"/>
    <!--MyBatis配置-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
          p:dataSource-ref="dataSource"
          p:configLocation="classpath:myBatisConf.xml"
          p:mapperLocations="classpath:**/mapper/*Mapper.xml"/>
    <!--扫描Mapper类-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"
          p:basePackage="org.zln" />
    <!--sqlSessionTemplate-->
    <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg ref="sqlSessionFactory"/>
    </bean>


    <!--事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
          p:dataSource-ref="dataSource"/>

    <!--使用注解配置事务-->
    <tx:annotation-driven transaction-manager="transactionManager"/>

</beans>

 

与Spring集成后的Dao

package org.zln.myWeb.dao;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.zln.myWeb.domain.T00_User;
import org.zln.myWeb.mapper.T00_UserMapper;

/**
 * Created by sherry on 16/8/6.
 */
@Repository
public class T00_UserDao {

    @Autowired
    private SqlSessionTemplate sqlSessionTemplate;

    public T00_User getT00_UserById(Integer id){
        T00_UserMapper t00_userMapper = sqlSessionTemplate.getMapper(T00_UserMapper.class);
        return t00_userMapper.getT00_UserById(id);
    }
}

 

posted @ 2016-08-16 22:35  csnmd  阅读(312)  评论(0编辑  收藏  举报