mybatis基础2

Posted mslog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mybatis基础2相关的知识,希望对你有一定的参考价值。

1、输入与输出映射

Mapper.xml映射文件中定义了操作数据库的sql,每个sql是一个statement,映射文件是mybatis的核心。

1.1parameterType(输入类型)

1.1.1基本类型

1.1.2pojo类型

Mybatis使用ognl表达式解析对象字段的值,#{}或者${}括号中的值为pojo属性名称

1.1.3传递pojo包装对象

开发中通过pojo传递查询条件 ,查询条件是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件

(比如将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。

Pojo类中包含pojo。

QueryVo包装对象

public class QueryVo {

    private User user;

    public User getUser() {
        returnuser;
    }

    publicvoid setUser(User user) {
        this.user = user;
    }
    
    
}

 

添加Mapper配置

<!-- 使用包装类型查询用户 
        使用ognl从对象中取属性值,如果是包装对象可以使用.操作符来取内容部的属性
    -->
    <selectid="findUserByQueryVo"parameterType="queryvo"resultType="user">
        SELECT * FROM user where username like ‘%${user.username}%‘
    </select>

 

定义接口

List<User> findUserByQueryVo(QueryVo queryVo)

 

测试方法

@Test
    publicvoidtestFindUserByQueryVo() throws Exception {
        SqlSession sqlSession = sessionFactory.openSession();
        //获得mapper的代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //创建QueryVo对象
        QueryVo queryVo = new QueryVo();
        //创建user对象
        User user = new User();
        user.setUsername("刘");
        queryVo.setUser(user);
        //根据queryvo查询用户
        List<User> list = userMapper.findUserByQueryVo(queryVo);
        System.out.println(list);
        sqlSession.close();
    }

1.2resultType(输出类型)

1.2.1输出基本类型

添加mapper配置

    <!-- 只有返回一行一列的时候,那么返回值类型才可以是指定成基本类型 -->
    <select id="findUserCount" resultType="java.lang.Integer">
        select count(*) from user
    </select>

Mapper接口

public int findUserCount(User user) throws Exception;

 

测试:

Publicvoid testFindUserCount() throws Exception{
        //获取session
        SqlSession session = sqlSessionFactory.openSession();
        //获取mapper接口实例
        UserMapper userMapper = session.getMapper(UserMapper.class);
    
        User user = new User();
        user.setUsername("管理员");

        //传递Hashmap对象查询用户列表
        intcount = userMapper.findUserCount(user);
        
        //关闭session
        session.close();
    }

输出简单类型必须查询出来的结果集有一条记录,最终将第一个字段的值转换为输出类型。

使用session的selectOne可查询单条记录。

1.2.2输出pojo类型

配置Mapper

    <select id="findUserByUserName" parameterType="java.lang.String" resultType="com.wang.pojo.User">
        SELECT * from user where  username like ‘%${value}%‘
    </select>

Mapper接口

    public List<User> findUserByUserName(String name);

测试

    @Test
    public void findUserByUserName() throws Exception{
        SqlSession session = factory.openSession();
        //通过getMapper实例化接口
        UserMapper userMapper = session.getMapper(UserMapper.class);
        
        List<User> users= userMapper.findUserByUserName("王");
        System.err.println(users);
    }

 

2、动态sql

通过mybatis提供的各种标签方法实现动态拼接sql。

2.1 if

<!-- 传递pojo综合查询用户信息 -->
    <selectid="findUserList"parameterType="user"resultType="user">
        select * from user 
        where 1=1 
        <iftest="id!=null">
        and id=#{id}
        </if>
        <iftest="username!=null and username!=‘‘">
        and username like ‘%${username}%‘
        </if>
    </select>

 

注意要做不等于空字符串校验。

2.2 Where

<selectid="findUserList"parameterType="user"resultType="user">
        select * from user 
        <where>
        <iftest="id!=null and id!=‘‘">
        and id=#{id}
        </if>
        <iftest="username!=null and username!=‘‘">
        and username like ‘%${username}%‘
        </if>
        </where>
    </select>

where 标签作用:
1、会自动向sql中添加where关键字
2、会自动去掉第一个条件的and关键字

2.3 foreach

向sql传递数组或List,mybatis使用foreach解析,如下

在QueryVo中声明:

public class QueryVo {
private List<Integer> ids;public List<Integer> getIds() {
        return ids;
    }

    public void setIds(List<Integer> ids) {
        this.ids = ids;
    }    
}

 测试:

    @Test
    public void testfindUserByIds()throws Exception{
        SqlSession session = factory.openSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        QueryVo queryVo =new QueryVo();
        List<Integer> integers = new ArrayList<>();
        integers.add(1);
        integers.add(10);
        integers.add(31);
        queryVo.setIds(integers);
        
        List<User> users = mapper.findUserByIds(queryVo);
        System.out.println(users);
    }

 

对应的sql映射文件

    <select id="findUserByIds" parameterType="com.wang.pojo.QueryVo" resultType="com.wang.pojo.User">    
        select * from user
        <where>
            <if test="ids !=null">
            <!-- foreach:循环传入集合的参数
                collection:传入的集合
                item:每次循环将循环出的数据放入这个变量中
                open:循环开始拼接的字符串
                close:循环结束拼接的字符串
                separator:循环中拼接分隔符
                 -->
                <foreach collection="ids" item="id" open="id in (" close=") " separator=",">
                    #{id}
                </foreach>
            </if>
        </where>
    </select>
foreach:循环传入集合的参数
collection:传入的集合
item:每次循环将循环出的数据放入这个变量中
open:循环开始拼接的字符串
close:循环结束拼接的字符串
separator:循环中拼接分隔符


2.4sql片段

Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的,如下:

<!-- 封装sql条件,封装后可以重用
    ID:是唯一表示 -->
    <sql id="userWhere">
        <!-- where 标签作用:
            1、会自动向sql中添加where关键字
            2、会自动去掉第一个条件的and关键字
             -->
        <where>
            <if test="username !=null and username !=‘‘">
            and username like ‘%${username}%‘
        </if>
        <if test="sex !=null and sex !=‘‘">
            and sex =#{sex}
        </if>
        </where>        
    </sql>

 

 引入sql片段:
    <select id="findUserByUserNameAndSex" parameterType="com.wang.pojo.User" resultType="com.wang.pojo.User">
        select * from user
        <include refid="userWhere"></include>
    </select>

 

3、关联查询
两个表:
顾客表:
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) NOT NULL COMMENT 用户名称,
  `birthday` date DEFAULT NULL COMMENT 生日,
  `sex` char(1) DEFAULT NULL COMMENT 性别,
  `address` varchar(256) DEFAULT NULL COMMENT 地址,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8;

 


订单表:
CREATE TABLE `orders` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL COMMENT 下单用户id,
  `number` varchar(32) NOT NULL COMMENT 订单号,
  `createtime` datetime NOT NULL COMMENT 创建订单时间,
  `note` varchar(100) DEFAULT NULL COMMENT 备注,
  PRIMARY KEY (`id`),
  KEY `FK_orders_1` (`user_id`),
  CONSTRAINT `FK_orders_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
3.1一对一
对于两表:商品中订单与顾客的关系为一对一
对应的sql语句如下:
        select a.*,b.id uid,username,birthday,sex,address 
        from orders a,user b 
        where a.user_id = b.id

    <!-- resultType返回的属性名与列命一直 -->
    <select id="findOrdersAndUser1" resultType="cn.itheima.pojo.CustomOrders">
        select a.*,b.id uid,username,birthday,sex,address 
        from orders a,user b 
        where a.user_id = b.id
    </select>

 



3.1.1.解法一:自动自动映射 
新键一个pojo让其继承Orders,之后在平铺User中所有的属性(决不可直接把user当做属性)
如下:
public class CustomOrders extends Orders{

    //不能直接声明为user
    
    private int uid;   //resultType返回的属性域列命一致,故为uid
    private String username;// 用户姓名
    private String sex;// 性别
    private Date birthday;// 生日
    private String address;// 地址
    
    
    public int getUid() {
        return uid;  
    }
    public void setUid(int uid) {
        this.uid = uid;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    } 
}

 

接口:
    public List<CustomOrders> findOrdersAndUser1();

 

测试:
    @Test
    public void findOrdersAndUser1() throws Exception{
        SqlSession session = factory.openSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        
        List<CustomOrders> customOrders = mapper.findOrdersAndUser1();
        
        System.err.println(customOrders);
        
    }

 

3.1.2手动映射

   a、定义po类

       在Orders类中加入User属性,user属性中用于存储关联查询的用户信息,因为订单关联查询用户是一对一关系,所以这里使用单个User对象存储关联查询的用户信息。

public class Orders {
    private Integer id;

    private Integer userId;

    private String number;

    private Date createtime;

    private String note;
    
    private User user;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number == null ? null : number.trim();
    }

    public Date getCreatetime() {
        return createtime;
    }

    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note == null ? null : note.trim();
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    } 
}

 

b、mapper.xml配置
    <!--id:resultMap唯一标识
        type:将查询出的数据放入指定的对象中 
        注意:手动映射需要:指定数据库中表的字段名与java中pojo类的属性名称对应关系
    -->
    <!-- 以Orders为主,查询数据放入其中,把User放入其中当做属性 -->
    <resultMap type="com.wang.pojo.Orders" id="orderAndUserResultMap">
        <!-- id标签指定主键字段对应关系
            column:列,数据库中字段名称
            property:pojo中属性名
         -->
        <id column="id" property="id"/>
        <!--result指定非属性列的对应关系  -->
        <result column="user_id" property="userId"/>
        <result column="number" property="number"/>
        <result column="createtime" property="createtime"/>
        <result column="note" property="note"/>
        
        <!-- 指定单个对象的对应关系
            property:指定将数据放入Oders中的user属性中
            JavaType:支付user属性类型
         -->
        <association property="user" javaType="com.wang.pojo.User">
            <id column="uid" property="id"/>
            <result column="username" property="username"/>
            <result column="sex" property="sex"/>
            <result column="birthday" property="birthday"/>
            <result column="address" property="address"/>            
        </association>
    </resultMap>
    <select id="findOrdersAndUser2" resultMap="orderAndUserResultMap">
        select a.*,b.id uid,username,birthday,sex,address 
        from orders a,user b 
        where a.user_id = b.id
    </select>

 

新的方法
resultMap标签:
       id:resultMap唯一标识
       type:将查询出的数据放入指定的对象中 注意:手动映射需要:指定数据库中表的字段名与java中pojo类的属性名称对应关系
          以Orders为主,查询数据放入其中,把User放入其中当做属性
<id column="" property=""/>  指定id标签指定主键字段对应关系   column:列,数据库中字段名称  property:pojo中属性名
        <result column="" property=""/>   result指定非属性列的对应关系
  <association property="user" javaType="com.wang.pojo.User">
    指定单个对象的对应关系

        property:指定将数据放入Oders中的user属性中
           JavaType:支付user属性类型
         <id column="uid" property="id"/>
         <result column="username" property="username"/>
接口定义:
    public List<Orders> findOrdersAndUser2();

 

测试:
    @Test
    public void testFindOrdersAndUser2() throws Exception{
        SqlSession session = factory.openSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        
        List<Orders> customOrders = mapper.findOrdersAndUser2();
        
        System.out.println(customOrders);
        
    }

 

3.2多对一:
顾客与订单是多对一:
            select a.*,b.id oid,user_id,number,createtime 
            from user a,orders b 
            where a.id=b.user_id
以顾客为主,User新pojo(新的List<Orders> ordersList)
public class User {
    private int id;
    private String username;// 用户姓名
    private String sex;// 性别
    private Date birthday;// 生日
    private String address;// 地址
    private List<Orders> ordersList;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public List<Orders> getOrdersList() {
        return ordersList;
    }
    public void setOrdersList(List<Orders> ordersList) {
        this.ordersList = ordersList;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", sex=" + sex
                + ", birthday=" + birthday + ", address=" + address + "]";
    }
}

对应的sql映射:
        <select id="findUserAndOrders" resultMap="userAndOrderResultMap">
            select a.*,b.id oid,user_id,number,createtime 
            from user a,orders b 
            where a.id=b.user_id
        </select>
mapper.xml配置
        <resultMap type="com.wang.pojo.User" id="userAndOrderResultMap">
            <id column=" id" property="id"/>
            <result column="username" property="username"/>
            <result column="sex" property="sex"/>
            <result column="birthday" property="birthday"/>
            <result column="address" property="address"/>
            
            <!-- 指定对应的集合对象关系映射
                property:将数据放入User对象中的ordersList中
                ofType:指定ordersList的范型的类型
             -->
            <collection property="ordersList" ofType="com.wang.pojo.Orders">
                <id column="oid" property="id"/>
                <result column="user_id" property="userId"/>
                <result column="number" property="number"/>
                <result column="createtime" property="createtime"/>
                <result column="note" property="note"/>    
            </collection>
        </resultMap>
        <select id="findUserAndOrders" resultMap="userAndOrderResultMap">
            select a.*,b.id oid,user_id,number,createtime 
            from user a,orders b 
            where a.id=b.user_id
        </select>

 

标签resultMap中collection指定对应的集合对象关系映射

接口定义:
    public List<User> findUserAndOrders();

 

测试:
    @Test
    public void testfindUserAndOrders() throws Exception{
        SqlSession session = factory.openSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        
        List<User> customOrders = mapper.findUserAndOrders();
        
        System.out.println(customOrders);
        
    }

 




整个:UserMapper.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">
<!-- 
    mapper接口代理实现规则:
        1、映射文件中namespace要等于接口的全路径名
        2、映射文件中sql语句id要等于接口的方法名
        3、映射文件中传入参数类型要等于接口方法的传入参数类型
        4、映射文件中返回结果集类型要等于接口方法的返回值类型
 -->
<mapper namespace="com.wang.mapper.UserMapper"> 
<!-- 封装sql条件,封装后可以重用
    ID:是唯一表示 -->
    <sql id="userWhere">
        <!-- where 标签作用:
            1、会自动向sql中添加where关键字
            2、会自动去掉第一个条件的and关键字
             -->
        <where>
            <if test="username !=null and username !=‘‘">
            and username like ‘%${username}%‘
        </if>
        <if test="sex !=null and sex !=‘‘">
            and sex =#{sex}
        </if>
        </where>        
    </sql>



        <!-- 
    id:sql语句唯一表示
    parameterType:指定传入参数类型,对应pojo属性的类型
    resultType:返回结果类型
    #{}占位符,起到站位的作用,如果传入的是基本类型(string、long、int、boolean、float等),
    那么#{}中的变量名称可以是随意写,一般写属性
    -->
    <select id="findUserById" parameterType="java.lang.Integer" resultType="com.wang.pojo.User">
        SELECT * from user WHERE id =#{id}
    </select>
    <!-- 
        如果返回结果为集合,可以调用selectList方法,这个方法返回的结果就是一个集合,所映射的文件一个配置成集合范型的类型
         ${}拼接符,字符串原样拼接,如果传入的是基本类型(string、long、int、boolean、float等),
    那么%{}中的变量名称必须是value
    注意:有sql注入的风险
     -->
    <select id="findUserByUserName" parameterType="java.lang.String" resultType="com.wang.pojo.User">
        SELECT * from user where  username like ‘%${value}%‘
    </select>
    <!-- 
        #{}:如果传入的pojo类型,那么#{}中的变量名称必须是pojo中对应的属性.属性.属性.....
     如果要返回数据库自增主键,使用SELECT LAST_INSERT_ID()
     -->
    <insert id="insertUser" parameterType="com.wang.pojo.User">
    <!--
         执行SELECT LAST_INSERT_ID()数据库函数,返回自增主键
         keyProperty:将返回的主键放入传入参数的Id中保存
         order:当前函数相对于insert语句的执行顺序,在insert前是BEFORE之后是AFTER
         resultType:ID的类型,就是keyProperty中的类型
     -->
        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
            SELECT LAST_INSERT_ID()
        </selectKey>
        INSERT INTO user (username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
    </insert>
    
    <delete id="deleteUserById" parameterType="java.lang.Integer">
        delete from user where id=#{id}
    </delete>
    
    <update id="updateById" parameterType="com.wang.pojo.User">
        update user set username=#{username} where id=#{id}
    </update>
    
    <!-- 只有返回一行一列的时候,那么返回值类型才可以是指定成基本类型 -->
    <select id="findUserCount" resultType="java.lang.Integer">
        select count(*) from user
    </select>
    
    <select id="findUserByUserNameAndSex" parameterType="com.wang.pojo.User" resultType="com.wang.pojo.User">
        select * from user
        <include refid="userWhere"></include>
    </select>
    
    <select id="findUserByIds" parameterType="com.wang.pojo.QueryVo" resultType="com.wang.pojo.User">    
        select * from user
        <where>
            <if test="ids !=null">
            <!-- foreach:循环传入集合的参数
                collection:传入的集合
                item:每次循环将循环出的数据放入这个变量中
                open:循环开始拼接的字符串
                close:循环结束拼接的字符串
                separator:循环中拼接分隔符
                 -->
                <foreach collection="ids" item="id" open="id in (" close=") " separator=",">
                    #{id}
                </foreach>
            </if>
        </where>
    </select>
    
    <!-- 一对一:自动映射 -->
    <!-- resultType返回的属性名与列命一直 -->
    <select id="findOrdersAndUser1" resultType="cn.itheima.pojo.CustomOrders">
        select a.*,b.id uid,username,birthday,sex,address 
        from orders a,user b 
        where a.user_id = b.id
    </select>
    
    <!-- 一对一:手动映射 -->
    <!--id:resultMap唯一标识
        type:将查询出的数据放入指定的对象中 
        注意:手动映射需要:指定数据库中表的字段名与java中pojo类的属性名称对应关系
    -->
    <!-- 以Orders为主,查询数据放入其中,把User放入其中当做属性 -->
    <resultMap type="com.wang.pojo.Orders" id="orderAndUserResultMap">
        <!-- id标签指定主键字段对应关系
            column:列,数据库中字段名称
            property:pojo中属性名
         -->
        <id column="id" property="id"/>
        <!--result指定非属性列的对应关系  -->
        <result column="user_id" property="userId"/>
        <result column="number" property="number"/>
        <result column="createtime" property="createtime"/>
        <result column="note" property="note"/>
        
        <!-- 指定单个对象的对应关系
            property:指定将数据放入Oders中的user属性中
            JavaType:支付user属性类型
         -->
        <association property="user" javaType="com.wang.pojo.User">
            <id column="uid" property="id"/>
            <result column="username" property="username"/>
            <result column="sex" property="sex"/>
            <result column="birthday" property="birthday"/>
            <result column="address" property="address"/>            
        </association>
    </resultMap>
    <select id="findOrdersAndUser2" resultMap="orderAndUserResultMap">
        select a.*,b.id uid,username,birthday,sex,address 
        from orders a,user b 
        where a.user_id = b.id
    </select>
        
        
        <resultMap type="com.wang.pojo.User" id="userAndOrderResultMap">
            <id column=" id" property="id"/>
            <result column="username" property="username"/>
            <result column="sex" property="sex"/>
            <result column="birthday" property="birthday"/>
            <result column="address" property="address"/>
            
            <!-- 指定对应的集合对象关系映射
                property:将数据放入User对象中的ordersList中
                ofType:指定ordersList的范型的类型
             -->
            <collection property="ordersList" ofType="com.wang.pojo.Orders">
                <id column="oid" property="id"/>
                <result column="user_id" property="userId"/>
                <result column="number" property="number"/>
                <result column="createtime" property="createtime"/>
                <result column="note" property="note"/>    
            </collection>
        </resultMap>
        <select id="findUserAndOrders" resultMap="userAndOrderResultMap">
            select a.*,b.id oid,user_id,number,createtime 
            from user a,orders b 
            where a.id=b.user_id
        </select>
</mapper>

 

对应的UserMapper.java接口
package com.wang.mapper;

import java.util.List;

import cn.itheima.pojo.CustomOrders;

import com.wang.pojo.Orders;
import com.wang.pojo.QueryVo;
import com.wang.pojo.User;

public interface UserMapper {
    
    public com.wang.pojo.User findUserById(java.lang.Integer id);
    
    //动态代理形式中如果返回结果集为list,那么mybatis会生成实现类的使用
    //会自动调用selectList方法
    public List<User> findUserByUserName(String name);
    
    public void insertUser(User user);
    
    public Integer findUserCount();
    
    public List<User> findUserByUserNameAndSex(User user);
    
    public List<User> findUserByIds(QueryVo vo);
    
    public List<CustomOrders> findOrdersAndUser1();
    
    public List<Orders> findOrdersAndUser2();
    
    public List<User> findUserAndOrders();


}

 



 

总结:

1、Mybatis解决jdbc编程的问题

  1、  数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。

    解决:在SqlMapConfig.xml中配置数据链接池,使用连接池管理数据库链接。

  2、  Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。

    解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。

  3、  向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。

    解决:Mybatis自动将java对象映射至sql语句,通过statement中的parameterType定义输入参数的类型。

  4、  对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。

    解决:Mybatis自动将sql执行结果映射至java对象,通过statement中的resultType定义输出结果的类型。

2、mybatis与hibernate不同

  Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句,不过mybatis可以通过XML或注解方式灵活配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,最后将sql执行的结果再映射生成java对象。

   Mybatis学习门槛低,简单易学,程序员直接编写原生态sql,可严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。

   Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用hibernate开发可以节省很多代码,提高效率。但是Hibernate的学习门槛高,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡,以及怎样用好Hibernate需要具有很强的经验和能力才行。

  总之,按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构,所以框架只有适合才是最好。 

 



































以上是关于mybatis基础2的主要内容,如果未能解决你的问题,请参考以下文章

markdown [mybatis参考]关于mybatis #mybatis的一些片段

MyBatis高级特性

[mybatis]动态sql_sql_抽取可重用的sql片段

mybatis学习(39):动态sql片段

使用mybatis的两种方式

Mybatis -- 动态Sql概述动态Sql之<if>(包含<where>)动态Sql之<foreach>sql片段抽取