Mybatis笔记

jopen 10年前

1.ibatismybatis的前身。

2.mybatishibernate灵活,性能也比hibernate好,而且也比较轻量级。

3.什么是mybatis

        MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架。

        MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。

        MyBatis使用简单的XML或注解用于配置和原始映射,

        将接口和JavaPOJOsPlan Old Java Objects,普通的Java对象) 映射成 数据库中的记录.

 

4.orm工具的基本思想:

        无论是用过的hibernate,mybatis,你都可以发现他们有一个共同点:

        1. 从配置文件(通常是XML配置文件中)得到 sessionfactory.

        2. sessionfactory 产生 session

        3. session 中完成对数据的增删改查和事务提交等.

        4. 在用完之后关闭session

        5. java 对象和 数据库之间有做mapping 的配置文件,也通常是xml 文件。

 

5.对于物理分页方案,不同的数据库,有不同的实现方法。

        对于 mysql 来说 就是利用 limit offset, pagesize 方式来实现的。

        oracle 是通过 rownum 来实现的。

 

6.实现 mybatis 物理分页,一个最简单的方式是,是在你的mapperSQL语句中直接写类似如下方式 :

        <select id="getUserArticles" parameterType="Your_params" resultMap="resultUserArticleList">

              select user.id,user.userName,user.userAddress,article.id aid,article.title,article.content from user,article

              where user.id=article.userid and user.id=#{id} limit #{offset},#{pagesize}

       </select>

        用这种方式,肯定可以实现分页。这是简单的一种方式。

        但更通用的一种方式是用 mybatis 插件的方式, 代码参考Z_LiamMS_V0.5中的PagePlugin.java

 

7.总体说来mybatis 动态SQL 语句主要有以下几类:

        1). if 语句 (简单的条件判断)

                <select id="dynamicIfTest" parameterType="Blog" resultType="Blog">

                     select * from t_blog where 1 = 1

                     <if test="title != null">

                           and title = #{title}

                     </if>

                     <if test="content != null">

                           and content = #{content}

                     </if>

                     <if test="owner != null">

                           and owner = #{owner}

                     </if>

              </select>

 

 

 

 

 

        2). choose (when,otherwize) ,相当于java 语言中的 switch , jstl 中的choose 很类似.

                <select id="dynamicChooseTest" parameterType="Blog" resultType="Blog">

                     select * from t_blog where 1 = 1

                     <choose>

                           <when test="title != null">

                                  and title = #{title}

                            </when>

                           <when test="content != null">

                                  and content = #{content}

                           </when>

                           <otherwise>

                                  and owner = "owner1"

                           </otherwise>

                     </choose>

              </select>

 

        3). trim (对包含的内容加上 prefix,或者 suffix 等,前缀,后缀)

                <select id="dynamicTrimTest" parameterType="Blog" resultType="Blog">

                     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>

              </select>

 

        4). where (主要是用来简化sql语句中where条件判断的,能智能的处理 and or ,不必担心多余导致语法错误)

                <select id="dynamicWhereTest" parameterType="Blog" resultType="Blog">

                     select * from t_blog

                     <where>

                           <if test="title != null">

                                  title = #{title}

                           </if>

                           <if test="content != null">

                                  and content = #{content}

                           </if>

                           <if test="owner != null">

                                  and owner = #{owner}

                           </if>

                     </where>

              </select>

 

 

 

 

 

 

 

 

 

 

        5). set (主要用于更新时)

                <update id="dynamicSetTest" parameterType="Blog">

                     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>

                     where id = #{id}

              </update>

 

        6). foreach (在实现 mybatis in 语句查询时特别有用)

                (6.1)单参数List的类型

                <select id="dynamicForeachTest" resultType="Blog">

                     select * from t_blog where id in

                     <foreach collection="list" index="index" item="item" open="(" separator="," close=")">

                           #{item}

                     </foreach>

              </select>

                对应的Mapper:

                public List<Blog> dynamicForeachTest(List<Integer> ids);

 

                (6.2)数组类型的参数

                <select id="dynamicForeach2Test" resultType="Blog">

                     select * from t_blog where id in

                    <foreach collection="array" index="index" item="item" open="(" separator="," close=")">

                           #{item}

                     </foreach>

              </select>

                对应mapper:

                public List<Blog> dynamicForeach2Test(int[] ids);

 

                (6.3)Map 类型的参数

                <select id="dynamicForeach3Test" resultType="Blog">

                     select * from t_blog where title like "%"#{title}"%" and id in

                     <foreach collection="ids" index="index" item="item" open="(" separator="," close=")">

                           #{item}

                     </foreach>

              </select>

                mapper 应该是这样的接口:

                public List<Blog> dynamicForeach3Test(Map<String, Object> params);

 

 

 

 

8.使用mybatis代码生成工具

        1)下载mybatis-generator-core-1.3.2.jar,拷贝到WEB-INF/lib

        2)在数据库中创建mybatis数据库和category测试表

                Drop TABLE IF EXISTS `category`;

              Create TABLE `category` (

                     `id` int(11) NOT NULL AUTO_INCREMENT,

                     `catname` varchar(50) NOT NULL,

                     `catdescription` varchar(200) DEFAULT NULL,

                     PRIMARY KEY (`id`)

              ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

        3)在用mybatis 代码生成工具之前,相应的目录必须先创建好:

                com.liam.inter 用来存放mybatis 接口对象.

                com.liam.mapper用来存放sql mapper对应的映射,sql语句等.

                com.liam.model 用来存放与数据库对应的model

 

        4)配置文件 mbgConfiguration.xml 放在src 目录下.配置文件内容如下:

        <?xml version="1.0" encoding="UTF-8"?>

       <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"

                "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

 

       <generatorConfiguration>

               

       <!-- 配置mysql 驱动jar包路径.用了绝对路径 -->

       <classPathEntry

location="D:\Work\Java\eclipse\workspace\myBatisGenerator\WebContent\WEB-INF\lib\mysql-connector-java-5.1.22-bin.jar" />

 

          <context id="liam_mysql_tables" targetRuntime="MyBatis3">

               

                     <!-- 为了防止生成的代码中有很多注释,比较难看,加入下面的配置控制 -->

                     <commentGenerator>

                       <property name="suppressAllComments" value="true" />

                       <property name="suppressDate" value="true" />

                     </commentGenerator>

                     <!-- 注释控制完毕 -->

               

                     <!-- 数据库连接 -->

                     <jdbcConnection driverClass="com.mysql.jdbc.Driver"

                           connectionURL="jdbc:mysql://127.0.0.1:3306/mybatis?characterEncoding=utf8"

                           userId="root"

                           password="password">

                     </jdbcConnection>

 

                     <javaTypeResolver >

                       <property name="forceBigDecimals" value="false" />

                     </javaTypeResolver>

                    

                     <!-- 数据表对应的model   -->

                     <javaModelGenerator targetPackage="com.liam.model" targetProject="src">

                       <property name="enableSubPackages" value="true" />

                       <property name="trimStrings" value="true" />

                     </javaModelGenerator>

                    

                     <!-- sql mapper 隐射配置文件 -->

                     <sqlMapGenerator targetPackage="com.liam.mapper"  targetProject="src">

 

 

                       <property name="enableSubPackages" value="true" />

                     </sqlMapGenerator>

                    

                     <!-- ibatis2 中是dao层,但在mybatis3中,其实就是mapper接口 -->

                     <javaClientGenerator type="XMLMAPPER" targetPackage="com.liam.inter"  targetProject="src">

                       <property name="enableSubPackages" value="true" />

                     </javaClientGenerator>

                    

                     <!-- 要对那些数据表进行生成操作,必须要有一个. -->

                     <table schema="mybatis" tableName="category" domainObjectName="Category"

                           enableCountByExample="false" enableUpdateByExample="false"

                           enableDeleteByExample="false" enableSelectByExample="false"

                           selectByExampleQueryId="false">    

                     </table>

 

              </context>

       </generatorConfiguration>

 

 

        5)创建一个com.liam.testpackage ,并在此package下建立一个测试的类GenMain

                public class GenMain {

                     public static void main(String[] args) {

                           List<String> warnings = new ArrayList<String>();

                           boolean overwrite = true;

                           String genCfg = "/mbgConfiguration.xml";

                           File configFile = new File(GenMain.class.getResource(genCfg).getFile());

                           ConfigurationParser cp = new ConfigurationParser(warnings);

                           Configuration config = null;

                           try {

                                  config = cp.parseConfiguration(configFile);

                           } catch (IOException e) {

                                  e.printStackTrace();

                           } catch (XMLParserException e) {

                                  e.printStackTrace();

                           }

                           DefaultShellCallback callback = new DefaultShellCallback(overwrite);

                           MyBatisGenerator myBatisGenerator = null;

                           try {

                                  myBatisGenerator = new MyBatisGenerator(config, callback, warnings);

                           } catch (InvalidConfigurationException e) {

                                  e.printStackTrace();

                           }

                           try {

                                  myBatisGenerator.generate(null);

                           } catch (SQLException e) {

                                  e.printStackTrace();

                           } catch (IOException e) {

                                  e.printStackTrace();

                           } catch (InterruptedException e) {

                                  e.printStackTrace();

                           }

                     }

              }

 

 

 

 

 

 

 

        6)运行测试类的main方法,随即生成mybatis相关代码

        7)如果你想生成example之类的东西,需要在<table></table>里面去掉:

                enableCountByExample="false"

              enableUpdateByExample="false"

              enableDeleteByExample="false"

              enableSelectByExample="false"

              selectByExampleQueryId="false"

                这部分配置,这是生成Example而用的,一般来说对项目没有用.

        8)另外生成的sql mapper等,只是对单表的增删改查,

                如果你有多表join操作,你就可以手动配置。

                如果调用存储过程,你也需要手工配置。

                这时工作量已经少很多了。