mybatis

#mybatis介绍#
支持普通SQL查存过程和高级映射的优秀持久层框架。消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。
使用简单的XML或注解用于配置和原始映射,将接口和 Java 的普通对象映射成数据库中的记录。
实现了DAO接口与xml映射文件的绑定,自动为我们生成接口的具体实现,使用起来变得更加省事和方便。

<!--优点-->
把Sql语句从Java中独立出来。
封装了底层的JDBC,API的调用,并且能够将结果集自动转换成JavaBean对象,简化了Java数据库编程的重复工作。
自己编写Sql语句,更加的灵活。入参无需用对象封装(或者map封装),使用@Param注解

Ibatis的升级版本。
(2010年,apache的Ibatis框架停止更新,并移交给了google团队,同时更名为MyBatis。
从2010年后Ibatis在没更新过,彻底变成了一个孤儿框架。一个没人维护的框架注定被mybatis拍在沙滩上。)

#核心#

SqlSession

#原理#

通过SqlSessionFactoryBuilder从mybatis-config.xml配置文件中构建出SqlSessionFactory。
SqlSessionFactory开启一个SqlSession,通过SqlSession实例获得Mapper对象并且运行Mapper映射的Sql语句。
完成数据库的CRUD操作和事务提交,关闭SqlSession。


#使用模式#

1,注解使用情况:Sql语句简单时直接写在Dao层

    @Mapper
     public interface TestDao {
     @Select("select id, name, name_pinyin from mm_test; ")
     List<MmTest> selectAll();
     
     @Insert("insert into mm_test(id, name) values(#{id}, #{name})")  
     public void insertUser(MmTest mmtTestS);
     }


2,xml绑定使用情况:xml绑定 (@RequestMap用来绑定xml文件)
      (id名与dao层方法名一致)
     <select id="">

 ${}:预编译处理,把${}直接替换成变量的值,不做任何转换。
 #{}:字符串替换,sql中的#{}替换成?,有效的防止Sql语句注入。
 总结:一般用#{}来进行列的代替

#实体类#

#工具类#
    public class MyBatisUtil {
    
    private static SqlSessionFactory factory;
        
        static{
            //1.获取mybatis.xml的输入流
            InputStream iStream;
            try {
                iStream=Resources.getResourceAsStream("Mybatis-config.xml");
                factory=new SqlSessionFactoryBuilder().build(iStream);
                
            } catch (Exception e) {
                // TODO: handle exception
            }
        }
        
        public static SqlSession createSqlSession(){
            //取消自动提交
            return factory.openSession(false);
        }
        
        public static void closeSqlsession(SqlSession session){
            if (session!=null) {
                session.close();
            }
        }
    }


    

#接口#
    /**
     * 根据用户姓名来进行模糊查询
     */
  

  public  List<User> getUserListByUserName(String username);
    
    public List<User> getUserListByMap(Map<String, String> usermap);



#测试#
   

 @Test
    public void getUserListByUserName(){
        SqlSession sqlSession = null;
        List<User> userList = new ArrayList<User>();
        try {
            sqlSession = MyBatisUtil.createSqlSession();
            
            //第一种方式:调用selectList方法执行查询操作
            //userList = sqlSession.selectList("cn.smbms.dao.user.UserMapper.getUserList");
            
            //第二种方式:调用getMapper(Mapper.class)执行dao接口方法来实现对数据库的查询操作
            userList = sqlSession.getMapper(UserMapper.class).getUserListByUserName("赵");

            (关闭自动提交后,增删改执行后 需要自己提交)
            // sqlsession.commit(); 
        } catch (Exception e) {
            // TODO: handle exception
            (增删改执行后 执行失败后回滚)
            //sqlsession.rollback();
            e.printStackTrace();
        }finally{
            MyBatisUtil.closeSqlSession(sqlSession);
        }
        for(User user: userList){
            logger.debug("testGetUserList userCode: " + user.getUserCode() + " and userName: " + user.getUserName());
        }
    }    
    
    @Test
    public void getUserListByMap(){
        SqlSession sqlSession = null;
        List<User> userList = new ArrayList<User>();
        try {
            sqlSession = MyBatisUtil.createSqlSession();
            Map<String, String>usermap=new HashMap<String, String>();
            usermap.put("username", "赵");
            usermap.put("userRole", "2");
            userList = sqlSession.getMapper(UserMapper.class).getUserListByMap(usermap);
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }finally{
            MyBatisUtil.closeSqlSession(sqlSession);
        }
        for(User user: userList){
            logger.debug("testGetUserList userCode: " + user.getUserCode() + " and userName: " + user.getUserName());
        }
    }    




#XML代码#【XML需要与Dao接口名一致,通过session.getMapper(接口名.class).方法名(参数)调用执行】
直接复制使用(使用前要手动配置文件)
  

  <?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的路径)
    <mapper namespace="Dao.UserMapper">
    
    //返回类型1
    <resultMap type="Pojo.User" id="User">
    (同字段名自动匹配)
    <result property="ID" column="ID"/>
    (一对一:加了一个类)
    <association property="role" javaType="Pojo.Role">
    <id property="id" column="id"/>
    <result property="roleName" column="roleName"/>
    </association>
    </resultMap>
    
    //返回类型2
    <resultMap type="Pojo.User" id="User1">
    <result property="ID" column="ID"/>
    (一对多:加了一个集合或者map)
    <collection property="addressList" ofType="Pojo.Address">
    <result property="id" column="id"/>
    </collection>
    
    </resultMap>
    <!-- 1对1嵌套查询 -->
    【下面代码在接口中实现使用@param("id")注入参数,如果没有使用则为后面()中代码,使用更新操作则<update></update>,其他同理】
    <select id="Select1"  resultMap="User">
    SELECT     a.*,b.roleCode FROM  smbms.smbms_user a ,smbms_role b WHERE a.userRole=b.id    AND a.userRole=#{id}    
    </select>
    <!-- 1对多嵌套查询 -->
    <select id="Select2" resultMap="User1" >
    SELECT     a.*,b.addressDesc,b.contact FROM  smbms.smbms_user a ,smbms_address b WHERE a.id=b.userId    AND b.id=#{id}
    </select>
    
    <select id="Modif" resultMap="User1" >
    
    </select>

    (<select id="getUserListByUserName" resultType="User" parameterType="String">
    SELECT * FROM smbms_user WHERE userName  LIKE CONCAT ('%',#{username},'%')
    </select>
    
    <select id="getUserListByMap" resultType="User" parameterType="Map">
    SELECT * FROM smbms_user WHERE userName  LIKE CONCAT ('%',#{username},'%')
     and userRole=#{userRole}
    </select>)
    
    </mapper>

#条件查询的xml#
    <mapper namespace="Dao.BillMapper">

    <resultMap type="Pojo.Bill" id="Map1">
    <result property="id " column="id "/>
    </resultMap>

    (单一条件使用<choose> <when></when></choose>)
    <select id="Select" resultMap="Map1" parameterType="Map">
    SELECT     a.*,b.proName FROM  smbms.smbms_bill a ,smbms_provider b WHERE a.providerId=b.id
    <if test="name!=null and name!=''"> and productName like concat('%',#{name},'%') </if>
    <if test="id!=null">                and  providerId=#{id}                        </if>
    <if test="flag!=null">              and isPayment=#{flag}                        </if>
    </select>
    
    <update id="Modif"   parameterType="Pojo.Bill" >
    UPDATE smbms.smbms_bill a 
    (前缀后缀及忽略设置)
    <trim prefix="set" suffix="where a.id=#{id}" suffixOverrides=",">
    <if test="billCode!=null">a.billCode=#{billCode},</if>
    <if test="productName!=null">a.productName=#{productName},</if>
    <if test="productDesc!=null">a.productDesc=#{productDesc},</if>
    <if test="productUnit!=null">a.productUnit=#{productUnit},</if>
    <if test="productCount!=null">a.productCount=#{productCount},</if>
    <if test="totalPrice!=null">a.totalPrice=#{totalPrice},</if>
    <if test="isPayment!=null">a.isPayment=#{isPayment},</if>
    <if test="createdBy!=null">a.createdBy=#{createdBy},</if>
    <if test="creationDate!=null">a.creationDate=#{creationDate},</if>
    <if test="modifyBy!=null">a.modifyBy=#{modifyBy},</if>
    <if test="modifyDate!=null">a.modifyDate=#{modifyDate},</if>
    <if test="providerId!=null">a.providerId=#{providerId},</if>
    </trim>
    </update>

    (通过传入的数组或list或map【map里放字符和list】获取条件,进行查询)
    <select id="Select1" resultMap="Map1" >
    SELECT     a.*,b.proName FROM  smbms.smbms_bill a ,smbms_provider b WHERE 
    a.providerId=b.id and a.id in
    (循环遍历)
    <foreach collection="Array" item="i" open="(" separator="," close=")">
    #{i}
    </foreach>
    </select>
    <select id="Select2" resultMap="Map1" >
    SELECT     a.*,b.proName FROM  smbms.smbms_bill a ,smbms_provider b WHERE 
    a.providerId=b.id and a.id in
    <foreach collection="List" item="i" open="(" separator="," close=")">
    #{i}
    </foreach>
    </select>
    <select id="Select3" resultMap="Map1" >
    SELECT     a.*,b.proName FROM  smbms.smbms_bill a ,smbms_provider b WHERE 
    a.providerId=b.id
     AND a.isPayment=#{isPa}
      AND a.id IN 
    <foreach collection="List" item="i" open="(" separator="," close=")">
    #{i}
    </foreach>
    </select>
    </mapper>




#mybatis的配置XML代码#【一般放在src/resource内,有配置文件database.properties和日志文件log4j.properties】
直接复制使用
  

  <?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> 
 
    <!-- 配置文件 -->
    <properties resource="database.properties"/>

    <!-- 配置mybatils的log实现 -->
    <settings>
    <setting  name="logImpl" value="LOG4J"/>

    <!-- 自动配备全开(字段名匹配,同名),联表查询则需要开启(只用设置不同名,其他同名自动匹配)。 -->
    <setting name="autoMappingBehavior" value="FULL"/>
    </settings>
    
    (自动扫描,使前面与接口同名的xml内引入文件名可以少打一些共有代码)
     <typeAliases>
       <package name="Pojo"/>
      </typeAliases>
      
    <!-- default默认 -->
    <environments default="development"> 

    <environment id="development" >
    <!-- 配置事务JDBC的事务管理 -->
    <transactionManager type="JDBC"/>
    <!-- tomcat数据源 -->
    <dataSource type="POOLED" >
    <property name="driver" value="${driver}"/> 
    <property name="url" value="${url}"/> 
    <property name="username" value="${name}"/>
     <property name="password" value="${password}"/>
      </dataSource> 
      </environment> 
      </environments> 
     
      (引入接口的xml)
      <mappers> 
    <mapper resource="Dao/UserMapper.xml"/> 
    <mapper resource="Dao/BillMapper.xml"/> 
      </mappers>
     
      </configuration>
  



#复习#
1. 查询 select标签 
2. resultType一般用来返回的是对象,但是可能有点情况下数据库和实体类当中的表字段不一致的情况,那我们需要使用resultmap----源于我们的map集合
3. 修改、新增、删除 传入参数-----如果有多个参数,那么在我们的xml当中是无法去判断参数的,所以我们需要使用注解来帮助我们指定我们传入的是什么参数
4. mybatis执行的增删改也有返回值,同时需要注意的是,我们创建的时候默认的是不自动提交,当我们执行成功之后就需要提交commit
5. sqlsession的生命周期---存在于一次请求,由于我们是默认的不自动提交,所以我们可以在里面执行多次sql。原理:由于sqlsession是由我们的SqlSessionFactory创建的,他是一个人力劳动市场,sqlsession相当于是一次人力,sqlsession这一次生命周期中执行多个语句都是可以的,但是当我们关闭了sqlsession之后,将无法再次使用。
6. 一对一   就是左表和右表都有相关联的数据,并且有且仅有一条记录关联,在这个时候,虽然我们可以使用之前的resultmap方式,在对象当中新增一些字段,但是这样不方便后期维护。我们为了方便后期维护,就是用了一对一的方式。在对象当中嵌套一个关联的对象。

  

      <resultMap type="User" id="userRoleResult">
         <result property="id" column="id"/>
          <result property="userCode" column="userCode"/>
         <result property="userName" column="userName"/> 
        <result property="phone" column="phone"/>
        <result property="birthday" column="birthday"/>
        <result property="gender" column="gender"/>
        <result property="userRole" column="userRole"/> 
        <association property="role" javaType="Role" resultMap="roleresult">
        </association>
    </resultMap>
      <resultMap type="Role" id="roleresult">
            <id  property="id" column="id"/>
            <result property="roleName" column="roleName"/>
            <result property="roleCode" column="roleCode"/>
      </resultMap>



7. 可能将来会遇到一个用户有多个地址的情况---一对多
8. 比如我们在京东上面购物,我这个账号有多个地址,查地址呗。但是有很多公司的后台,需要通过人名或者编号来查询这个帐号下面的地址

#什是项目核心?#
项目实现什么功能,用了什么技术,是在怎样的环境下开发的,工作周期

#得到了什么?#
刚开始的时候,由于我的代码还不够规范,所以总是出现很多bug,但是随着后面代码越来越熟练,
我也知道了代码规范的重要性,并且知道了如何去定位BUG,解决BUG。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值