MyBetis3.2框架技術

1.1    MyBatis介紹

MyBatis 世界上流行最普遍的基於SQ語句的ORM框架,由Clinton Begin 在2002 年建立,其後,捐獻給了Apache基金會,成立了iBatis 項目。2010 年5 月,將代碼庫遷致Google Code,並改名爲MyBatis.java

1.2 與Hibernate比較

  1. 學習成本:MyBatis簡單易學(特別是有SQL語法基礎的人),較接近JDBC
  2. 程序靈活性:MyBatis直接使用SQL,靈活性高
  3.  程序執行效律:MyBatis效律高
  4. 可移植性:hibernate較好(與數據庫關聯在配置中完成,HQL語句與數據庫無關)

1.3    適用場合

MyBatis是一個靈活的DAO層解決方案,知足較高的性能要求,能夠在不少場合使用,但通常如下場合不建議使用:mysql

  1. 須要支持多種數據庫或數據庫有移植要求
  2. 徹底動態SQL,例如:字段都要動態生成

使用的不是關係數據庫web

1.4 開發步驟(推薦)

  1. 新建JAVA項目或WEB項目
  2. 部署jar包(包括數據庫驅動包):使用MyBatis須要先下載jar包:下載地址http://code.google.com/p/mybatis
  3. 編寫主配置文件
  4. 建立數據庫及表
  5. 建立實體類及SQL映射文件
  6. 編寫數據庫接口及實現
  7. 編寫測試類及測試

1.5 開發示例

1.5.1  新建項目

新建java項目或web 項目。sql

1.5.2 導入JAR包

導入mybatis和數據庫驅動包、日誌包(配置日誌配置文件)。數據庫

1.5.3  建立myBatis-config.xml

(能夠參考用戶手冊)數組

<?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>
<!--能夠設置多個運行環境,知足不一樣須要,例如 開發、測試、生產環境上有不一樣一配置 -->
    <environments default="development">
        <environment id="development">
<!--事務管理類型主要有jdbc和managed,前者依賴於數據源得到的鏈接,後者依賴於容器 -->
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <!-- 若是數據庫設置爲UTF-8,則URL參數鏈接須要添加?useUnicode=true&amp;characterEncoding=UTF-8,以下 -->
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&amp;characterEncoding=UTF-8" />
                <property name="username" value="***" />
                <property name="password" value="***" />
            </dataSource>
        </environment>
    </environments>
</configuration>

1.5.4  建立數據庫及表

drop database if exists mybatis;
create database mybatis CHARACTER SET UTF8;
use mybatis;

create table dept(
    dept_id int primary key auto_increment,
    dept_name varchar(50),
    dept_address varchar(50)
);


insert into dept(dept_name,dept_address) values('研發部一部','廣州');
insert into dept(dept_name,dept_address) values('研發部二部','廣州');
insert into dept(dept_name,dept_address) values('研發部三部','深圳');
select * from dept;

1.5.5  建立實體類:Dept.java

public class Dept implements Serializable {
    private Integer deptId; //部門編號
    private String deptName;//部門名稱
    private String deptAddress;//部門地址
    public Integer getDeptId() {
        return deptId;
    }
    public void setDeptId(Integer deptId) {
        this.deptId = deptId;
    }
    public String getDeptName() {
        return deptName;
    }
    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }
    public String getDeptAddress() {
        return deptAddress;
    }
    public void setDeptAddress(String deptAddress) {
        this.deptAddress = deptAddress;
    }
    @Override
    public String toString() {
        return "Dept [deptId=" + deptId + ", deptName=" + deptName
                + ", deptAddress=" + deptAddress + "]";
    }    
}

1.5.6  建立SQL映射文件及修改主配置文件

SQL映射文件:DeptMapper.xml(能夠參考用戶手冊)session

<?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 namespace="cn.it.entity.DeptMapper">
    <!--  通常在查詢時使用-->
    <resultMap type="cn.it.entity.Dept" id="deptResultMap">
        <id property="deptId" column="dept_id"/>
        <result property="deptName" column="dept_name"/>
        <result property="deptAddress" column="dept_address"/>    
    </resultMap>
    <!-- 定義插入的sql語句,經過命名空間+id方式被定位 -->
    <insert id="insert" parameterType="cn.it.entity.Dept">
        insert into dept(dept_name,dept_address) values(#{deptName},#{deptAddress});
    </insert>
</mapper>

修改myBatis-config.xml,加入映射文件信息
<?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>
    <environments default="development">
    …………        
    </environments>
     
    <mappers>
        <mapper resource="cn/it/entity/DeptMapper.xml" />
    </mappers>
    
</configuration>

1.5.7  編寫數據庫操做

包括操做接口及實現,接口略,實現類爲:DeptDaoImpl.javamybatis

public class DeptDaoImpl {
    /**
     * 用於插入數據到dept表。
     * @param dept 部門信息
     * @return 表示受影響的行數
     */
    public int insert(Dept dept){
        /*
         * 1.讀取配置信息
         * 2.構建session工廠
         * 3.建立session
         * 4.啓動事務(可選)
         * 5.數據處理
         * 6.提交事務、回滾事務(可選)
         * 7.關閉session  
         */        
        int i=0;
        SqlSession session=null;
        String config="myBatis-config.xml";
       Reader reader = null;
        try {
            reader=Resources.getResourceAsReader(config);
            SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(reader);
            session=sqlSessionFactory.openSession();
            //事務默認自動啓動
            //SQL映射文件定義的命名空間+SQL語句的ID定位SQL語句,例以下的:cn.it.entity.DeptMapper.insert
            i=session.insert("cn.it.entity.DeptMapper.insert",dept);
            session.commit();        
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            session.rollback();
        }finally{
//關閉reader對象,這裏略
            session.close();
        }        
        return i;
    }
}

1.5.8  編寫測試類

須要導入junit包app

public class DeptTest {
    private static DeptDaoImpl deptDaoImpl;
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        deptDaoImpl=new DeptDaoImpl();
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
        deptDaoImpl=null;
    }

    @Test
    public void testInsert() {
        Dept dept=new Dept();
        dept.setDeptName("市場部");
        dept.setDeptAddress("深圳");
        int i=deptDaoImpl.insert(dept);
        System.out.println("受影響行數:"+i);
    }

}

2.基本的CRUD操做

2.1         準備工做(繼續使用前面的庫表和代碼)

2.2         別名與自定義別名

2.2.1  內置別名

對經常使用的 java 類型,已經內置了一些別名支持。這些別名都是不區分大小寫的。(詳細參看用戶手機)框架

2.2.2  自定義別名

在myBatis的主配置文件給cn.it.entity.Dept類建立別名Dept,後繼的DeptMapper.xml配置文件中可使用別名

<!-- 經過別名簡化對類的使用 -->
<typeAliases>
        <typeAlias type="cn.it.entity.Dept" alias="Dept" />
</typeAliases>

2.3  MyBatisUtil工具類

public class MyBatisUtil {

   
    private static final ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();
    private static SqlSessionFactory sessionFactory;
    
    private static String CONFIG_FILE_LOCATION = "myBatis-config.xml";

    static {
        try {
            buildSessionFactory();
        } catch (Exception e) {
            System.err.println("%%%% Error Creating SessionFactory %%%%");
            e.printStackTrace();
        }
    }
    private MyBatisUtil() {
    }
    
    /**
     * Returns the ThreadLocal Session instance.  Lazy initialize
     * the <code>SessionFactory</code> if needed.
     *
     *  @return Session
     *  @throws Exception
     */
    public static SqlSession getSession() throws Exception {
        SqlSession session = (SqlSession) threadLocal.get();

        if (session == null) {
            if (sessionFactory == null) {
                buildSessionFactory();
            }
            session = (sessionFactory != null) ? sessionFactory.openSession()
                    : null;
            threadLocal.set(session);
        }

        return session;
    }

    /**
     *  build  session factory
     *
     */
    public static void buildSessionFactory() {
        Reader reader=null;
        try {
            reader=Resources.getResourceAsReader(CONFIG_FILE_LOCATION);
            sessionFactory = new SqlSessionFactoryBuilder().build(reader);
        } catch (Exception e) {
            System.err.println("%%%% Error Creating SessionFactory %%%%");
            e.printStackTrace();
        }finally{
            try {
                reader.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    /**
     *  Close the single  session instance.
     *
     */
    public static void closeSession(){
        SqlSession session = (SqlSession) threadLocal.get();
        threadLocal.set(null);

        if (session != null) {
            session.close();
        }
    }

    /**
     *  return session factory
     *
     */
    public static SqlSessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

2.3         CRUD操做

2.3.1  新增操做

配置文件DeptMapper.xml使用別名, DeptDaoImpl.java新增方法使用工具類。

修改配置文件DeptMapper.xml(使用別名):

<!--parameterType="Dept"不寫時,也能自動根據代碼傳遞的參數Dept自動匹配 內容-->
<insert id="insert" parameterType="Dept">
        insert into dept(dept_name)    values(#{deptName});
</insert>

修改DeptDaoImpl.java新增方法(使用MyBatisUtil.java工具類):

/**
     * @param dept 部門信息
     * @return 保存信息後受影響的行數
     */
    public int saveDept(Dept dept) {
        int i = 0;
        try {
            session = MyBatisUtil.getSession();
            i = session.insert("cn.it.entity.DeptMapper.insertDept", dept);
            session.commit();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            session.rollback();
        } finally {
            try {
                MyBatisUtil.closeSession();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }            
        }

        return i;
}

2.3.2  修改操做

修改配置文件deptMapper.xml,添加

<update id="update" parameterType="Dept">
            update dept set dept_name=#{deptName} ,dept_address=#{deptAddress} where dept_id=#{deptId} 
</update>

修改DeptDaoImpl.java,添加update方法:

public int  update(Dept dept){
        SqlSession session = null;
        int i=0;

        try {
            session=MyBatisUtil.getSession();
            //方法的第一個參數爲DeptMapper.xml文件的命名空間+id
             i=session.update("cn.it.entity.DeptMapper.update",dept);
            System.out.println("受影響行數:"+i);
            session.commit();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            session.rollback();
            
        }finally{
                MyBatisUtil.closeSession();
        }    
        return i;
}

2.3.3  刪除操做

修改配置文件deptMapper.xml,添加

<delete id="delete" parameterType="Dept">
        delete from dept  where dept_id=#{deptId}
</delete>

修改DeptDaoImpl.java,添加delete方法:

public int delete(Dept dept){
        int i = 0;
        try {
            session=MyBatisUtil.getSession();
            //方法的第一個參數爲DeptMapper.xml文件的命名空間+id
            i=session.delete("cn.it.entity.DeptMapper.delete",dept);
            //System.out.println("受影響行數:"+i);
            session.commit();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            session.rollback();
            
        }finally{
            MyBatisUtil.closeSession();
        }        
        return i;
}

2.3.4  查詢操做(返回單條記錄)

配置deptMapper.xml文件的resultMap元素及SQL查詢語句

<!-- 表字段和實體屬性命名一致時能夠不配置 -->
    <resultMap id="deptResultMap" type="Dept">
        <id property="deptId" column="dept_id"/>
        <result property="deptName" column="dept_name"/>
        <result property="deptAddress" column="dept_address"/>    
    </resultMap>
<!—省略其它的配置信息 -->
    <!—返回單條記錄,表字段和對應實體屬性命名一致時能夠不使用resultMap屬性配置,直接使用resultType="返回的全類名或別名",建議使用前者;查詢結果爲全部字段時,也能夠用*表示  -->
    <select id="selectOne" parameterType="int" resultMap="deptResultMap"  >
        select dept_id, dept_name from dept where dept_id=#{deptId}    
</select>

修改DeptDaoImpl.java,添加selectOne方法:

public Dept selectOne(int deptId){
        Dept dept=null;
        try {
            session=MyBatisUtil.getSession();
            dept=(Dept)session.selectOne("cn.it.entity.DeptMapper.selectOne",deptId);
            System.out.println("dept:"+dept);
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            MyBatisUtil.closeSession();
        }
        return dept;
} 

2.3.5  查詢操做(返回多條記錄)

修改配置文件deptMapper.xml,添加

 

<!-- 返回多條記錄,返回結果配置的不是集合類型,而是集合元素的類型;參數也能夠經過Map等方式封裝  -->
    <select id="selectList" parameterType="Map"  resultMap="deptResultMap">
        select * from dept where dept_name like #{deptName}
</select>

修改DeptDaoImpl.java,添加selectList方法:

public List<Dept> selectList(Map map){
        List<Dept> depts=null;
        try {
            session=MyBatisUtil.getSession();
            depts=session.selectList("cn.it.entity.DeptMapper.selectList",map);
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            MyBatisUtil.closeSession();
        }
        return depts;
}

測試類代碼:

@Test
    public void testSelectList() {
        Map map=new HashMap();
        map.put("deptName", "%研%");
        List<Dept> depts=deptDaoImpl.selectList(map);
        for(Dept dept:depts){
            System.out.println("dept:"+dept);
        }
}

3.動態SQL操做

3.1    準備工做

建立表及庫,實體類,配置文件(參考上章節內容),如下爲建表和庫的SQL:

drop database if exists mybatis;
create database mybatis CHARACTER SET UTF8;
use mybatis;

create table dept(
    dept_id int primary key auto_increment,
    dept_name varchar(50),
    dept_address varchar(50)
);


insert into dept(dept_name,dept_address) values('研發部一部','廣州');
insert into dept(dept_name,dept_address) values('研發部二部','廣州');
insert into dept(dept_name,dept_address) values('研發部三部','深圳');
select * from dept;

3.2  IF語句

修改配置文件deptMapper.xml,添加

<!-- 動態IF條件 -->
    <select id="selectListUseIf" parameterType="Dept"  resultMap="deptResultMap">
        select * from dept where 1=1 
        <if test="deptId!=null">
            and dept_id=#{deptId} 
        </if>
        <if test="deptName!=null">
            and dept_name=#{deptName} 
        </if>
        <if test="deptAddress!=null">
            and dept_address=#{deptAddress}
        </if>
</select>

修改DeptDaoImpl.java,添加selectListUseIf方法:

//根據參數使用配置文件的IF語句自動填充查詢的過濾條件
    public List<Dept> selectListUseIf(Dept dept){
        List<Dept> depts=null;
        try {
            session=MyBatisUtil.getSession();
            depts=session.selectList("cn.it.entity.DeptMapper.selectListUseIf",dept);
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            MyBatisUtil.closeSession();
        }
        return depts;
}

3.3  WHERE語句

修改配置文件deptMapper.xml,添加

<!-- 動態Where條件 ,通常也須要與if結合使用,與純if比較,省略了where 1=1-->
    <select id="selectListUseWhere" parameterType="Dept"  resultMap="deptResultMap">
        select * from dept
        <where>
            <if test="deptId!=null">
                and dept_id=#{deptId}
            </if>
            <if test="deptName!=null">
                and dept_name=#{deptName}
            </if>
            <if test="deptAddress!=null">
                and dept_address=#{deptAddress}
            </if>
        </where>
</select>

3.4  choose(when,otherwise)語句

修改配置文件deptMapper.xml,添加

<!-- 動態choose條件 ,以下配置,能夠完成沒有選擇條件時,查找不出任何數據 -->
    <select id="selectListUseChoose" parameterType="Dept" resultMap="deptResultMap">
        select * from dept where 1=1
        <choose>
            <when test="deptId!=null">and dept_id=#{deptId}</when>
            <when test="deptName!=null">and dept_name=#{deptName}</when>
            <when test="deptAddress!=null">and dept_address=#{deptAddress}</when>
            <otherwise>and !1 = 1</otherwise>
        </choose>
</select>

3.5  SET語句

修改配置文件deptMapper.xml,添加

<!--動態set語句能夠用來更新數據 -->
    <update id="updateUseSet" parameterType="Dept">
        update dept
        <set>
            <if test="deptName!=null">dept_name=#{deptName},</if>
            <if test="deptAddress!=null">dept_address=#{deptAddress},</if>
        </set>
        where dept_id=#{deptId}
</update>

3.6  ForEach語句

修改配置文件deptMapper.xml,添加

< <!-- 定義根據多個部門ID查詢部門相關部門信息的SQL語句 ,resultMap的值是指集合裏元素的類型,parameterType不用指定 -->
<select id="selectListUseForeach" parameterType="Integer[]" resultMap="deptResultMap">
        select * from dept where dept_id in
        <!-- collection="array或list",array用來對應參數爲數組,list對應參數爲 集合 -->
        <foreach collection="array" item="deptId" open="(" separator="," close=")">
            #{deptId}
        </foreach>
</select>

3.7  include語句

修改配置文件deptMapper.xml,添加

<!-- 使用include語句動態插入表的字段及對應的值 -->
    <sql id="key">
        <!--suffixOverrides="," 能夠忽略最後「,」號 -->
        <trim suffixOverrides=",">

            <if test="deptName!=null">
                dept_name,
            </if>
            <if test="deptAddress!=null">
                dept_address,
            </if>
        </trim>
    </sql>
    <sql id="value">
        <trim suffixOverrides="," >
                <if test="deptName!=null">
                #{deptName},
            </if>
            <if test="deptAddress!=null">
                #{deptAddress},
            </if>
        </trim>
    </sql>
    
    <insert id="insertUseInclude" parameterType="Dept">
        insert into dept(
        <include refid="key" />
        ) values(
        <include refid="value"/>
        )
</insert>
相關文章
相關標籤/搜索