myBatis总结

来源:互联网 发布:固定收益部 收入 知乎 编辑:程序博客网 时间:2024/06/07 03:00
(一)、
mybatis:    hibernate
  1-持久层
  2-orm框架
  3-工作:Java对象和数据库记录之间的转换
  4-反射    约定    :  类名--》表名    属性名---》字段名
  5-操作DB:
    1-数据库连接属性
    2-连接数据库   connection
    3-sql
    4-执行对象
    5-处理结果
    6-关闭连接
  6-步骤:
    1-导入jar
      1-mybatis的核心jar(依赖包暂时先不导入)
      2-数据库的驱动包
    2-创建mybatis的核心配置文件:com.xml
    3-在数据库里面创建db和table
    4-创建一个sql映射文件
      1-在映射文件中注册sql语句
      2-将sql映射文件注册到主配置文件中
    5-创建一个封装bean 类用来接收查询出来的数据
    6-创建一个SqlSession对象
    7-调用sqlsession中的方法执行响应的sql语句(sql_id)即可
    8-关闭session
(二)、
mybatis:
  1-jdbc:操作数据库的弊端:
    1-每一次操作都需要开启连接,关闭连接 ,耗资源
    2-jdbc直接把sql语句卸载业务逻辑代码中,sql的可维护性差
    3-jdbc中sql的参数是硬编码,可维护性差
    4-jdbc结果集的返回,resultset
  2-mybatis解决jdbc问题:
    1-底层采用数据库连接池机制
    2-将sql语句封装到了xml映射文件中
    3-自带参数类型转换
    4-返回结果直接是list  javabean对象
  3-mybatis:ibatis
  4-步骤:
    1-通用配置:
       1-jar包
       2-主配置文件
         1-配置数据库连接属性
         2-注册sql映射文件
       3-创建sql映射文件
       4-创建po类
    
    2-模块配置:
       1-在映射文件中注入sql语句
          1-namespace:用来区分所有sql语句:包名+文件名
          2-sql-id:在同一个namespace中映射一个唯一的sql语句   :方法名
       2-注册映射文件:在主配置文件中
       3-调用sql语句:
          1-创建sqlsessionfactory---->由SqlSessionFactoryBuilder生成
          2-由sqlsessionfactory--->sqlsession对象
          3-调用sqlsession的相应的方法执行sql(namespace+sqlid)语句
       4-关闭session
          
  5-添加操作:
    1-mapper文件中:
    <insert id="addPerson" parameterType="com.po.Person">
insert into person(pname,page,psex) values(#{pname},#{page},#{psex})
</insert>
   1-parameterType:指定sql语句的参数类型  例如:java.lang.String
   2-#{xxx}:占位符
      1-如果参数是简单Java类型(8基本类型 string)写法:#{value}   value也可写成任意名字
      2-如果是复杂类型:写法:#{属性名}
    2-测试:
    SqlSession session = sf.openSession(true);//自动提交事务  默认是false
String sql = "com.dao.PersonMapper.addPerson";
Person p = new Person();
p.setPname("wagnwu");
p.setPage(25);
p.setPsex("男");
int count =  session.insert(sql, p);
System.out.println(count);
//session.commit();
session.close();
    
    3-resultType:SQL语句的返回值类型
      1-如果返回值是一个对象,则直接指定该对象的类型即可   :com.po.Person
         1-方法:selectOne
      2-如果返回值是一个集合,则指定的是泛型即可
         1-方法:selectList
(三)、
mybatis:
1-SqlSessionFactoryBuilder:
 1-创建sqlsessionfactory
 2-匿名对象
2-sqlsessionfactory
 1-生产sqlsession
 2-单例
3-sqlsession
 1-sql语句的操作对象
 2-生命周期:跟数据库的一次会话


 2-mybatis编程方式:
   1-传统的dao编程:定义到接口,定义一个dao实现类
      1-缺陷:存在重复代码,和硬编码
   2-mapper接口编程:
      1-开发一个mapper接口:接口中声明操作方法
      2-定义mapper映射文件
         1-规范:
           1-xml文件的包名和文件名跟mapper接口的包名和类名一致
         2-规定:
           1-namespace:接口的全类名
           2-sql-id:为对应方法的方法名
           3-sql的parameterType类型必须跟方法的参数类型一致
           4-sql的resultType必须跟方法的返回值类型一致
              1-如果方法的返回值是单个封装类对象(String  person)  ,resultType也得是该类型
                 1-根据返回值是单对象,底层会自动调用selectOne方法
                 2-如果返回值是单对象,而sql却返回了多条记录,则会报错
              2-如果方法的返回值是list集合  ,resultType只需要制定集合的泛型
                 1-返回值是list,底层会自动调用selectList
      3-使用:
      SqlSession session = ssf.openSession(true);
this.pd = session.getMapper(PersonMapper.class);//获取一个接口的动态代理对象
int num = pd.addPerson(p);
   3-注解方式编程:
   
 3-#{}  ${}:
   1-#{}:占位符
      1-自动进行类型转换
   2-${}:sql拼接符
      1-统一将参数作为string跟sql进行拼接使用
      2-使用的地方:模糊查询,集合查询,排序查询等
 4-属性名跟数据库表中的字段名不一致:
   1-使用别名
   2-resultMap属性进行字段跟属性的映射
   <resultMap type="com.bean.Person" id="personmap">
<id column="_pid" property="pid"/>
<result column="_pname" property="pname"/>
<result column="_page" property="page"/>
<result column="_psex" property="psex"/>
</resultMap>
<select id="selectPersonListByMap" resultMap="personmap">
select pid _pid,pname _pname,page _page,psex _psex from person
</select>
 5-conf.xml配置文件:
    1-子标签:properties?, settings?, typeAliases?, typeHandlers?, objectFactory?, objectWrapperFactory?, plugins?, environments?, databaseIdProvider?, mappers?
2-properties:指定键值对常量值
  1-语法1:
  <properties>
<property name="username" value="dev_user"/>
<property name="password" value="F2Fa3!33TYyg"/>
</properties>
  2-<properties resource="db.properties"></propeties>
  3-<properties url="绝对路径:db.properties"></propeties>
  4-如果key发生了冲突,则优先级:resource/url高于property子标签
    1-如果:sqlSessionFactoryBuilder.build(reader, props)
    3-Settings:设置mybatis全局的常量信息:比如:是否开启缓存
  1-<settings>
<setting name="cacheEnabled" value="true"/>
4-typeAliases:指定别名
 1-<typeAliases>
<typeAlias alias="person" type="com.bean.Person"/>
 2-<typeAliases>
<package name="com.bean"/><!-- 别名:简单类型  首字母可以大写也可以小写 -->
    5-typeHandlers:指定类型转换(了解)
    6-environments:配置数据库连接属性
    7-mappers:注册映射文件
      1-语法1:
      <mappers>
<mapper resource="com/dao/IPersonDao.xml" />
 2-语法2:前提:mapper接口开发模式,而且映射文件的包名跟文件名与接口的保持一致
 <mappers>
<mapper calss="com.dao.PersonMapper" />
      3-语法3:前提:mapper接口开发模式,而且映射文件的包名跟文件名与接口的保持一致
       <package name="com.mapper"/>
(四)、
mybatis:       对象----sql语句的映射(sql语句还得写)   hibernate(类---表)
   1-动态sql:
     1-if:解决动态where条件
     <select id="selectPersons" parameterType="person" resultType="person">
SELECT * FROM person WHERE 1=1 
<if test="pname!=null and pname!= ''">
AND PNAME LIKE '%${pname}%' 
</if>
<if test="psex !=null and psex!=''">
AND psex=#{psex} 
</if>
<if test="page!=0">
<![CDATA[AND page<=#{page}]]>
</if>

</select>
2-where标签:会自动去除第一个and关键字,如果所有的条件不存在了,则where关键字也消失
    3-sql片段:解决一段sql代码的共享问题
      1-定义片段:
      <sql id="queryperson">
      <if test="pname!=null and pname!= ''">
AND PNAME LIKE '%${pname}%' 
</if>
<if test="psex !=null and psex!=''">
AND psex=#{psex} 
</if>
<if test="page!=0">
<![CDATA[AND page<=#{page}]]>
</if>
</sql>
 2-导入片段:<include refid="queryperson"/>
      
    4-foreach:解决集合查询问题
       1-第一种方法:用封装类属性的方式
        1-接口方法:public List<Person> selectPersonsAges(PersonPo p);
        2-扩展一个封装类:public class PersonPo extends Person {
                              private List<Integer> ages;
            3-sql定义:
            <select id="selectPersonsAges" parameterType="personPo" resultType="person">
SELECT * FROM person WHERE page IN 
<foreach collection="ages" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</select>
   1-collection:指定要遍历的集合
   2-item:定义个临时变量接受集合中的值
   3-open:以什么符号开始
   4-close:以什么结尾
   5-separator:每一个值之间的分隔符
      2-第二种方法:以list集合作为参数方式:
         <select id="selectPersonsAgesList" parameterType="java.util.List" resultType="person">
SELECT * FROM person WHERE page IN 
<foreach collection="list" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</select>
            
           1-parameterType:java.util.List
           2-collection:固定值:list
      3-第三种方法:以数组作为参数方式:
           1-parameterType:Object[]
           2-collection:array
         
   2-关联查询:
      1-一对一  一对多   多对一  多对多
         1-表层面
      2-一对一   一对多
         1-业务层面
      3-一对一:
         1-新建一个Card类(cid  cnum)  Person(cid)
         2-修改表
         3-第一种:用扩展类的方式将多表的查询转换成了单类的查询(推荐)
            1-扩展一个封装类PersonVo extends Person  ,在类中扩展person不具有的属性
            2-定义接口方法  ,注意:返回值类型时扩展类
            3-封装sql语句
         2-第二种:resultsMap
            1-在主类中(person) 添加一个从类(card)的引用
            2-定义接口方法(返回值就是person对象):public Person selectPersonAndCardByPId1(int pid);
            3-sql:
               1-定义sql
               <select id="selectPersonAndCardByPId1" parameterType="int" resultMap="p_c">
SELECT p.*,c.cnum FROM person p,card c WHERE p.cid=c.cid and p.pid=#{value}
</select>
               2-定义resultMap
               <resultMap type="person" id="p_c">
<id column="pid" property="pid"/>
<result column="pname" property="pname"/>
<result column="page" property="page"/>
<result column="psex" property="psex"/>
<association property="card" javaType="card">
<id column="cid" property="cid"/>
<result column="cnum" property="cnum"/>
</association>
</resultMap>
  
   1-association:作一对一映射
      1-property:指定person中对card的引用的属性名字
      2-javaType:指定该引用的Java类型
      3-子标签:
         1-id:映射主键
             1-column:指定查询列表中的字段名
             2-property:指定card的属性名
         2-result:映射普通属性
   4-一对多:
    1-在person中添加一个addr的集合引用
    2-方法:public Person selectPersonAndCardAndAddrByPid(int pid);
    3-sql:
      1-sql定义:
      
      
    <select id="selectPersonAndCardAndAddrByPid" parameterType="int" resultMap="p_c_a">
SELECT p.*,c.cnum mycard,a.aid,a.aname FROM person p,card c,addr a WHERE p.cid=c.cid AND p.pid=a.pid and p.pid=#{value}
</select>
      2-resultMap定义:
      
      
<resultMap type="person" id="p_c_a">
<!-- person信息 -->
<id column="pid" property="pid"/>
<result column="pname" property="pname"/>
<result column="page" property="page"/>
<result column="psex" property="psex"/>
<!-- card信息 -->
<association property="card" javaType="card">
<id column="cid" property="cid"/>
<result column="mycard" property="cnum"/>
</association>
<!-- addr信息 -->
<collection property="addrs" ofType="addr">
<id column="aid" property="aid"/>
<result column="aname" property="aname"/>
</collection>
</resultMap>  
                   
                   1-collection:一对多映射
                      1-property:指定person中的addr集合的属性名
                      2-ofType:指定集合属性中的数据的类型(泛型)
             
            3-resultMap的继承:
            
            
               <resultMap type="person" id="p_c_a" extends="p_c">
<!-- addr信息 -->
<collection property="addrs" ofType="addr">
<id column="aid" property="aid"/>
<result column="aname" property="aname"/>
</collection>
</resultMap>
    
   
   3-延迟加载:lazy策略       :只有在使用查询sql返回的数据是才真正发出sql语句到数据库,否则不发出(主要用在多表的联合查询)
       1-导入mybatis 的依赖jar包
       2-添加log4j文件 
       3-一对一延迟加载:
          1-原理:只有当前台使用身份证号时才发出对card的查询,否则只发出person信息的查询
          2-开启lazy:在conf.xml
          <settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>

     3-实现:
     
     <select id="findCardById" parameterType="int" resultType="card">
select * from card where cid=#{value}
       </select>
<resultMap type="person" id="p_c1">
<id column="pid" property="pid"/>
<result column="pname" property="pname"/>
<result column="page" property="page"/>
<result column="psex" property="psex"/>
<association property="card" javaType="card" select="findCardById" column="cid"></association>
</resultMap>

<select id="selectPersonAndCardByPId_lazy" parameterType="int" resultMap="p_c1">
select * from person
</select>

    1-select:指定关联的查询语句
    2-column:指定主语句中的哪个字段的值作为参数传递给从sql语句
     
(五)、
mybatis:
1--查询缓存:防止相同数据的重复获取操作,第一次获取数据后,将数据保存到缓存区中,以后访问时就不连接数据库,直接从缓存中获取
 1-一级缓存
    1-session级
    2-程序员不能控制
    3-生命周期:跟随着session
    4-使用:直接用
    5-管理:执行增删改操作   也可以手工清空    也可以手工提交session   关闭session
   
 2-二级缓存
    1-sessionfactory级
    2-只要是同一个工厂生产的session共享
    3-生命周期:同sessionfactory
    4-默认:关闭
    5-开启二级缓存:
      1-xml:
      <settings>
<setting name="cacheEnabled" value="true"/>
</settings>
  2-mapper文件中:加:<cache/>
  3-被缓存的对象需要实现序列化接口(二级缓存有可能会将对象缓存到文件中)
6-原理:二级缓存跟namespace相关
7-禁用二级缓存:某一个sql禁用二级
给特定的sql添加一个属性:useCache=false
 3-ehcache:二级缓存产品
    1-jar
    2-配置ehcache的xml文件
    3-mapper文件:
    
    4-org.apache.ibatis.cache.Cache:二级缓存的标准  所有跟mybatis整合的二级缓存产品需要实现该接口
      

2-调用存储过程:
 1-jdbc调用存储过程:
 2-数据库:call 
 3-定义:
 

3-逆向工程:  
原创粉丝点击