Mybatis简介

来源:互联网 发布:电脑报淘宝旗舰店 编辑:程序博客网 时间:2024/05/23 23:52
1. MyBatis概念
  MyBatis本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。它支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。

2. MyBatis和Hibernate比较
  1)hibernate是全自动,而mybatis是半自动。hibernate完全可以通过对象关系模型实现对数据库的操作,拥有完整的JavaBean对象与数据库的映射结构来自动生成sql。而mybatis仅有基本的字段映射,对象数据以及对象实际关系仍然需要通过手写sql来实现和管理。
  2)hibernate数据库移植性远大于mybatis。hibernate通过它强大的映射结构和hql语言,大大降低了对象与数据库(oracle、mysql等)的耦合性,而mybatis由于需要手写sql,因此与数据库的耦合性直接取决于程序员写sql的方法,如果sql不具通用性而用了很多某数据库特性的sql语句的话,移植性也会随之降低很多,成本很高。
  3)hibernate拥有完整的日志系统,mybatis则欠缺一些。hibernate日志系统非常健全,涉及广泛,包括:sql记录、关系异常、优化警告、缓存提示、脏数据警告等;而mybatis则除了基本记录功能外,功能薄弱很多。
  4)mybatis相比hibernate需要关心很多细节。hibernate配置要比mybatis复杂的多,学习成本也比mybatis高。但也正因为mybatis使用简单,才导致它要比hibernate关心很多技术细节。mybatis由于不用考虑很多细节,开发模式上与传统jdbc区别很小,因此很容易上手并开发项目,但忽略细节会导致项目前期bug较多,因而开发出相对稳定的软件很慢,而开发出软件却很快。hibernate则正好与之相反。但是如果使用hibernate很熟练的话,实际上开发效率丝毫不差于甚至超越mybatis。
  5)sql直接优化上,mybatis要比hibernate方便很多。由于mybatis的sql都是写在xml里,因此优化sql比hibernate方便很多。而hibernate的sql很多都是自动生成的,无法直接维护sql;虽有hql,但功能还是不及sql强大,见到报表等变态需求时,hql也歇菜,也就是说hql是有局限的;hibernate虽然也支持原生sql,但开发模式上却与orm不同,需要转换思维,因此使用上不是非常方便。总之写sql的灵活度上hibernate不及mybatis。
  6)Hibernate有更好的二级缓存机制,可以使用第三方缓存。而MyBatis的二级缓存机制不佳。

二、MyBatis简单示例
1. 导包
  新建一个Java项目,将 mybatis-3.1.1.jar 和 mysql-connector-java-5.1.6.jar 导入即可。

2. src/Configuration.xml配置文件
  Configuration.xml是mybatis用来建立 sessionFactory 用的,里面主要包含了数据库连接相关东西,还有java类所对应的别名,比如<typeAlias alias="User" type="com.jiang.mybatis.model.User"/>这个别名非常重要,你在具体的类的映射中,比如User.xml 中resultType就是对应这里的。要保持一致,当然这里的resultType还有另外单独的定义方式,后面再说。里面的<mapper resource="com/jiang/mybatis/model/User.xml"/>是包含要映射的类的xml配置文件。
Java代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  
  3. "http://mybatis.org/dtd/mybatis-3-config.dtd">  
  4. <configuration>  
  5.     <typeAliases>   
  6.         <typeAlias alias="User" type="com.jiang.mybatis.model.User"/>   
  7.     </typeAliases>   
  8.   
  9.     <environments default="development">  
  10.         <environment id="development">  
  11.         <transactionManager type="JDBC"/>  
  12.             <dataSource type="POOLED">  
  13.             <property name="driver" value="com.mysql.jdbc.Driver"/>  
  14.             <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis" />  
  15.             <property name="username" value="root"/>  
  16.             <property name="password" value="1234"/>  
  17.             </dataSource>  
  18.         </environment>  
  19.     </environments>  
  20.       
  21.     <mappers>  
  22.         <mapper resource="com/jiang/mybatis/model/User.xml"/>  
  23.     </mappers>  
  24. </configuration>  


3. User.java实体
Java代码  收藏代码
  1. package com.jiang.mybatis.model;  
  2.   
  3. public class User {  
  4.       
  5.     private int id;  
  6.     private String userName;  
  7.     private String userAge;  
  8.     private String userAddress;  
  9.       
  10.     public int getId() {  
  11.         return id;  
  12.     }  
  13.     public void setId(int id) {  
  14.         this.id = id;  
  15.     }  
  16.     public String getUserName() {  
  17.         return userName;  
  18.     }  
  19.     public void setUserName(String userName) {  
  20.         this.userName = userName;  
  21.     }  
  22.     public String getUserAge() {  
  23.         return userAge;  
  24.     }  
  25.     public void setUserAge(String userAge) {  
  26.         this.userAge = userAge;  
  27.     }  
  28.     public String getUserAddress() {  
  29.         return userAddress;  
  30.     }  
  31.     public void setUserAddress(String userAddress) {  
  32.         this.userAddress = userAddress;  
  33.     }  
  34. }  


4. User.xml映射文件
Java代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"   
  3. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
  4.   
  5. <mapper namespace="com.jiang.mybatis.models.UserMapper">  
  6.     <!-- 注意:此处resultType的User为Configuration里的别名。  
  7.        实体的属性和数据库中的字段名相同时会自动匹配,如果不同则需要配置一个自己的resultMap然后指定一个返回类型为resultMap的自定义Map -->  
  8.     <select id="selectUserByID" parameterType="int" resultType="User">  
  9.         select * from user where id = #{id}  
  10.     </select>  
  11. </mapper>  


5. 测试
Java代码  收藏代码
  1. package test;  
  2.   
  3. import java.io.Reader;  
  4. import org.apache.ibatis.io.Resources;  
  5. import org.apache.ibatis.session.SqlSession;  
  6. import org.apache.ibatis.session.SqlSessionFactory;  
  7. import org.apache.ibatis.session.SqlSessionFactoryBuilder;  
  8. import com.jiang.mybatis.model.User;  
  9.   
  10. public class Test {  
  11.     private static SqlSessionFactory sqlSessionFactory;  
  12.     private static Reader reader;  
  13.     static {  
  14.         try {  
  15.             reader = Resources.getResourceAsReader("Configuration.xml");  
  16.             sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);  
  17.         } catch (Exception e) {  
  18.             e.printStackTrace();  
  19.         }  
  20.     }  
  21.     public static SqlSessionFactory getSession() {  
  22.         return sqlSessionFactory;  
  23.     }  
  24.     public static void main(String[] args) {  
  25.         SqlSession session = sqlSessionFactory.openSession();  
  26.         try {  
  27.             User user = (User) session.selectOne(  
  28.                     "com.jiang.mybatis.models.UserMapper.selectUserByID"1);  
  29.             System.out.println(user.getUserAddress());  
  30.             System.out.println(user.getUserName());  
  31.         } finally {  
  32.             session.close();  
  33.         }  
  34.     }  
  35. }  



三、基于命名空间的接口方式编程
  基于接口方式的编程有很多优点,首先它不是基于文字的,那就更安全了。第二,如果你的 IDE 有代码补全功能,那么你可以利用它来操纵已映射的 SQL 语句。第三,不需要强制类型转换,同时 IUserMapper接口可以保持简洁,返回值类型很安全(参数类型也很安全) 。

1. 新建接口类IUserOperation.java
Java代码  收藏代码
  1. package com.jiang.mybatis.inter;  
  2. import com.jiang.mybatis.model.User;  
  3. public interface IUserOperation {      
  4.     //这里的方法名必须和映射文件里的select的id相同  
  5.     public User selectUserByID(int id);  
  6. }  


2. 修改User.xml映射文件
<mapper namespace="com.jiang.mybatis.inter.IUserOperation">

3. 测试
Java代码  收藏代码
  1. ...  
  2. public static void main(String[] args) {  
  3.         SqlSession session = sqlSessionFactory.openSession();  
  4.         try {  
  5.             IUserOperation userOperation = session.getMapper(IUserOperation.class);  
  6.             User user = userOperation.selectUserByID(1);  
  7.             System.out.println(user.getUserAddress());  
  8.             System.out.println(user.getUserName());  
  9.         } finally {  
  10.             session.close();  
  11.         }  
  12.     }  
  13. ...  


四、MyBatis实现增删改查
1. 命名空间接口IUserOperation.java
Java代码  收藏代码
  1. package com.jiang.mybatis.inter;  
  2. import java.util.List;  
  3. import com.jiang.mybatis.model.User;  
  4. public interface IUserOperation {      
  5.     //这里的方法名必须和映射文件里的select的id相同  
  6.     public User selectUserByID(int id);  
  7.     public List<User> selectUsers(String userName);  
  8.     public void addUser(User user);  
  9.     public void updateUser(User user);   
  10.     public void deleteUser(int id);  
  11. }  


2. 映射文件User.xml
Java代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"   
  3. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
  4.   
  5. <mapper namespace="com.jiang.mybatis.inter.IUserOperation">  
  6.     <resultMap type="User" id="resultListUser">  
  7.         <id column="id" property="id" />  
  8.         <result column="user_name" property="userName" />  
  9.         <result column="user_age" property="userAge" />  
  10.         <result column="user_address" property="userAddress" />  
  11.     </resultMap>  
  12.       
  13.     <select id="selectUserByID" parameterType="int" resultMap="resultListUser">  
  14.         select * from user where id = #{id}  
  15.     </select>  
  16.       
  17.     <!-- 返回list 的select 语句,注意 resultMap 的值是指向前面定义好的 -->  
  18.     <select id="selectUsers" parameterType="string" resultMap="resultListUser">  
  19.         select * from user where user_name like #{userName}  
  20.     </select>   
  21.       
  22.     <!--id和parameterType分别与IUserOperation接口中的addUser方法的名字和参数类型一致;  
  23.            以#{name}的形式引用User参数的属性,MyBatis将使用反射读取Student参数的此属性,#{name}中name大小写敏感;  
  24.       seGeneratedKeys设置为"true"表明要MyBatis获取由数据库自动生成的主键;  
  25.       keyProperty="id"指定把获取到的主键值注入到User的id属性-->   
  26.     <insert id="addUser" parameterType="User" useGeneratedKeys="true" keyProperty="id">   
  27.         insert into user(user_name,user_age,user_address) values (#{userName},#{userAge},#{userAddress})    
  28.     </insert>  
  29.       
  30.     <update id="updateUser" parameterType="User" >  
  31.         update user set user_name=#{userName},user_age=#{userAge},user_address=#{userAddress} where id=#{id}  
  32.     </update>  
  33.       
  34.     <delete id="deleteUser" parameterType="int">  
  35.         delete from user where id=#{id}  
  36.     </delete>  
  37. </mapper>  


3. 测试
Java代码  收藏代码
  1. package test;  
  2. import java.io.Reader;  
  3. import java.util.List;  
  4. import org.apache.ibatis.io.Resources;  
  5. import org.apache.ibatis.session.SqlSession;  
  6. import org.apache.ibatis.session.SqlSessionFactory;  
  7. import org.apache.ibatis.session.SqlSessionFactoryBuilder;  
  8. import com.jiang.mybatis.inter.IUserOperation;  
  9. import com.jiang.mybatis.model.User;  
  10. public class Test {  
  11.     private static SqlSessionFactory sqlSessionFactory;  
  12.     private static Reader reader;  
  13.     static {  
  14.         try {  
  15.             reader = Resources.getResourceAsReader("Configuration.xml");  
  16.             sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);  
  17.         } catch (Exception e) {  
  18.             e.printStackTrace();  
  19.         }  
  20.     }  
  21.     public static void main(String[] args) {  
  22.         Test test = new Test();  
  23.         test.selectUserByID();  
  24.         test.selectUsers();  
  25.         test.addUser();  
  26.         test.updateUser();  
  27.         test.deleteUser();  
  28.     }  
  29.     public void selectUserByID() {  
  30.         SqlSession session = sqlSessionFactory.openSession();  
  31.         try {  
  32.             IUserOperation userOperation = session.getMapper(IUserOperation.class);  
  33.             User user = userOperation.selectUserByID(1);  
  34.             System.out.println("selectUserByID: "+user.getUserAddress()+":"+user.getUserName());  
  35.         } finally {  
  36.             session.close();  
  37.         }  
  38.     }  
  39.     public void selectUsers() {  
  40.         SqlSession session = sqlSessionFactory.openSession();  
  41.         try {  
  42.             IUserOperation userOperation = session  
  43.                     .getMapper(IUserOperation.class);  
  44.             List<User> users = userOperation.selectUsers("AAA");  
  45.             for (User user : users) {  
  46.                 System.out.println("selectUsers: "+user.getId() + ":" + user.getUserName()  
  47.                         + ":" + user.getUserAddress());  
  48.             }  
  49.         } finally {  
  50.             session.close();  
  51.         }  
  52.     }  
  53.     public void addUser(){  
  54.         User user=new User();  
  55.         user.setUserAddress("人民广场");  
  56.         user.setUserName("飞鸟");  
  57.         user.setUserAge("33");  
  58.         SqlSession session = sqlSessionFactory.openSession();  
  59.         try {  
  60.             IUserOperation userOperation=session.getMapper(IUserOperation.class);  
  61.             userOperation.addUser(user);  
  62.             session.commit(); //增加必须提交事务,否则不会写入库中。  
  63.             System.out.println("addUser: id="+user.getId());  
  64.         } finally {  
  65.             session.close();  
  66.         }  
  67.     }  
  68.     public void updateUser(){  
  69.         //先得到用户,然后修改,提交。  
  70.         SqlSession session = sqlSessionFactory.openSession();  
  71.         try {  
  72.             IUserOperation userOperation=session.getMapper(IUserOperation.class);  
  73.             User user = userOperation.selectUserByID(1);              
  74.             user.setUserAddress("MMMMMMMM");  
  75.             userOperation.updateUser(user);  
  76.             session.commit();  
  77.         } finally {  
  78.             session.close();  
  79.         }  
  80.     }  
  81.     public void deleteUser(){  
  82.         SqlSession session = sqlSessionFactory.openSession();  
  83.         try {  
  84.             IUserOperation userOperation=session.getMapper(IUserOperation.class);             
  85.             userOperation.deleteUser(1);  
  86.             session.commit();              
  87.         } finally {  
  88.             session.close();  
  89.         }  
  90.     }  
  91. }  


五、MyBatis的关联查询
1. 增加实体Article.java
Java代码  收藏代码
  1. package com.jiang.mybatis.model;  
  2. public class Article {     
  3.     private int id;  
  4.     private User user;  
  5.     private String title;  
  6.     private String content;  
  7.     ....  
  8. }  


2. 命名空间接口IUserOperation.java
  public List<Article> getArticlesByUser(int id);

3. 映射文件User.xml
Java代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"   
  3. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
  4.   
  5. <mapper namespace="com.jiang.mybatis.inter.IUserOperation">  
  6.    <resultMap type="User" id="resultListUser">  
  7.         <id column="id" property="id" />  
  8.         <result column="user_name" property="userName" />  
  9.         <result column="user_age" property="userAge" />  
  10.         <result column="user_address" property="userAddress" />  
  11.     </resultMap>  
  12.       
  13.     <resultMap id="resultUserArticleList" type="Article">  
  14.         <id property="id" column="aid" />  
  15.         <result property="title" column="title" />  
  16.         <result property="content" column="content" />          
  17.         <association property="user" javaType="User" resultMap="resultListUser" />               
  18.     </resultMap>  
  19.       
  20.     <sql id="Base_Column_List">  
  21.         user.id,user.user_name,user.user_address,article.id aid,article.title,article.content  
  22.     </sql>  
  23.       
  24.     <select id="getUserArticles" parameterType="int" resultMap="resultUserArticleList">  
  25.        select  <include refid="Base_Column_List"/>   
  26.        from user,article where user.id=article.userid and user.id=#{id}  
  27.     </select>  
  28. </mapper>  


4. 测试
Java代码  收藏代码
  1. public void getUserArticles(int userid){  
  2.     SqlSession session = sqlSessionFactory.openSession();  
  3.     try {  
  4.         IUserOperation userOperation=session.getMapper(IUserOperation.class);             
  5.         List<Article> articles = userOperation.getUserArticles(userid);  
  6.         for(Article article:articles){  
  7.             System.out.println(article.getTitle()+" : "+article.getUser().getUserName());  
  8.         }  
  9.     } finally {  
  10.         session.close();  
  11.     }  
  12. }  


六、MyBatis的动态SQL
1. if标签
    <if test="userName != null">
        and user_name= #{userName}
    </if>
  如果userName不为null则加上if中的筛选条件

2. choose标签
    <choose>
        <when test="userAge != null">
            and user_age = #{userAge}
        </when>
        <when test="userAddress != null">
            and user_address= #{userAddress}
        </when>
        <otherwise>
            and user_name = "userName"
        </otherwise>
    </choose>
  choose标签跟switch效果一样,如果userAge不为null就增加该条件,然后退出。如果所有的when都为null,则执行otherwise中的筛选条件。

3. where标签
    select * from t_blog
    <where>
        <if test="title != null">
            title = #{title}
        </if>
        <if test="content != null">
            and content = #{content}
        </if>
    </where>
  where标签可以智能的处理SQL,如果标签里面的内容不全为null的话,它会自动在SQL里加入一个where语句,并且可以去掉条件中多余的AND或OR。

4. set标签
    update t_blog
    <set>
        <if test="title != null">
            title = #{title},
        </if>
        <if test="content != null">
            content = #{content},
        </if>
        <if test="owner != null">
            owner = #{owner}
        </if>
    </set>
  set标签主要用于update语句,对SQL的处理和where标签一样。

5. trim标签
    select * from t_blog
    <trim prefix="where" prefixOverrides="and | or">
        <if test="title != null">
            title = #{title}
        </if>
        <if test="content != null">
            and content = #{content}
        </if>
        <if test="owner != null">
            or owner = #{owner}
        </if>
    </trim>
  trim标签的作用和上面的where和set相似,如果里面条件不全为null,则加上prefix条件,并能自动去掉前面多余的and或or。
  前缀prefix和后缀suffix分别对应的属性是prefixOverrides和suffixOverrides。
 
6. foreach标签
    select * from t_news n where
    <foreach collection="listTag" index="index" item="tag" open="(" separator="," close=")">
        #{tag} in n.tags
    </foreach>
    select * from xxx where mid in
    <foreach collection="mids" item="mid"  open="(" separator="," close=")">
        #{mid}
    </foreach>
  foreach标签的作用是循环的把collection指定的参数里的每个元素加入一个分支语句连接起来。标签的属性主要有 item,index,collection,open,separator,close。
    collection应该是传入参数中的一个list或者数组或者map
    item表示集合中每一个元素进行迭代时的别名
    index指定每次迭代到的位置
    open表示该语句以什么开始
    separator表示在每次进行迭代之间以什么符号作为分隔符
    close表示以什么结束
  上面的标签转换为SQL为:
    select * from xxx where mid in ( ? , ? ...)
2 0
原创粉丝点击