[置顶] mybatis总结(分文件类型)

时间:2021-05-20 05:11:47

Mybatis项目总结

几个整合的注意事项:①配置熟路库连接参数文件时,注意文件结尾是properties,同时每一个属性值的末尾千万不要有空格,不然读取文件值时时可能这样的 user="root    "     ②与spring整合时,如果使用c3p0连接池,记住不仅要导入c3p0的jar包,还要导入mchange-commons-java.jar     ③为了防止中文传入mysql查找时的编码错误,建议使用jdbc:mysql:///test?characterset=utf-8

一、最重要的配置文件mapper.xml(与POJO的Mapper接口相连)

1、普通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">


<!-- 
namespace命名空间,作用是对sql进行分类话管理,
理解sql隔离注意:使用mapper代理方法开发,
namespace有特殊重要的作用
 -->


<mapper namespace="test">
<!-- 在映射文件中配置很多sql语句 -->
<!-- 同归id查询表数据 -->
<!-- 通过select执行数据库管理 
id:标识映射文件的sql   通过namespace.id来使用
将sql语句封装到mappedStatement对象中,所有将id成为statement的id
parameterType:指定输入参数的类型
#{}标识一个占位符         #{参数名} 可以传参 参数名可以任意
${}表示拼接字符串,将接收到字符的参数直接拼接到sql中,容易引起sql注入
resultType:指定sql输入结果的所映射的java对象类型,select指定的resultType表示将单条记录映射成javabean对象
--> 

<select id="findUserById" parameterType="int" resultType="com.mybatis.entity.User"> 
SELECT * FROM user WHERE id=#{id}
</select>

<select id="findUserByName"  parameterType="java.lang.String"  resultType="com.mybatis.entity.User">
SELECT * FROM user WHERE name LIKE '%${value}%'
</select>

<select id="findUsers"  resultType="com.mybatis.entity.User">
SELECT * FROM user 
</select>

<!-- 插入 -->
<insert id="addUser" parameterType="com.mybatis.entity.User">

<!-- 插入结束后,想获得自增主键的值 -->
<!-- 获得刚插入的主键值,并返回给插入对象的id中 
keyProperty将查询到的主键值设置到parameterTyoe指定的对象属性中
order (BEFORE/AFTER) selectKey的执行顺序,相对于insert语句而言
-->
<!-- <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer ">
SELECT lAST_INSERT_ID()
</selectKey> -->


<!-- 插入前,通过mysql的uuid()方法自动生成主键(要求类型为String,长度为35位) -->
<!-- <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
SELECT uuid()
</selectKey>  
-->

<!-- 通过oracle的序列生成主键 -->  
<!-- <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
SELECT 序列名.nextval()
</selectKey>  
-->

insert into user(id,name,nickname) value(#{id}, #{name}, #{nickname})
<!-- 如果主键是自增的话(语句是给id插入一个0的值,然后在数据库中,自增) -->
<!-- insert into user(name,nickname) value (#{name},#{nickname})  -->
</insert>

<!-- 删除用户 
根据id删除 (int和Integer都可以,Integer比较好)
-->
<delete id="deleteUser" parameterType="java.lang.String">
delete from user where id = #{id}
</delete>

<!-- 更新用户 
需要传入用户的id
需要传入对用户的更新信息
parameterType指定user对象,一定要有id属性
#{id}从user对象中获取id属性值
-->
<update id="updateUser" parameterType="com.mybatis.entity.User">
update user set name = #{name}, nickname = #{nickname} where id = #{id}
</update>


</mapper>

2、mapper.xml(mapper接口其实就是dao接口,二者放在同一个目录下,而且方法的大部分定义通过配置文件来约束)
<?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">


<!-- 该文件需要在SqlMapConfig.xml中进行配置
也可以通过package属性整个包一起配置  -->


<!-- namespace命名空间,作用是对sql进行分类话管理, namespace等于mapper接口地址 -->


<mapper namespace="com.mybatis.dao.mapper.userMapper">


<!-- resultType和resultMap均可以实现一一映射
resultType不可以实现延迟加载
resultMap可以实现延迟记载啊
 
-->


<!-- 
type一对多时,type是一个具体的对象,如果是多对多,查询主表的对象的class路径
定义返回类型的最终返回的java对象类型(使用别名) id:对resultmap的唯一标识(是返回类型resultMap对应的对象) 
result中有一个extend的属性,用来继承其他的resultMap
-->
<resultMap type="user" id="userResultMap"> 
<!--select id id_,username username_ 
form user where id = #{value } column查询出来的列名 property type指定的poji类型中的属性名 -->
<!--单个属性,唯一标识-->
<!-- <id column="id_" property="id" />  -->
<!-- <result column="列" property="bean中属性"/> -->

<!--配置映射关系的类关系
id关联查询用户的唯一标识
指定唯一标识用户信息的列
javaType映射到user的哪个属性
-->
<!-- <association property="user" javaType="user的路径">
<id column="id_" property="id" /> 
</association> -->

<!--配置一对多的映射
映射到 含有一个list列表的对象
collection 对关联查询到多条记录映射到集合对象中
property 将关联查询到多条记录映射到 的属性名(就是映射bean的集合对象名称,如List<User> users)
ofType指定映射到集合属性中poji的类型 就像Users  使用User对象的路径
-->
<collection property="users" ofType="cn.....User">
<!-- 
id是另一张表的主键名
column从数据库中查找到的字段名
property是bean中的字段名
-->
<id column="" property="" />
<result column="" property="" />
</collection>
</resultMap> 

<!-- 定义sql片段 -->
<sql id="user_where">
<if test="userCustomer.name != null and userCustomer.username != ''">
and user.name=#{userCustomer.name}
</if>
<if test="userCustomer.nickname != null and userCustomer.nickname  != ''">
and user.nickname =#{userCustomer.nickname }
</if>
</sql>
<!-- 动态sql语句  引入sql片段  refid是sql片段的id -->
<select id="findUserList3" parameterType="com.mybatis.dao.po.UserQuertVo"
resultType="com.mybatis.dao.po.UserCustomer">
SELECT * FROM user
<where>
<foreach collection=""></foreach>
<include refid="user_where"></include>
</where>
</select>


<!-- 传入多个参数的方法 1.parameterType不给值的类型,直接传入,使用#{0},#{1},#{2}..来调用 2.使用map传入多个参数,但需要对类型进行转换 
<select id=" selectUser" resultMap="BaseResultMap"> select * from user_user_t 
where user_name = #{userName,jdbcType=VARCHAR} and user_area=#{userArea,jdbcType=VARCHAR} 
</select> 3.接口层使用注释(推荐) Public User selectUser(@param("userName")String userName,@param("userArea")String 
userArea); <select id=" selectUser" resultMap="BaseResultMap"> select * from 
user_user_t where user_name = #{userName,jdbcType=VARCHAR} and user_area=#{userArea,jdbcType=VARCHAR} 
</select> 4.使用list,在接口层传入list <select id="getXXXBeanList" resultType="XXBean"> 
select 字段... from XXX where id in <foreach item="item" index="index" collection="list" 
open="(" separator="," close=")"> #{item} </foreach> </select> -->


<!-- 封装成pojo #{userCustomer.name} 取出pojo取出包装对象的 姓名 #{userCustomer.nickname}取出包装对象中的昵称 -->
<select id="findUserList" parameterType="com.mybatis.dao.po.UserQuertVo"
resultType="com.mybatis.dao.po.UserCustomer">
SELECT * FROM user WHERE user.name = #{userCustomer.name} and user.nickname
= #{userCustomer.nickname}
</select>




<!-- 未使用别名前com.mybatis.entity.User -->
<select id="findUserById" parameterType="String" resultType="User" >
SELECT * FROM user WHERE id=#{id}
</select>






<!-- 动态sql语句 自动取出第一个条件的and(where) -->
<select id="findUserList2" parameterType="com.mybatis.dao.po.UserQuertVo"
resultType="com.mybatis.dao.po.UserCustomer">
SELECT * FROM user
<where>
<if test="userCustomer.name != null and userCustomer.username != ''">
and user.name=#{userCustomer.name}
</if>
<if test="userCustomer.nickname != null and userCustomer.nickname  != ''">
and user.nickname =#{userCustomer.nickname }
</if>
</where>
</select>







<!-- 实现延迟加载 (需要在SqlMapConfig。xml中配置开启延迟加载)-->
<resultMap type="" id="">

<!--
association collection都可以实现延迟加载
select 指定延迟加载需要执行的statement的id,(指定其他的xml文件时,将其他的xml的namespace复制)
column订单信息中关联用户信息查询的列
-->
<association property=""></association>
<collection property=""></collection>
</resultMap>


<!-- 一级缓存放在sqlSession中,commit提交后,清空,
二级缓存需要手动开启(既要在 SqlMapConfig.xml中配置,也要在想赢的mapper中配置),每个Mapper的namespace都有自己的二级缓存区域,如果两个namespace是一样的,则他们的mapper的二级缓存区域是一样的
二级缓存和一级缓存的区别:二级缓存的范围更大,多个sqlSession可以共享一个UserMapper的二级缓存区域

SqlMapConfig.xml中配置  <setting name="CacheEnabled" value="true" /> 表示对此配置文件下的所有cache进行全局性开/关配置,默认为true
Mapper.xml中配置 <cache/>
调用pojo(实体类) 实现序列化接口(为了将缓存数据取出执行反序列化操作,因为二级缓存数据存储介质多种多样,不一定存储在内存)
注:如果想要禁用sql语句,可以在sql语句<Select></Select>中设置userCache="false"表示禁用二级缓存,比如每次都想从sql中获取最新数据,就可以使用这条命令

刷新缓存(就是清空缓存):当执行完commit操作后,就需要执行刷新缓存,避免脏读<insert id=""></insert>中这只flushCache=true就是刷新缓存,默认为true

对缓存数据进行集中管理,使用分布式缓存框架,redis memached ehcache(不使用分布缓存,缓存的数据在各个服务服务单独存储,不方便系统开发),mybatis无法实现分布缓存,提供了cache接口,框架只需要实现cache类,随后在二级缓存的cache中添加type="实现接口的类名
" -->
</mapper>


二 、SqlMapConfig.xml的几个知识点(整合Spirng的时候,通过批量扫描spring的配置文件的mapper批量扫描可以不配置任何东西)


<?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">  
    
    <!--
    mybatis加载属性的过程  
    先从properties元素体内的property中读取
    再去从properties元素中resource或uri加载的属性文件中读取
    最后读取mapper.xml/user.xml中的parameterType中读取
    下面读取的会把上面读取的覆盖掉,所以建议不要在property元素内添加任何属性,定义在文件中
    -->
    
    
    <!-- 可以引用properties文件来对数据库信息进行配置 -->
     
    <configuration>  
   
    <!-- 引入数据库配置文件 -->
    <properties resource="db.properties">
    <!-- 配置属性名和属性值 -->
    <!--  <property name="" value=""/> -->
    </properties> 
  


        <!--配置别名  
        typeAliases和environments是平等级别的标签  
            type是实体类的完整类名  
            alias是类的别名  
        -->  
        <!-- 批量定义别名
        <package name=""/> name中指定包名,然后mybatis自动扫描包中的类,自定义别名(类名,首字母大小写不限制)
         -->
         
        <typeAliases>
        <typeAlias type="com.mybatis.entity.User" alias="User"/>  
        </typeAliases>
        
         <!-- 和Spring整合后environments就会抛弃 --> 
       <environments default="development">  
            <environment id="development">  
            <!-- 使用jdbc事务处理,事务控制由mbatis -->
                <transactionManager type="JDBC" />  
                <!-- 数据库连接池,由mybatis管理   -->
                <!-- 可以外部创建一个专门管理数据库连接的properties文件 -->
              
              <dataSource type="POOLED">  
                    <property name="driver" value="com.mysql.jdbc.Driver" />  
                    <property name="url" value="jdbc:mysql://localhost/test" />  
                    <property name="username" value="root" />  
                    <property name="password" value="root" />  
                </dataSource>  
                
                 
               <!--引入db.properties的方法之一 (测试失败) -->
               
            <!--   <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代理后,既可以不需要User.xml -->
            <!-- 通过resource一次加载一个文件 -->
      <!-- <mapper resource="sqlmap/User.xml" />   -->
          <!--<mapper resource="mapper/UserMapper.xml" />   -->
            
            <!-- 通过mapper接口加载映射文件
            将mapper接口类和mapper.xml映射文件名保持一致。且二者放到同一个目录下   UserMapper.xml UserMapper.java
            要求使用了mapper代理方法   
            同時     UserMapper.xml 中的namespace也不能省略
             --> 
             <!-- 单个加载 -->
      <mapper class="com.mybatis.dao.mapper.userMapper"/>
       
      <!-- 扫描包下的文件,批量加载 -->
      <!-- <package name="com.mybatis.dao.mapper"/> -->
        </mappers> 
        
        <!-- 
        setting全局参数配置
         -->
       <settings>
        <!-- 开启延迟加载  默认是false-->
        <setting name="lazyKoadingEbabled" value="true"/>  
        <!--  属性加载  true属性全部加载 false每个属性都按需加载 (默认是false) -->
        <setting name="aggressiveLazyLoading" value=""false/>
       </settings>
        
        
        
    </configuration>  
    
    
    
    <!-- 该文件的名字可以修改(自定义) -->

三、与Spirng的applicationContext.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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-4.3.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">
<!-- 配置数据源,使用c3p0 -->
<context:property-placeholder location="classpath:db.properties" />
<!-- -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="${c3p0.driver}" />
<property name="jdbcUrl" value="${c3p0.url}" />
<property name="user" value="${c3p0.username}" />
<property name="password" value="${c3p0.password}" />
</bean>
<!-- 配置sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 加载mybatis的配置文件 -->
<property name="configLocation" value="Mybatis/SqlMapConfig.xml" />
<!-- 加载数据源 -->
<property name="dataSource" ref="dataSource" />
</bean>

    <!-- mapper开发 -->
    <!-- <bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="mapperInterface" value="cn.edu.ssm.mapper.UserMapper"></property>
        <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
    </bean> -->
    
    <!-- mapper批量扫描,从mapper包中扫描出mapper接口,自动创建代理对象并且在Spring容器中注入 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
       <!-- 指定扫描的包名 
                    使用sqlSessionFactoryBeanName而不是用sqlSessionFactory
                    因为使用sqlSessionFactory会先扫描mapper之后加载数据源
       -->
       <property name="basePackage" value="cn.edu.ssm.mapper"></property>
       <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
    </bean>
    
</beans>



备注  附上log4j.properties的配置信息
# Global logging configuration 
#开发环境下日志级别要设置成DEBUG,生产华宁设置成Info/error
log4j.rootLogger=DEBUG, stdout  
# MyBatis logging configuration...  
log4j.logger.org.mybatis.example.BlogMapper=TRACE  
# Console output...  
log4j.appender.stdout=org.apache.log4j.ConsoleAppender  
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout  
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n