ssm系列之MyBatis(一)

MyBatis簡介

1、MyBatis可以簡化JDBC操作,實現數據的持久化

2、MyBatis是ORM產品,是ORM的一個實現。對象關係映射(Object Relational Mapping,簡稱ORM)是通過使用描述對象和數據庫之間映射的元數據,將面嚮對象語言程序中的對象自動持久化到關係數據庫中。可以使操作數據庫表變得和操作對象一樣。
映射關係:對象與表名映射,對象的屬性與表的屬性映射
映射後每增加一個對象,被映射的表就會多一條數據

配置MyBatis

1、下載並導入jar包,mybatis.jar和數據庫驅動jar包, mybatis.jar下載地址.
2、MyBatis是普通的Java項目,項目創建後首先要創建mapper.xml(在文件裏把對象和表一一映射):增刪改查標籤,需要複製官方文檔中的 2.15的代碼

<?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=“”中放入映射文件的路徑******
namespace:該mapper.xml映射文件的唯一標識-->
<mapper namespace="org.mybatis.example.BlogMapper">
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
</select>
</mapper>

3、創建表和類
4、創建configure.xml配置文件,在裏面添加數據庫的信息和需要加載的映射文件,需要複製官方文檔中的 2.12的代碼

<?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值和environment的id 來指定MyBatis運行時的數據庫環境-->
    <environments default="development">

        <!-- 開發環境(如自己的計算機) -->
        <environment id="development">

            <!-- 事務提交方式:
             JDBC:利用JDBC方式處理事務(commit rollback close)
             MANAGED:將事務交由其他組件去託管(spring,jobss),用完後會默認關閉連接,需要自己配置纔不會關閉,代碼如下:
             <transactionManager type="MANAGED"/>
                <property name="closeConnection" value="false"/>
             -->
            <transactionManager type="JDBC"/>   <!-- 用什麼方式處理事務 -->

            <!-- 數據源類型:
             UNPOOLED:傳統的JDBC模式,每次訪問數據庫,都需要進行打開和關閉等數據庫操作,比較消耗性能
             POOLED:使用數據庫連接池,有多個連接就能處理多個請求,用完後只需還回來,省略了數據庫的打開和關閉,提高效率
             JNDI:從tomcat中獲取一個內置的數據庫連接池()
             -->
            <dataSource type="POOLED">
                <!-- 配置數據庫信息 -->
                <property name="driver" value="oracle.jdbc.OracleDriver"/>     <!-- value裏放數據庫的驅動 -->
                <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:ORCL"/>       <!-- 訪問數據庫的鏈接字符串 -->
                <property name="username" value="scott"/>
                <property name="password" value="tiger"/>
            </dataSource>
        </environment>

        <!-- 真正的項目應該在發佈的那臺計算機上運行(實施計算機) -->
        <environment id="implement">
          <!-- .........-->.
        </environment>

    </environments>
    <mappers>
        <!-- 加載映射文件 -->
        <mapper resource="chern/cn/studentMapper"/>
    </mappers>
</configuration>

基礎方式的增刪改查

1、輸入參數:如果是簡單類型(8個基本類型+String),則可以使用任意佔位符,即可在#{}裏寫任意名稱,代碼如下

<!--parameterType:輸入參數類型    resultType:返回值類型
    且mybatis規定parameterType輸入參數和resultType輸出參數在形式上只能有一個
    如果是對象類型,則必須是對象的屬性 #{屬性名},代碼如下
    -->
    
	<!---->
<insert id="addStudent" parameterType="chern.cn.Student">
        insert into student(stuno,stuname,stuage,graname) values(#{stuNo},#{stuName},#{stuAge},#{graName})
    </insert>
    
	<!---->
    <delete id="deleteStudentByStuno"   parameterType="int">
        delete from student where stuno = #{stuno}
    </delete>
    
    <!---->
    <update id="updateStudentByStuno" parameterType="chern.cn.Student">
        update student set stuname=#{stuName}, stuage=#{stuAge},graname=#{graName} where stuno=#{stuNo}
    </update>
    
    <!---->
<select id="queryPersonByStuno" resultType="chern.cn.Student" parameterType="int">
    select * from student where stuno = #{stuno}

2、輸出參數:如果返回值類型是一個對象(如Student),則無論返回一個、還是多個,在resultType都寫成chern.cn.Student

3、如果使用的事務方式爲JDBC,則需要手工commit提交,即session.commit();

4、所有的標籤等,都必須有sql語句,但是sql參數值可選,
如:select * from student where stuno = #{xxx}中select * from student代表第一個參數,where stuno = #{xxx}代表第二個參數,代碼如下

//java執行查詢代碼
		//加載MyBatis配置文件(爲了訪問數據庫)
        //Connection - SqlSession操作MyBatis
        //conf.xml -> reader
		Reader reader = Resources.getResourceAsReader("conf");
        //SqlSessionFactory - connection
        //reader -> SqlSession
        //通過SqlSessionFactoryBuilder().build()的第二個參數可以指定MyBatis運行時的數據庫環境
        //如SqlSessionFactoryBuilder().build(reader,"development")
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
        //session - connection
        SqlSession session = sessionFactory.openSession();
        //session.selectOne("需要查詢的SQL的namespace.id,"SQL的參數值")
        String statement = "chern.cn.studentMapper.queryPersonByStuno";
        Student student = session.selectOne(statement,1);
        System.out.println(student);
        session.close();

<!-- 對應映射文件的代碼 -->
<mapper namespace="chern.cn.studentMapper">
    <select id="queryPersonByStuno" resultType="chern.cn.Student" parameterType="int">
    select * from student where stuno = #{stuno}
    </select>

mapper動態代理方式的增刪改查(MyBatis接口開發)

1、原則:約定優於配置,配置優於硬編碼
2、各種方式
以配置項目的名字爲例
硬編碼方式:
abc.java

		Configuration conf = new Configuration();
		conf.setName("myProject");

配置方式:
abc.xml

		<name>myProject</name>	

約定:默認值設置爲myProject

3、實現步驟
1)、基礎環境:mybatis.jar、ojdbc.jar、conf.xml、mapper.xml
2)、約定的目標:省略掉statement,即根據約定直接定位出sql語句
a、接口,接口中的方法必須遵循以下規則

1、方法名和mapper.xml文件中標籤的id值相同
2、方法的輸入參數和mapper.xml文件中標籤的parameterType類型一致(如果mapper.xml的標籤中沒有parameterType,則說明方法沒有輸入參數)
3、方法的返回值和mapper.xml文件中標籤的resultType類型一致(如果沒有返回值,則說明方法的返回值爲void)

除了以上約定,要實現 接口中的方法 和 mapper.xml中sql標籤一一對應,還需要:把namespace的值設置爲接口的全類名(接口 – mapper.xml 一一對應)

約定的過程
1、根據 接口名 找到 mapper.xml文件(根據的是namespace=接口全類名)
2、根據 接口的方法名 找到 mapper.xml文件中的sql標籤(方法名=sql標籤Id值)

以上2點可以保證:當我們調用接口中的方法時,程序能自動定位到 某一個mapper.xml文件中的sql標籤

習慣:一般我們把sql映射文件(mapper.xml) 和 接口放在同一個包中

可以通過接口的方法->sql語句

主要代碼:

//主要是定義好StudentMapper接口後,在裏面創建相應的方法。

//mapper.xml的代碼
<mapper namespace="chern.mapper.StudentMapper">
<select id="queryPersonByStuno" resultType="student" parameterType="int">
    select * from student where stuno = #{stuno}
 </select>

//StudentMapper.java的代碼
Student queryPersonByStuno(int stuno);

//main方法裏的代碼
Reader reader = Resources.getResourceAsReader("conf");
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = sessionFactory.openSession();
        StudentMapper sessionMapper = session.getMapper(StudentMapper.class);
        Student student = sessionMapper.queryPersonByStuno(1);//接口中的方法->sql語句
        System.out.println(student);
        session.close();

在main方法中通過session對象獲取接口(session.getMapper(接口.class)),再調用該接口中的方法,程序會自動執行該方法對應的sql

優化

1、改配置信息
可以將配置信息 以key–value對的形式 單獨放入db.properties文件(文件放在根目錄裏)中,然後再動態引入(在conf.xml的configuration標籤下添加<properties resource="文件路徑"/>
如:

//db.properties代碼
driver=oracle.jdbc.OracleDriver
url=jdbc:oracle:thin:@127.0.0.1:1521:ORCL
username=scott
password=tiger

//conf.xml代碼
<!-- 該標籤放在<configuration>標籤下 -->
<properties resource="db.properties"/>

	<!-- 配置數據庫信息 -->
	<property name="driver" value="${driver}"/>
	<property name="url" value="${url}"/>
	<property name="username" value="${username}"/>
	<property name="password" value="${password}"/>


2、全局參數(在conf文件中設置)
代碼如下:

<settings>
        //<setting name="需要設置的參數" value="開啓或關閉"/>如
        <setting name="cacheEnabled" value="false"/>
    </settings>

3、別名(在conf中配置)
a、設置單個別名
b、批量設置別名
代碼如下:

<typeAliases>
        <!--單個別名(別名忽略大小寫)
        <typeAlias type="chern.cn.Student" alias="student"/>
        -->
        <!--批量定義別名(別名忽略大小寫),會自動將該包中的所有類批量定義別名:別名就是類名(不帶包名的類名)-->
        <package name="chern.cn"/>
    </typeAliases>

除了自定義別名外,MyBatis還內置了一些常見類的別名,在這裏就不一一列舉了。

類型處理器(類型轉換器)

1、MyBatis自帶一些常見的類型處理器,如 int - number
2、自定義MyBatis類型處理器:java - 數據庫(jdbc類型)
實例:
實體類Student: boolean stuSex
true:男
false:女
表student: number stuSex
1:男
0:女
自定義類型轉換器(boolean - number)步驟:
a、創建轉換器:實現TypeHandler接口(此接口有一個實現類BaseTypeHandler,所以也可以繼承該實現類),主要代碼

//BooleanAndIntConverter.java代碼

public class BooleanAndIntConverter extends BaseTypeHandler<Boolean> {
    //set:java -> 數據庫(DB)
    //get:數據庫(DB)-> java
    /**
     * preparedStatement:PreparedStatement對象
     * i:PreparedStatement對象操作參數的位置
     * aBoolean:java值
     * jdbcType:jdbc操作的數據庫類型
     */
    //java(boolean) -> DB(number)
    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, Boolean aBoolean, JdbcType jdbcType) throws SQLException {
        if(aBoolean){
            preparedStatement.setInt(i,1);
        }
        else{
            preparedStatement.setInt(i,0);
        }
    }
    //DB(number) -> java(boolean)
    @Override
    public Boolean getNullableResult(ResultSet resultSet, String s) throws SQLException {
        int sexnum = resultSet.getInt(s);
        return sexnum == 1?true:false;
    }

    @Override
    public Boolean getNullableResult(ResultSet resultSet, int i) throws SQLException {
        int sexnum = resultSet.getInt(i);
        return sexnum == 1?true:false;
    }

    @Override
    //CallableStatement:存儲過程
    public Boolean getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        int sexnum = callableStatement.getInt(i);
        return sexnum == 1?true:false;
    }
}

b、配置conf.xml

<typeHandlers>
        <typeHandler handler="chern.converter.BooleanAndIntConverter" javaType="Boolean" jdbcType="INTEGER"/>
    </typeHandlers>

在做好以上配置後,我們還需要在studentMapper.xml進行進一步的配置。
如果類中屬性 和 表中的字段 類型能夠合理識別(String-varchar2),則可以使用resultType;否則使用resultMap(boolean-number)。
如果類中屬性名 和 表中的字段名 能夠合理識別(stuNo -stuno),則可以使用resultType;否則使用resultMap(id-stuno)。主要代碼如下:

<select id="queryStudentByStunoWithConverter" resultMap="studentResult" parameterType="int">
    select * from student where stuno = #{stuno}
    </select>
    <resultMap id="studentResult" type="student">
        <!--分爲主鍵(使用<id/>標籤) 和 非主鍵使用<result/>標籤)-->
        <id property="stuNo" column="stuno"/>
        <result property="stuName" column="stuname"/>
        <result property="stuAge" column="stuage"/>
        <result property="graName" column="graname"/>
        <result property="stuSex" column="stusex" javaType="boolean" jdbcType="INTEGER"/>
    </resultMap>
發佈了8 篇原創文章 · 獲贊 3 · 訪問量 421
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章