淺談MyBatis

一、Mybatis簡介

MyBatis 是一款優秀的持久層框架,它支持自定義 SQL、存儲過程以及高級映射。MyBatis 免除了幾乎所有的 JDBC 代碼以及設置參數和獲取結果集的工作。MyBatis 可以通過簡單的 XML 或註解來配置和映射原始類型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 對象)爲數據庫中的記錄。

1.1 引入依賴(pom.xml)

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.1</version>
            <type>pom</type>
        </dependency>

1.2 全局配置文件(mybatis-config.xml)

<configuration>
    <properties>
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/activity?characterEncoding=utf8"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </properties>
    <!-- 環境,可以配置多個,default:指定採用哪個環境 -->
    <environments default="test">
        <!-- id:唯一標識 -->
        <environment id="test"/>
        <environment id="prot"/>
    </environments>
    <mappers>
        <mapper resource="mapper/map.xml" />
    </mappers>
</configuration>

1.3 配置map.xml(map.xml)

<!-- mapper:根標籤,namespace:命名空間,隨便寫,一般保證命名空間唯一 -->
<mapper namespace="mapper">
    <!-- statement,內容:sql語句。id:唯一標識,隨便寫,在同一個命名空間下保持唯一
       resultType:sql語句查詢結果集的封裝類型需全路徑,person即爲數據庫中的表-->
    <select id="selectUserById" resultType="...User">
            select * from person where id= #{id}
    </select>
    <select id="selectUserByName" resultType="...User">
        select * from person where name= #{name}
    </select>
</mapper>

1.4.修改全局配置文件(mybatis-config.xml)

<configuration>
    <!-- 添加加載map.xml配置文件 -->
    <mappers>
        <mapper resource="mapper/map.xml" />
    </mappers>
</configuration>

1.5 構建sqlSessionFactory 

Mybatis中3個重要的概念:Configuration(容器),SqlSessionFactory(工廠),SqlSession;

相對於Spring中的applicationContext,BeanFactory,Bean。不同之處在於SqlSession包含了所有的SQL方法,即這個SqlSession有且只有一個。SqlSession可以執行mybatis中註冊的所有方法。

        // 指定全局配置文件
        String resource = "mybatis-config.xml";
        // 讀取配置文件
        InputStream inputStream = Resources.getResourceAsStream(resource);
        // 構建sqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

1.6 打開sqlSession會話,並執行sql

        // 獲取sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //<!-- SqlSession 完全包含了面向數據庫執行 SQL 命令所需的所有方法。
        //你可以通過 SqlSession 實例來直接執行已映射的 SQL 語句。例如:-->
        try {
            // 操作CRUD,第一個參數:指定statement,規則:命名空間+“.”+statementId
            // 第二個參數:指定傳入sql的參數:這裏是用戶id
            User user = sqlSession.selectOne("mapper.selectUserByName", "name");
            System.out.println(user);
        } finally {
            sqlSession.close();
        }

 1.7構建UserMapper 

public interface UserMapper {
    User selectUserById(Long id);
    User selectUserByName(String name);
    int  updateUser(User user);
}

<!-- 這裏namespace必須是UserMapper接口的路徑,不然要運行的時候要報錯 “is not known to the MapperRegistry”-->
<mapper namespace="...UserMapper">
    <!-- statement,內容:sql語句。id:唯一標識,隨便寫,在同一個命名空間下保持唯一
       resultType:sql語句查詢結果集的封裝類型需全路徑,person即爲數據庫中的表-->
    <select id="selectUserById" resultType="...User" parameterType="java.lang.Long">
            select * from person where id= #{id}
    </select>
    <select id="selectUserByName" resultType="...User" parameterType="java.lang.String">
        select * from person where name= #{name}
    </select>
    <!--更新用戶信息-->
    <update id="updateUser" parameterType="...User">
        UPDATE person
        <set>
            <if test="name != null and name != ''">name=#{name},</if>
            <if test="sex >= 0">sex=#{sex},</if>
            <if test="age >= 0">sex=#{age},</if>
            <if test="height >= 0">height=#{height},</if>
            <if test="weight >= 0">weight=#{weight},</if>
        </set>
        WHERE id=#{id}
    </update>
</mapper>
          
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user= mapper.selectUserByName("name");
System.out.println(user);

2.1使用註解注入

接口必須添加@Mapper註解,注意,使用#符號和$符號的不同:

使用#{}意味着使用的預編譯的語句,即在使用jdbc時的preparedStatement,sql語句中如果存在參數則會使用?作佔位符,我們知道這種方式可以防止sql注入,並且在使用#{}時形成的sql語句,已經帶有引號,例,select  * from table1 where id=#{id}  在調用這個語句時我們可以通過後臺看到打印出的sql爲:select * from table1 where id='2' 加入傳的值爲2.也就是說在組成sql語句的時候把參數默認爲字符串。

使用${}時的sql不會當做字符串處理,是什麼就是什麼,如上邊的語句:select * from table1 where id=${id} 在調用這個語句時控制檯打印的爲:select * from table1 where id=2 ,假設傳的參數值爲2

從上邊的介紹可以看出這兩種方式的區別,我們最好是能用#{}則用它,因爲它可以防止sql注入,且是預編譯的,在需要原樣輸出時才使用${},如,select * from ${tableName} order by ${id} 這裏需要傳入表名和按照哪個列進行排序 ,加入傳入table1、id 則語句爲:select * from table1 order by id如果是使用#{} 則變成了select * from 'table1' order by 'id' 我們知道這樣就不對了。

@Mapper
public interface PersonMapper {

    @Select("Select * from person where name = #{name}")
    User selectTeachForGivenName(@Param("name") String name);

    @Select("Select * from person where name = '${name}'")
    User selectTeachLikeName(@Param("name") String name);

    @Select("select * from person")
    List<User> queryUser();

    @Select("SELECT * FROM users WHERE id = #{id}")
    User selectUserById(Long id);

    @Select("select * from person")
    User selectUserByName(@Param("name") String name);

}

 2.2執行測試

@RunWith(SpringRunner.class)
@SpringBootTest
public class MybatisTest {

    @Autowired
    PersonMapper personMapper;
    @Test
    public void testMybatis(){
        List<User> users = personMapper.queryUser();
        System.out.println(users);
    }
}

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章