Framework---Mybatis

一芽突、重點(diǎn)知識(shí)

git 監(jiān)視的是文件內(nèi)容的修改

$ git checkout -- abc.txt : 其實(shí)是用版本庫(kù)里的版本替換工作區(qū)的版本施禾,此功能在刪除未提交時(shí)使用才有效果

分支和分支之間是平衡的,沒(méi)有關(guān)系

只有主分支和從分支同時(shí)進(jìn)行版本提升的時(shí)候才會(huì)出現(xiàn)版本沖突

在向遠(yuǎn)程提交代碼之前一定要pull 再push

當(dāng)版本高于沖突版本時(shí)就不會(huì)沖突了

再pull遠(yuǎn)端數(shù)據(jù)前一定要把本地的commit完

核心類又叫核心api

mybatis操作數(shù)據(jù)庫(kù)要手動(dòng)提交數(shù)據(jù)才行

查詢依賴的方式 https://mvnrepository.com/

當(dāng)接口中傳入的參數(shù)不是一個(gè)對(duì)象的時(shí)候杜秸,再xml文件中實(shí)現(xiàn)方法時(shí)控乾,傳入?yún)?shù)的類型因該就寫(xiě)接口中參數(shù)定義時(shí)的參數(shù)名

實(shí)現(xiàn)注冊(cè)功能的xml中只要有一個(gè)功能出錯(cuò)遂蛀,前面的也不能運(yùn)行

sqlsession要保證每次都獲取新的,不然會(huì)出現(xiàn)線程不安全問(wèn)題

內(nèi)置集合mybatis是認(rèn)識(shí)的鹃答,所以傳參時(shí)不需要指定

_parameter mybatis內(nèi)置參數(shù)乎澄,接口傳來(lái)的參數(shù)數(shù)據(jù)都存在里面

在處理向數(shù)據(jù)庫(kù)存儲(chǔ)數(shù)據(jù)時(shí) 枚舉類型處理器,后面千萬(wàn)不能加雙引號(hào)

在處理從數(shù)據(jù)庫(kù)讀取數(shù)據(jù)時(shí)

枚舉類型處理器测摔,后面一定要加加雙引號(hào)

兩次shift跳出類查詢器

maven中配置文件都要放在resources中

choose (when, otherwise)置济,只匹配一個(gè),如果給了多個(gè)參數(shù)锋八,誰(shuí)在上面他匹配哪一個(gè)

不是mybatis可以默認(rèn)識(shí)別的類型浙于,例如用形參名作為參數(shù),就要加@parm注解

再xml中 & 表示為 & amp;

mybatis中入?yún)⑷绻且粋€(gè)且是他自己定義過(guò)的類型挟纱,則不加也可以

一般不會(huì)開(kāi)啟懶加載

當(dāng)Mybayis中參數(shù)多于兩個(gè)時(shí)羞酗,一個(gè)都不要給

二、知識(shí)框架

第一章 mybatis簡(jiǎn)介

1.1 mybatis的歷史

1. mybatis在2010年前叫ibatis是apache內(nèi)部的一個(gè)項(xiàng)目紊服,名字來(lái)源于internet+ibatis 是一個(gè)基于Java的持久層框架
2. 2010年以后從apache內(nèi)部遷移到google code上檀轨,并且改名為mybatis
3. 2013年遷移到github上</pre>

1.2 mybatis是什么

1. 是一款優(yōu)秀的持久層框架
2. 支持定制化sql,存儲(chǔ)過(guò)程以及高級(jí)映射
3. 可以避免幾乎所有的JDBC代碼手動(dòng)設(shè)置參數(shù)以及獲取結(jié)果集
4. 可以使用簡(jiǎn)單的 XML 或注解來(lái)配置和映射原生信息
5. 用接口將Java 的 POJOs(Plain Old Java Objects,普通的 Java對(duì)象)映射成數(shù)據(jù)庫(kù)中的記錄</pre>

1.3 mybatis的優(yōu)勢(shì)

1. 相比于JDBC沒(méi)有侵入性可以達(dá)到很好的解耦效果
2. 相比于hibernate他有著高性能围苫,可以滿足當(dāng)下絕大多數(shù)移動(dòng)互聯(lián)網(wǎng)時(shí)代的需求
3. sql代碼分類放置在不同的sql map中易維護(hù)</pre>

1.4 mybatis的核心文件編寫(xiě)

1. POJO映射數(shù)據(jù)庫(kù)表的Java對(duì)象
2. data access objects(DAOS)映射器接口類裤园,用于操作數(shù)據(jù)庫(kù)
3. sql maps : SQL映射配置文件,用于注冊(cè)DAOs接口,使其接口有操作數(shù)據(jù)庫(kù)的能力
4. mybatis配置文件,初始化一些基本的配置信息,用于生成SqlSessionFactory</pre>


第二章 入門HelloWorld

  • 數(shù)據(jù)庫(kù)表創(chuàng)建

//創(chuàng)建數(shù)據(jù)庫(kù)
CREATE DATABASE mybatis DEFAULT CHARACTER SET UTF8;
//創(chuàng)建數(shù)據(jù)庫(kù)表
CREATE TABLE user(
user_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '主鍵',
user_name VARCHAR(100) NOT NULL COMMENT '用戶名',
create_time DATETIME DEFAULT NULL comment '創(chuàng)建時(shí)間'
)ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=UTF8 COMMENT="用戶表";</pre>

  • 入門HelloWorld代碼的編寫(xiě)

①創(chuàng)建項(xiàng)目,添加jar包
mybatis-3.4.6.jar
mysql-connector-java-5.1.7-bin.jar
②根據(jù)官網(wǎng)的步驟一步步進(jìn)行環(huán)境搭建.
③使用junit測(cè)試進(jìn)行接口的測(cè)試.</pre>

    • 步驟

第1步 創(chuàng)建映射數(shù)據(jù)庫(kù)表的實(shí)體類

/**

  • 映射數(shù)據(jù)庫(kù)表的接口類
  • @author hu shuang
  • @email hd1611756908@163.com
    */
    import java.util.Date;
    ?
    public class User {
    //用戶ID
    private Integer userId;
    //用戶名
    private String userName;
    //創(chuàng)建時(shí)間
    private Date createTime;
    ?
    public User() {
    }
    public User(Integer userId, String userName, Date createTime) {
    this.userId = userId;
    this.userName = userName;
    this.createTime = createTime;
    }
    }</pre>

第2步 創(chuàng)建操作數(shù)據(jù)庫(kù)表的接口類

/**

  • 操作數(shù)據(jù)庫(kù)表的接口
  • @author hu shuang
  • @email hd1611756908@163.com
    /
    public interface UserMapper {
    /
  • 添加用戶
    /
    void addUser(User user);
    /
  • 刪除用戶
    /
    void deleteUser(Integer userId);
    /
  • 更新用戶
    /
    void updateUser(User user);
    /
  • 通過(guò)用戶ID獲取用戶信息
    /
    User getUser(Integer userId);
    /
  • 獲取用戶列表
    */
    List<User> getUsers();

/*

  • 根據(jù)名字模糊查詢獲取用戶列表
    */
    List<User> getUsersLikeByUserName(@Param("userName") String userName);
    }</pre>

第3步 創(chuàng)建注冊(cè)操作數(shù)據(jù)庫(kù)接口類的映射文件

操作數(shù)據(jù)庫(kù)只能用SQL語(yǔ)句,但是mybatis提供了使用接口操作數(shù)據(jù)庫(kù),一般情況接口是沒(méi)有操作數(shù)據(jù)庫(kù)的能力的,但是 mybatis可以通過(guò)這個(gè)配置文件來(lái)注冊(cè)接口,讓接口有操作數(shù)據(jù)庫(kù)的能力</pre>

<?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="com.im.mapper.UserMapper">

<insert id="addUser" parameterType="com.im.entity.User" useGeneratedKeys="true" keyProperty="userId">
INSERT INTO user(user_name,create_time) VALUES(#{userName},#{createTime})
</insert>

<delete id="deleteUser" parameterType="Integer">
DELETE FROM user WHERE user_id=#{userId}
</delete>

<update id="updateUser" parameterType="com.im.entity.User">
UPDATE user SET user_name=#{userName},create_time=#{createTime} WHERE user_id=#{userId}
</update>

<select id="getUser" parameterType="Integer" resultType="com.im.entity.User">
SELECT user_id as userId,user_name as userName,create_time as createTime FROM user WHERE user_id=#{userId}
</select>

<select id="getUsers" resultType="com.im.entity.User">
SELECT user_id as userId,user_name as userName,create_time as createTime FROM user
</select>

<select id="getUsersLikeByUserName" resultType="com.sc.entity.User">
SELECT user_id as userId,user_name as userName,create_time as createTime FROM user WHERE user_name like CONCAT('%',#{userName},'%')
</select>
<select id="getUsersLikeByUserName" resultType="com.sc.entity.User">
SELECT user_id as userId,user_name as userName,create_time as createTime FROM user WHERE user_name like #{userName}
</select>

<select id="getUsersLikeByUserName" resultType="com.sc.entity.User">
<bind name="pattern" value="'%' + _parameter.userName + '%'" />
SELECT user_id as userId,user_name as userName,create_time as createTime FROM user WHERE user_name like #{pattern}
</select>
</mapper></pre>

第4步 創(chuàng)建mybatis核心配置文件 mybatis-config.xml,用于生成mybatis核心對(duì)象

<?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">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">

<property name="driver" value="com.mysql.jdbc.Driver"/>

<property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8"/>

<property name="username" value="root"/>

<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>

<mapper resource="com/im/mapper/UserMapper.xml"/>
</mappers>
</configuration></pre>

第5步 通過(guò)單元測(cè)試類調(diào)用接口測(cè)試(mybatis原生API版調(diào)用)

public class UserMapperTest1 {
?
/*

  • 添加用戶
    /
    @Test
    public void testAddUser() throws IOException {
    //加載外部屬性資源文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    //創(chuàng)建SqlSessionFactory
    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
    //創(chuàng)建SqlSession
    SqlSession session = sessionFactory.openSession();
    //創(chuàng)建statement
    String statement = "com.im.mapper.UserMapper.addUser";
    //構(gòu)建入?yún)?br> User user = new User();
    user.setUserName("Tom");
    user.setCreateTime(new Date());
    int row = session.insert(statement, user);
    System.out.println("row:"+row);
    //提交
    session.commit();
    //關(guān)閉會(huì)話
    session.close();
    }
    /
  • 刪除用戶
    /
    @Test
    public void testDeleteUser() throws IOException {
    //加載外部屬性資源文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    //創(chuàng)建SqlSessionFactory
    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
    //創(chuàng)建SqlSession
    SqlSession session = sessionFactory.openSession();
    //創(chuàng)建statement
    String statement = "com.im.mapper.UserMapper.deleteUser";
    //調(diào)用mybatis的刪除數(shù)據(jù)的API
    int row = session.delete(statement, 1);
    System.out.println("row:"+row);
    //提交
    session.commit();
    //關(guān)閉會(huì)話
    session.close();
    }
    /
  • 更新用戶
    /
    @Test
    public void testUpdateUser() throws IOException {
    //加載外部屬性資源文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    //創(chuàng)建SqlSessionFactory
    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
    //創(chuàng)建SqlSession
    SqlSession session = sessionFactory.openSession();
    //創(chuàng)建statement
    String statement = "com.im.mapper.UserMapper.updateUser";
    //調(diào)用mybatis的更新數(shù)據(jù)的API
    //構(gòu)建更新入?yún)?br> User user = new User(2, "polly", new Date());
    int row = session.update(statement, user);
    System.out.println("row:"+row);
    //提交
    session.commit();
    //關(guān)閉會(huì)話
    session.close();
    }
    /
  • 根據(jù)ID獲取用戶
    /
    @Test
    public void testGetUser() throws IOException {
    //加載外部屬性資源文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    //創(chuàng)建SqlSessionFactory
    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
    //創(chuàng)建SqlSession
    SqlSession session = sessionFactory.openSession();
    //創(chuàng)建statement
    String statement = "com.im.mapper.UserMapper.getUser";
    //調(diào)用mybatis的查詢單個(gè)數(shù)據(jù)的API
    User user = session.selectOne(statement, 2);
    System.out.println("user:"+user);
    //提交
    session.commit();
    //關(guān)閉會(huì)話
    session.close();
    }
    /
  • 獲取用戶列表
    */
    @Test
    public void testGetUsers() throws IOException {
    //加載外部屬性資源文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    //創(chuàng)建SqlSessionFactory
    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
    //創(chuàng)建SqlSession
    SqlSession session = sessionFactory.openSession();
    //創(chuàng)建statement
    String statement = "com.im.mapper.UserMapper.getUsers";
    //調(diào)用mybatis的查詢列表數(shù)據(jù)的API
    List<User> list = session.selectList(statement);
    System.out.println("users:"+list);
    //提交
    session.commit();
    //關(guān)閉會(huì)話
    session.close();
    }
    }</pre>

第6步 通過(guò)單元測(cè)試類調(diào)用接口測(cè)試(mybatis映射器版調(diào)用)

public class UserMapperTest2 {
/*

  • 添加用戶
    /
    @Test
    public void testAddUser() throws IOException {
    //加載外部屬性資源文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    //創(chuàng)建SqlSessionFactory
    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
    //創(chuàng)建SqlSession
    SqlSession session = sessionFactory.openSession();
    //獲取映射器類的對(duì)象實(shí)例
    UserMapper userMapper = session.getMapper(UserMapper.class);
    //構(gòu)建入?yún)?br> User user = new User();
    user.setUserName("張三");
    user.setCreateTime(new Date());
    //調(diào)用添加用戶方法
    userMapper.addUser(user);
    //提交
    session.commit();
    //關(guān)閉會(huì)話
    session.close();
    }
    /
  • 刪除用戶
    /
    @Test
    public void testDeleteUser() throws IOException {
    //加載外部屬性資源文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    //創(chuàng)建SqlSessionFactory
    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
    //創(chuàng)建SqlSession
    SqlSession session = sessionFactory.openSession();
    //獲取映射器類的對(duì)象實(shí)例
    UserMapper userMapper = session.getMapper(UserMapper.class);
    //調(diào)用刪除方法
    userMapper.deleteUser(2);
    //提交
    session.commit();
    //關(guān)閉會(huì)話
    session.close();
    }
    /
  • 更新用戶
    /
    @Test
    public void testUpdateUser() throws IOException {
    //加載外部屬性資源文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    //創(chuàng)建SqlSessionFactory
    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
    //創(chuàng)建SqlSession
    SqlSession session = sessionFactory.openSession();
    //獲取映射器類的對(duì)象實(shí)例
    UserMapper userMapper = session.getMapper(UserMapper.class);
    //構(gòu)建更新入?yún)?br> User user = new User(2, "polly", new Date());
    //調(diào)用更新方法
    userMapper.updateUser(user);
    //提交
    session.commit();
    //關(guān)閉會(huì)話
    session.close();
    }
    /
  • 根據(jù)ID獲取用戶
    /
    @Test
    public void testGetUser() throws IOException {
    //加載外部屬性資源文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    //創(chuàng)建SqlSessionFactory
    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
    //創(chuàng)建SqlSession
    SqlSession session = sessionFactory.openSession();
    //獲取映射器類的對(duì)象實(shí)例
    UserMapper userMapper = session.getMapper(UserMapper.class);
    //調(diào)用查詢方法
    User user = userMapper.getUser(3);
    System.out.println("user:"+user);
    //提交
    session.commit();
    //關(guān)閉會(huì)話
    session.close();
    }
    /
  • 獲取用戶列表
    */
    @Test
    public void testGetUsers() throws IOException {
    //加載外部屬性資源文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    //創(chuàng)建SqlSessionFactory
    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
    //創(chuàng)建SqlSession
    SqlSession session = sessionFactory.openSession();
    //獲取映射器類的對(duì)象實(shí)例
    UserMapper userMapper = session.getMapper(UserMapper.class);
    //調(diào)用查詢?nèi)糠椒?br> List<User> users = userMapper.getUsers();
    System.out.println("users:"+users);
    //提交
    session.commit();
    //關(guān)閉會(huì)話
    session.close();
    }
    }</pre>

第三章 mybatis常用屬性配置

  • properties:導(dǎo)入外部屬性資源文件剂府,解決數(shù)據(jù)庫(kù)配置信息寫(xiě)到Java代碼中的問(wèn)題

<properties resource="db.properties"></properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">

<property name="driver" value="{jdbc_driver}" /> <property name="url" value="{jdbc_url}" />

<property name="username" value="{user}" /> <property name="password" value="{password}" />
</dataSource>
</environment>
</environments></pre>

  • typeAliases: 解決別名的問(wèn)題

在mybatis-config.xml配置文件中配置別名
?

<typeAliases>




<package name="com.im.entity"/>
</typeAliases></pre>

??

image

</center>

  • setting: mybatis的一些常用配置

在mybatis-config.xml配置文件中配置一些mybatis的基本屬性
?
<settings>

<setting name="cacheEnabled" value="true"/>

<setting name="lazyLoadingEnabled" value="true"/>

<setting name="aggressiveLazyLoading" value="true"/>

<setting name="mapUnderscoreToCamelCase" value="false"/>
</settings>
?
?
?
?
mapUnderscoreToCamelCase:簡(jiǎn)單介紹一下此屬性的使用,其他的屬性會(huì)在后面一一介紹拧揽。
?
在日常Java開(kāi)發(fā)中我們的命名規(guī)則駝峰狀比如: aaaBbbCcc
而我們的數(shù)據(jù)庫(kù)命名規(guī)則為: AAA_BBB_CCC,因?yàn)槊?guī)則
的不同,在進(jìn)行Java POJO和數(shù)據(jù)庫(kù)表關(guān)系映射時(shí)淤袜,通過(guò)反射
就會(huì)出現(xiàn)名稱對(duì)應(yīng)不上出現(xiàn)屬性找不到數(shù)據(jù)為空的問(wèn)題,解決方式一般有兩種

  • ①通過(guò)SQL的設(shè)置別名
  • ②設(shè)置mapUnderscoreToCamelCase屬性為true

第一種方式我們上面已經(jīng)用過(guò)痒谴,接下來(lái)我們使用mybatis提供的配置方式解決這個(gè)問(wèn)題,但是一定要注意數(shù)據(jù)庫(kù)的命名和Java的命名,一定要遵循自己的命名規(guī)范
?</pre>

??

image

</center>

  • mappers: 映射文件的配置

在mybatis-config.xml配置文件中配置
?
<mappers>

<mapper resource="com/im/mapper/UserMapper1.xml" />
<mapper resource="com/im/mapper/UserMapper2.xml" />
<mapper resource="com/im/mapper/UserMapper3.xml" />
</mappers></pre>


第四章 映射枚舉類型

映射枚舉的時(shí)候比較特殊,mybatis官方給我們提供了將枚舉映射成字符串或者整數(shù)類型兩種方式.看下面的實(shí)現(xiàn)方式.</pre>

  • 表設(shè)計(jì)

數(shù)據(jù)庫(kù)表的SQL語(yǔ)句
?
CREATE TABLE student(
stu_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '主鍵',
stu_name VARCHAR(100) NOT NULL COMMENT '學(xué)生名',
gender1 INT NOT NULL COMMENT '性別整數(shù)類型',
gender2 VARCHAR(10) NOT NULL COMMENT '性別字符類型'
)ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=UTF8 COMMENT="學(xué)生表";</pre>

  • 映射數(shù)據(jù)庫(kù)表的實(shí)體類

/**

  • 性別的枚舉類

  • @author hu shuang

  • @email hd1611756908@163.com
    /
    public enum Gender {
    MAN("男"),
    WOMAN("女"),
    NEUTRAL("中性");
    private String sex;
    private Gender(String sex) {
    this.sex = sex;
    }
    public String getSex() {
    return sex;
    }
    public void setSex(String sex) {
    this.sex = sex;
    }
    }
    ?
    <------------------分隔線----------------------->
    ?
    /
    *

  • 映射數(shù)據(jù)庫(kù)student表的類

  • @author hu shuang

  • @email hd1611756908@163.com
    */
    public class Student {
    private Integer stuId;
    private String stuName;
    //性別映射數(shù)據(jù)庫(kù)整數(shù)類型
    private Gender gender1;
    //性別映射數(shù)據(jù)庫(kù)字符類型
    private Gender gender2;
    public Student() {
    }
    }</pre>

  • 操作學(xué)生表的映射器接口

/**

  • 操作學(xué)生表的映射器接口
  • @author hu shuang
  • @email hd1611756908@163.com
    /
    public interface StudentMapper {
    /
  • 添加一個(gè)學(xué)生
    /
    void addStudent(Student student);
    /
  • 更新一個(gè)學(xué)生
    /
    void updateStudent(Student student);
    /
  • 獲取學(xué)生列表
    */
    List<Student> getStudents();

}</pre>

  • 注冊(cè)接口的xml配置文件

注冊(cè)接口的xml配置文件
?
<mapper namespace="com.im.mapper.StudentMapper">

<insert id="addStudent" parameterType="student" useGeneratedKeys="true" keyProperty="stuId">
INSERT INTO student(stu_name,gender1,gender2) VALUES(#{stuName},

{gender1,typeHandler=org.apache.ibatis.type.EnumOrdinalTypeHandler},

{gender2,typeHandler=org.apache.ibatis.type.EnumTypeHandler})

</insert>

<resultMap type="student" id="studentMap">
<id property="stuId" column="stu_id"/>
<result property="stuName" column="stu_name"/>

<result property="gender1" column="gender1" typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler"/>

<result property="gender2" column="gender2" typeHandler="org.apache.ibatis.type.EnumTypeHandler"/>
</resultMap>
<select id="getStudents" resultMap="studentMap">
SELECT * FROM student
</select>


<update id="updateStudent" parameterType="student">
UPDATE student SET stu_name=#{stuName},gender1=#{gender1,typeHandler=org.apache.ibatis.type.EnumOrdinalTypeHandler},gender2=#{gender2,typeHandler=org.apache.ibatis.type.EnumTypeHandler} WHERE stu_id=#{stuId}
</update>
?
</mapper></pre>

  • 測(cè)試枚舉類型的增改查

/**

  • 測(cè)試枚舉類型的增刪改
  • @author hu shuang
  • @email hd1611756908@163.com
    /
    public class StudentMapperTest {
    /
  • 添加學(xué)生
    */
    @Test
    public void testAddStudent() throws IOException {
    //加載外部屬性資源文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    //創(chuàng)建SqlSessionFactory
    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
    //創(chuàng)建SqlSession
    SqlSession session = sessionFactory.openSession();

StudentMapper mapper = session.getMapper(StudentMapper.class);
Student student = new Student();
student.setStuName("韓梅梅");
student.setGender1(Gender.MAN);
student.setGender2(Gender.MAN);
mapper.addStudent(student);

//提交
session.commit();
//關(guān)閉會(huì)話
session.close();
}
/*

  • 獲取學(xué)生列表
    */
    @Test
    public void testGetStudents() throws IOException {
    //加載外部屬性資源文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    //創(chuàng)建SqlSessionFactory
    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
    //創(chuàng)建SqlSession
    SqlSession session = sessionFactory.openSession();

StudentMapper mapper = session.getMapper(StudentMapper.class);
List<Student> students = mapper.getStudents();
System.out.println(students);
//提交
session.commit();
//關(guān)閉會(huì)話
session.close();
}
?

/*

  • 更新學(xué)生信息
    */
    @Test
    public void testUpdateStudent() throws IOException {
    //加載外部屬性資源文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    //創(chuàng)建SqlSessionFactory
    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
    //創(chuàng)建SqlSession
    SqlSession session = sessionFactory.openSession();
    StudentMapper mapper = session.getMapper(StudentMapper.class);
    Student student = new Student();
    student.setStuId(1001);
    student.setStuName("polly");
    student.setGender1(Gender.WOMAN);
    student.setGender2(Gender.WOMAN);
    mapper.updateStudent(student);

//提交
session.commit();
//關(guān)閉會(huì)話
session.close();
}
}
?</pre>


第五章 SQL map(注解) 方式進(jìn)行數(shù)據(jù)庫(kù)操作

注解方式操作數(shù)據(jù)庫(kù):
?
1. 不需要注冊(cè)接口的xml配置文件
2. 直接將SQL寫(xiě)到操作數(shù)據(jù)庫(kù)的接口里的每一個(gè)方法上
3. 核心配置文件 mapper 直接配置類
<mappers>

<mapper class="com.im.mapper.UserMapper"/>
</mappers></pre>

  • 操作數(shù)據(jù)庫(kù)的接口

/**

  • 操作數(shù)據(jù)庫(kù)表的接口

  • @author hu shuang

  • @email hd1611756908@163.com
    /
    public interface UserMapper {
    /

  • 添加用戶
    /
    @Insert("INSERT INTO user(user_name,create_time) VALUES(#{userName},#{createTime})")
    public void addUser(User user);
    /

  • 刪除用戶
    /
    @Delete("DELETE FROM user WHERE user_id=#{userId}")
    void deleteUser(Integer userId);
    /

  • 更新用戶
    /
    @Update("UPDATE user SET user_name=#{userName},create_time=#{createTime} WHERE user_id=#{userId}")
    void updateUser(User user);
    /

  • 通過(guò)用戶ID獲取用戶信息
    /
    @Select("SELECT * FROM user WHERE user_id=#{userId}")
    User getUser(Integer userId);
    /

  • 獲取用戶列表
    */
    @Select("SELECT * FROM user")
    List<User> getUsers();
    }</pre>

  • 單元測(cè)試類

public class UserMapperTest {
?
@Test
public void testAddUser() throws IOException {
//加載外部屬性資源文件
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
//創(chuàng)建SqlSessionFactory
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
//創(chuàng)建SqlSession
SqlSession session = sessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
//構(gòu)建入?yún)?br> User user = new User();
user.setUserName("張三");
user.setCreateTime(new Date());
mapper.addUser(user);
//提交
session.commit();
//關(guān)閉會(huì)話
session.close();
}

@Test
public void testDeleteUser() throws IOException {
//加載外部屬性資源文件
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
//創(chuàng)建SqlSessionFactory
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
//創(chuàng)建SqlSession
SqlSession session = sessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
mapper.deleteUser(2);
//提交
session.commit();
//關(guān)閉會(huì)話
session.close();
}

@Test
public void testUpdateUser() throws IOException {
//加載外部屬性資源文件
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
//創(chuàng)建SqlSessionFactory
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
//創(chuàng)建SqlSession
SqlSession session = sessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
//構(gòu)建入?yún)?br> User user = new User();
user.setUserId(5);
user.setUserName("JIM");
user.setCreateTime(new Date());
mapper.updateUser(user);
//提交
session.commit();
//關(guān)閉會(huì)話
session.close();
}

@Test
public void testGetUsers() throws IOException {
//加載外部屬性資源文件
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
//創(chuàng)建SqlSessionFactory
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
//創(chuàng)建SqlSession
SqlSession session = sessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> users = mapper.getUsers();
System.out.println(users);
//提交
session.commit();
//關(guān)閉會(huì)話
session.close();
}
}</pre>


第六章 mybatis的日志功能

6.1 日志的介紹

mybatis內(nèi)置日志工廠提供日志功能铡羡,內(nèi)置日志工廠將日志交給以下其中一種工具做代理:
?
1. SLF4J
2. Apache Commons Logging
3. Log4j 2
4. Log4j
5. JDK logging
?
mybatis 內(nèi)置日志工廠基于運(yùn)行時(shí)自省機(jī)制選擇合適的日志工具积蔚。它會(huì)使用第一個(gè)查找得到的工具(按上文列舉的順序查找)。如果一個(gè)都未找到烦周,日志功能就會(huì)被禁用尽爆。
?</pre>

6.2 日志配置

不少應(yīng)用服務(wù)器(如 Tomcat 和 WebShpere)的類路徑中已經(jīng)包含 Commons Logging,所以在這種配置環(huán)境下的MyBatis會(huì)把它作為日志工具读慎,記住這點(diǎn)非常重要漱贱。這將意味著,在諸如 WebSphere 的環(huán)境中夭委,它提供了 Commons Logging的私有實(shí)現(xiàn)幅狮,你的Log4J配置將被忽略。MyBatis將你的Log4J配置忽略掉是相當(dāng)令人郁悶的(事實(shí)上株灸,正是因?yàn)樵谶@種配置環(huán)境下崇摄,MyBatis 才會(huì)選擇使用 Commons Logging而不是Log4J)。如果你的應(yīng)用部署在一個(gè)類路徑已經(jīng)包含 Commons Logging 的環(huán)境中慌烧,而你又想使用其它日志工具丐吓,你可以通過(guò)在 MyBatis 配置文件mybatis-config.xml里面添加一項(xiàng)setting 來(lái)選擇別的日志工具第焰。
?
?
<configuration>
<settings>
...
<setting name="logImpl" value="LOG4J"/>
...
</settings>
</configuration>
?
?
logImpl 可選的值有:SLF4J先嬉、LOG4J煌寇、LOG4J2、JDK_LOGGING淑翼、COMMONS_LOGGING、STDOUT_LOGGING品追、NO_LOGGING玄括,或者是實(shí)現(xiàn)了接口org.apache.ibatis.logging.Log的,且構(gòu)造方法是以字符串為參數(shù)的類的完全限定名肉瓦。
(譯者注:可以參考o(jì)rg.apache.ibatis.logging.slf4j.Slf4jImpl.java的實(shí)現(xiàn))</pre>

6.3 日志的使用

第1步: 添加jar包
?
log4j-1.2.17.jar
slf4j-api-1.7.25.jar
slf4j-log4j12-1.7.25.jar
?
第2步: 添加日志配置文件log4j.xml
?
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration
xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="STDOUT"
class="org.apache.log4j.ConsoleAppender">
<param name="Encoding" value="UTF-8" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" />
</layout>
</appender>
<logger name="java.sql">
<level value="debug" />
</logger>
<logger name="org.apache.ibatis">
<level value="debug" />
</logger>
<root>
<level value="debug" />
<appender-ref ref="STDOUT" />
</root>
</log4j:configuration></pre>


第七章 動(dòng)態(tài)SQL

7.1 動(dòng)態(tài)SQL簡(jiǎn)介

  • 動(dòng)態(tài)SQL優(yōu)勢(shì)

mybatis的強(qiáng)?特性之一就是動(dòng)態(tài)sql,有過(guò)根據(jù)不同條件拼接SQL經(jīng)歷的同學(xué)應(yīng)該知道當(dāng)條件多的時(shí)候拼接SQL是一件很痛苦的事情遭京,但是mybatis卻很好的幫我們解決了拼接SQL的煩惱</pre>

  • 動(dòng)態(tài)SQL所涉及到的標(biāo)簽

1. if
2. choose(when,otherwise)(類似于我們Java中的switch語(yǔ)句)
3. trim(where,set)
4. foreach(多用于批量操作)</pre>

7.2 動(dòng)態(tài)SQL使用

7.2.1 if語(yǔ)句(用于where子句之后作為條件判斷)

  • 使用常量(1=1)解決由于部分條件匹配而產(chǎn)生的多AND造成SQL語(yǔ)法錯(cuò)誤的問(wèn)題


<select id="getBooks" parameterType="book" resultType="book">
SELECT * FROM book WHERE 1=1
<if test="bookName!=null">AND book_name=#{bookName}</if>
<if test="author!=null and author.name!=null">AND author_name=#{author.name}</if>
<if test="price!=null">AND price=#{price}</if>
</select></pre>

??

image

</center>

  • 使用<where>標(biāo)簽解決由于部分條件匹配而產(chǎn)生的多AND造成SQL語(yǔ)法錯(cuò)誤的問(wèn)題


<select id="getBooks" parameterType="book" resultType="book">
SELECT * FROM book
<where>
<if test="bookName!=null">AND book_name=#{bookName}</if>
<if test="author!=null and author.name!=null">AND author_name=#{author.name}</if>
<if test="price!=null">AND price=#{price}</if>
</where>
</select></pre>

??

image

</center>

7.2.2 if語(yǔ)句(用于更新語(yǔ)句作為入?yún)⑴袛?

  • 解決在增量更新時(shí),因?yàn)椴皇撬凶侄味几?所以有些字段沒(méi)有賦值泞莉,造成的更新數(shù)據(jù)庫(kù)某些數(shù)據(jù)被置空的為題

<update id="updateBook" parameterType="book">
UPDATE book SET
<if test="bookNam!=null">book_name=#{bookName},</if>
<if test="author!=null and author.name!=null">author_name=#{author.name},</if>
<if test="price!=null">price=#{price}</if>
WHERE book_id=#{bookId}
</update></pre>

  • 注意事項(xiàng)

在更新時(shí)哪雕,由于有些字段不需要更新而造成的SQL語(yǔ)句多逗號(hào)(,)問(wèn)題</pre>

  • 解決方式(<set>標(biāo)簽)

<update id="updateBook" parameterType="book">
UPDATE book
<set>
<if test="bookNam!=null">book_name=#{bookName},</if>
<if test="author!=null and author.name!=null">author_name=#{author.name},</if>
<if test="price!=null">price=#{price}</if>
</set>
WHERE book_id=#{bookId}
</update></pre>

??

image

</center>

7.2.3 choose (when, otherwise)

用于匹配多個(gè)條件中的一個(gè)(不常用)
?
<select id="getBooks" parameterType="book" resultType="book">
SELECT * FROM book WHERE
<choose>
<when test="bookName!=null">book_name=#{bookName}</when>
<when test="author!=null and author.name!=null">author_name=#{author.name}</when>
<when test="price!=null">price=#{price}</when>
<otherwise>
book_id=#{bookId}
</otherwise>
</choose>
</select></pre>

7.2.4 foreach(多用于批量操作)

  • 批量操作Mapper層接口

/**

  • 操作數(shù)據(jù)庫(kù)表的接口
  • @author hu shuang
  • @email hd1611756908@163.com
    /
    public interface UserMapper {
    /
  • 批量添加
    */
    //void batchAddUser(List<User> users); //根據(jù)類型匹配
    void batchAddUser(@Param("users") List<User> users);//根據(jù)名稱匹配

/*

  • 批量查詢
    /
    void batchQueryUsers(List<Integer> ids);
    /
  • 批量刪除
    /
    void batchDeleteUsers(List<Integer> ids);
    /
  • 批量更新
    */
    void batchUpdateUsers(List<User> users);

}</pre>

  • 批量添加語(yǔ)法

    • 方式一

方式一:

separator:分隔符
<insert id="batchAddUser" parameterType="user">
INSERT INTO user(user_name,create_time) VALUES
<foreach collection="list" item="item" separator="," >
(#{item.userName},#{item.createTime})
</foreach>
</insert></pre>

    • 方式二


<insert id="batchAddUser" parameterType="user">
INSERT INTO user(user_name,create_time) VALUES
<foreach collection="users" item="item" separator="," >
(#{item.userName},#{item.createTime})
</foreach>
</insert></pre>

  • 批量查詢語(yǔ)法


<select id="batchQueryUsers" resultType="user">
SELECT * FROM user WHERE user_id IN
<foreach collection="list" item="item" open="(" close=")" separator=",">

{item}

</foreach>
</select></pre>

  • 批量刪除語(yǔ)法


<delete id="batchDeleteUsers">
DELETE FROM user WHERE user_id IN
<foreach collection="list" item="id" open="(" separator="," close=")">

{id}

</foreach>
</delete></pre>

  • 批量更新語(yǔ)法

    • 批量更新配置

使用mybatis進(jìn)行批量更新數(shù)據(jù)庫(kù)數(shù)據(jù)時(shí),需要在url地址后面加上allowMultiQueries參數(shù)等于true
例如: jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8&allowMultiQueries=true
注意:在properties文件中使用&號(hào);在xml配置文件中使用&連接參數(shù)</pre>

    • 語(yǔ)法格式


<update id="batchUpdateUsers" parameterType="user">
<foreach collection="list" item="item" open="" separator=";" close="">
UPDATE user
<set>
<if test="item.userName!=null">user_name=#{item.userName},</if>
<if test="item.createTime!=null">create_time=#{item.createTime}</if>
</set>
WHERE user_id=#{item.userId}
</foreach>
</update></pre>

  • 單元測(cè)試代碼

public class UserMapperTest {
/*

  • 批量添加
    */
    @Test
    public void testBatchAddUser() throws IOException {
    //加載外部屬性資源文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    //創(chuàng)建SqlSessionFactory
    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
    //創(chuàng)建SqlSession
    SqlSession session = sessionFactory.openSession();
    //獲取映射器類的對(duì)象實(shí)例
    UserMapper userMapper = session.getMapper(UserMapper.class);
    //構(gòu)建入?yún)?br> List<User> users = new ArrayList<>();
    User user1 = new User(null, "EEE", new Date());
    User user2 = new User(null, "FFF", new Date());
    User user3 = new User(null, "GGG", new Date());
    User user4 = new User(null, "HHH", new Date());

users.add(user1);
users.add(user2);
users.add(user3);
users.add(user4);

//調(diào)用添加用戶方法
userMapper.batchAddUser(users);
//提交
session.commit();
//關(guān)閉會(huì)話
session.close();
}

/*

  • 批量查詢
    */
    @Test
    public void testBatchQueryUsers() throws IOException {
    //加載外部屬性資源文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    //創(chuàng)建SqlSessionFactory
    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
    //創(chuàng)建SqlSession
    SqlSession session = sessionFactory.openSession();
    //獲取映射器類的對(duì)象實(shí)例
    UserMapper userMapper = session.getMapper(UserMapper.class);
    //構(gòu)建入?yún)?br> List<Integer> ids = new ArrayList<>();

ids.add(3);
ids.add(5);
ids.add(7);

//調(diào)用批量查詢用戶方法
List<User> users = userMapper.batchQueryUsers(ids);
System.out.println(users);
//提交
session.commit();
//關(guān)閉會(huì)話
session.close();
}

/*

  • 批量刪除
    */
    @Test
    public void testBatchDeleteUsers() throws IOException {
    //加載外部屬性資源文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    //創(chuàng)建SqlSessionFactory
    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
    //創(chuàng)建SqlSession
    SqlSession session = sessionFactory.openSession();
    //獲取映射器類的對(duì)象實(shí)例
    UserMapper userMapper = session.getMapper(UserMapper.class);
    //構(gòu)建入?yún)?br> List<Integer> ids = new ArrayList<>();

ids.add(3);
ids.add(5);
ids.add(7);

//調(diào)用批量刪除方法
userMapper.batchDeleteUsers(ids);
//提交
session.commit();
//關(guān)閉會(huì)話
session.close();
}
/*

  • 批量更新
    */
    @Test
    public void testBatchUpdateUsers() throws IOException {
    //加載外部屬性資源文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    //創(chuàng)建SqlSessionFactory
    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
    //創(chuàng)建SqlSession
    SqlSession session = sessionFactory.openSession();
    //獲取映射器類的對(duì)象實(shí)例
    UserMapper userMapper = session.getMapper(UserMapper.class);
    //構(gòu)建入?yún)?br> List<User> users = new ArrayList<>();

User user1 = new User(4,"MMM", new Date());
User user2 = new User(6,"VVV", new Date());
User user3 = new User(8,"WWW", new Date());

users.add(user1);
users.add(user2);
users.add(user3);

//調(diào)用批量更新方法
userMapper.batchUpdateUsers(users);
//提交
session.commit();
//關(guān)閉會(huì)話
session.close();
}
}</pre>


第八章 高級(jí)查詢

8.1 數(shù)據(jù)庫(kù)表創(chuàng)建(部門表/員工表)

CREATE TABLE department(
dept_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '主鍵',
dept_name VARCHAR(20) NOT NULL COMMENT '部門名稱'
)ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=UTF8 COMMENT="部門表";
?
CREATE TABLE employee(
emp_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '主鍵',
emp_name VARCHAR(20) NOT NULL COMMENT '員工名稱',
salary DOUBLE(10,2) DEFAULT 0.00 COMMENT '工資',
dept_id INT NOT NULL COMMENT '部門ID鲫趁,關(guān)聯(lián)部門表的主鍵'
)ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=UTF8 COMMENT="員工表";
?
//關(guān)聯(lián)
ALTER TABLE employee ADD FOREIGN KEY(dept_id) REFERENCES department(dept_id);
?
INSERT INTO department(dept_name) VALUES('行政部'),('人事部'),('IT部');
?
INSERT INTO employee(emp_name,salary,dept_id) VALUES('孫悟空',100.12,1000),('豬八戒',100.12,1001),('沙悟凈',100.12,1002);</pre>

8.2 創(chuàng)建映射數(shù)據(jù)庫(kù)表的實(shí)體類

/**

  • 映射數(shù)據(jù)庫(kù)部門表
  • @author hu shuang
  • @email hd1611756908@163.com
    */
    public class Department {
    private Integer deptId;
    private String deptName;
    // 一個(gè)部門下有多個(gè)員工(一對(duì)多關(guān)聯(lián))
    private List<Employee> employees;
    ?
    public Department() {
    }
    }</pre>

/**

  • 映射數(shù)據(jù)庫(kù)員工表
  • @author hu shuang
  • @email hd1611756908@163.com
    */
    public class Employee {
    ?
    private Integer empId;
    private String empName;
    private Double salary;
    // 一個(gè)員工對(duì)應(yīng)一個(gè)部門(一對(duì)一關(guān)聯(lián))
    private Department department;
    ?
    public Employee() {
    }
    }</pre>

8.3 創(chuàng)建操作數(shù)據(jù)庫(kù)的映射器接口

1. (一對(duì)一)查詢員工信息,將員工的部門信息同時(shí)查出(一個(gè)員工屬于一個(gè)部門)
2. (一對(duì)多)查詢部門信息,將此部門下的所有員工信息都查詢出來(lái)(一個(gè)部門下有多個(gè)員工)</pre>

public interface DepartmentMapper {
?
/*

  • 根據(jù)部門ID查詢部門詳情,不需要將當(dāng)前部門下的員工列表查出
    */
    Department getDepartmentByDeptId(Integer deptId);

/*

  • 根據(jù)部門ID查詢部門詳情,需要將當(dāng)前部門下的員工列表查詢出來(lái)(方式一 一對(duì)多關(guān)聯(lián)查詢 單條SQL)
    */
    Department getDepartmentByDeptId_(Integer deptId);

/*

  • 根據(jù)部門ID查詢部門詳情,需要將當(dāng)前部門下的員工列表查詢出來(lái)(方式二 一對(duì)多關(guān)聯(lián)查詢 多條SQL)
    */
    Department getDepartmentByDeptId$(Integer deptId);

}</pre>

public interface EmployeeMapper {
?
/*

  • 通過(guò)員工ID查詢員工信息,同時(shí)查詢出員工的部門信息( 方式一(單條SQL 關(guān)聯(lián)查詢) )
    */
    Employee getEmployeeByEmpId(Integer empId);

/*

  • 通過(guò)員工ID查詢員工信息,同時(shí)查詢出員工的部門信息( 方式二(多條SQL查詢) )
    */
    Employee getEmployeeByEmpId_(Integer empId);

/*

  • 通過(guò)部門ID查詢員工列表
    */
    List<Employee> getEmployeesByDeptId(Integer deptId);

}</pre>

8.4 創(chuàng)建注冊(cè)接口的XML配置文件

  • 一對(duì)一(方式一)單條SQL關(guān)聯(lián)查詢

EmployeeMapper.xml
?

<resultMap type="employee" id="employeeMap">

<id property="empId" column="emp_id"/>

<result property="empName" column="emp_name"/>
<result property="salary" column="salary"/>

<association property="department" javaType="department">
<id property="deptId" column="dept_id"/>
<result property="deptName" column="dept_name"/>
</association>
</resultMap>
<select id="getEmployeeByEmpId" parameterType="Integer" resultMap="employeeMap">
SELECT * FROM employee e,department d WHERE e.dept_id=d.dept_id AND e.emp_id=#{empId}
</select>
?</pre>

  • 一對(duì)一(方式二)多條SQL分別查詢

EmployeeMapper.xml
?

<resultMap type="employee" id="employeeMap_">
<id property="empId" column="emp_id"/>
<result property="empName" column="emp_name"/>
<result property="salary" column="salary"/>

<association property="department" javaType="department" column="dept_id" select="com.im.mapper.DepartmentMapper.getDepartmentByDeptId"/>
</resultMap>
<select id="getEmployeeByEmpId_" parameterType="Integer" resultMap="employeeMap_">
SELECT * FROM employee WHERE emp_id=#{empId}
</select></pre>

DepartmentMapper.xml
?
<select id="getDepartmentByDeptId" parameterType="Integer" resultType="department">
SELECT * FROM department WHERE dept_id=#{deptId}
</select></pre>

  • 一對(duì)多(方式一)單條SQL關(guān)聯(lián)查詢

DepartmentMapper.xml
?

<resultMap type="department" id="departmentMap_">
<id property="deptId" column="dept_id"/>
<result property="deptName" column="dept_name"/>

<collection property="employees" ofType="employee">
<id property="empId" column="emp_id"/>
<result property="empName" column="emp_name"/>
<result property="salary" column="salary"/>
</collection>
</resultMap>
<select id="getDepartmentByDeptId_" parameterType="Integer" resultMap="departmentMap_">
SELECT * FROM department d,employee e WHERE d.dept_id=e.dept_id AND d.dept_id=#{deptId}
</select></pre>

  • 一對(duì)多(方式二)多條SQL分別查詢

DepartmentMapper.xml
?

<resultMap type="department" id="departmentMap"> <id property="deptId" column="dept_id"/> <result property="deptName" column="dept_name"/> <collection property="employees" ofType="employee" column="dept_id" select="com.im.mapper.EmployeeMapper.getEmployeesByDeptId"/> </resultMap> <select id="getDepartmentByDeptId" parameterType="Integer" resultMap="departmentMap$">
SELECT * FROM department WHERE dept_id=#{deptId}
</select></pre>

EmployeeMapper.xml
?
<select id="getEmployeesByDeptId" parameterType="Integer" resultType="employee">
SELECT * FROM employee WHERE dept_id=#{deptId}
</select></pre>

8.5 單元測(cè)試類

  • EmployeeMapperTest.java

public class EmployeeMapperTest {
?
/*

  • 一對(duì)一 方式一(使用一條SQL語(yǔ)句關(guān)聯(lián)查詢)
    */
    @Test
    public void testGetEmployeeByEmpId() throws IOException {
    //加載外部屬性資源文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    //創(chuàng)建SqlSessionFactory
    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
    //創(chuàng)建SqlSession
    SqlSession session = sessionFactory.openSession();

EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
Employee employee = employeeMapper.getEmployeeByEmpId(1000);
System.out.println(employee);

//提交
session.commit();
//關(guān)閉會(huì)話
session.close();
}

/*

  • 一對(duì)一 方式二(多條SQL分別查詢)
    */
    @Test
    public void testGetEmployeeByEmpId_() throws IOException {
    //加載外部屬性資源文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    //創(chuàng)建SqlSessionFactory
    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
    //創(chuàng)建SqlSession
    SqlSession session = sessionFactory.openSession();

EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
Employee employee = employeeMapper.getEmployeeByEmpId_(1000);
System.out.println(employee);

//提交
session.commit();
//關(guān)閉會(huì)話
session.close();
}

}</pre>

  • DepartmentMapperTest.java

public class DepartmentMapperTest {
?
/*

  • 一對(duì)多 方式一(使用一條SQL語(yǔ)句關(guān)聯(lián)查詢)
    */
    @Test
    public void testGetDepartmentByDeptId_() throws IOException {
    //加載外部屬性資源文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    //創(chuàng)建SqlSessionFactory
    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
    //創(chuàng)建SqlSession
    SqlSession session = sessionFactory.openSession();

DepartmentMapper mapper = session.getMapper(DepartmentMapper.class);
Department department = mapper.getDepartmentByDeptId_(1000);
System.out.println(department);

//提交
session.commit();
//關(guān)閉會(huì)話
session.close();
}

/*

  • 一對(duì)多 方式二(多條SQL單獨(dú)查詢)
    */
    @Test
    public void testGetDepartmentByDeptId$() throws IOException {
    //加載外部屬性資源文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    //創(chuàng)建SqlSessionFactory
    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
    //創(chuàng)建SqlSession
    SqlSession session = sessionFactory.openSession();

DepartmentMapper mapper = session.getMapper(DepartmentMapper.class);
Department department = mapper.getDepartmentByDeptId$(1000);
System.out.println(department);

//提交
session.commit();
//關(guān)閉會(huì)話
session.close();
}
}</pre>

8.6 關(guān)聯(lián)查詢bug擴(kuò)展

由于帶有關(guān)聯(lián)關(guān)系的多個(gè)POJO之間因?yàn)閷傩悦嗤瑔?wèn)題而引起的映射數(shù)據(jù)出錯(cuò)的BUG處理以及解決方式</pre>

  • 創(chuàng)建數(shù)據(jù)庫(kù)表

CREATE TABLE tb_key(
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '主鍵',
name VARCHAR(20) NOT NULL COMMENT '鑰匙名稱',
lock_id INT NOT NULL COMMENT '鎖ID關(guān)聯(lián)鎖表的主鍵'
)ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=UTF8 COMMENT="鑰匙表";
?
CREATE TABLE tb_lock(
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '主鍵',
name VARCHAR(20) NOT NULL COMMENT '鎖名稱'
)ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=UTF8 COMMENT="鎖表";
//關(guān)聯(lián)
ALTER TABLE tb_key ADD FOREIGN KEY(lock_id) REFERENCES tb_lock(id);
?
INSERT INTO tb_key(name,lock_id) VALUES("鐵牛鑰匙",1000);
INSERT INTO tb_lock(name) VALUES('鐵牛鎖');</pre>

  • 創(chuàng)建映射數(shù)據(jù)庫(kù)表的實(shí)體類

/*

  • 鎖類
    */
    public class TbLock {
    ?
    private Integer id;
    private String name;
    ?
    public TbLock() {
    }
    }</pre>

/*

  • 鑰匙類
    */
    public class TbKey {
    ?
    private Integer id;
    private String name;
    //一把鑰匙只能開(kāi)一把鎖 一對(duì)一關(guān)聯(lián)
    private TbLock tbLock;
    ?
    public TbKey() {
    }
    }</pre>

  • 創(chuàng)建操作數(shù)據(jù)庫(kù)表的映射器接口

public interface TbKeyMapper {
/*

  • 通過(guò)鑰匙ID鑰匙信息以及鎖的信息
    */
    TbKey getKeyInfo(Integer keyId);
    }</pre>

  • 創(chuàng)建注冊(cè)操作數(shù)據(jù)庫(kù)表接口的xml配置文件

<mapper namespace="com.im.mapper.TbKeyMapper">
<resultMap type="tbKey" id="tbKeyMap">
<id property="id" column="id"/>
<result property="name" column="name"/>
<association property="tbLock" javaType="tbLock">
<id property="id" column="id"/>
<result property="name" column="name"/>
</association>
</resultMap>
<select id="getKeyInfo" parameterType="Integer" resultMap="tbKeyMap">
SELECT * FROM tb_key tk,tb_lock tl WHERE tk.lock_id=tl.id AND tk.id=#{keyId}
</select>
?
</mapper></pre>

  • 編寫(xiě)測(cè)試類

@Test
public void testGetKeyInfo() throws IOException {
//加載外部屬性資源文件
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
//創(chuàng)建SqlSessionFactory
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
//創(chuàng)建SqlSession
SqlSession session = sessionFactory.openSession();

TbKeyMapper keyMapper = session.getMapper(TbKeyMapper.class);
TbKey keyInfo = keyMapper.getKeyInfo(1000);
System.out.println(keyInfo);

//提交
session.commit();
//關(guān)閉會(huì)話
session.close();
}</pre>

  • 結(jié)果分析
    得出的結(jié)果,會(huì)發(fā)現(xiàn)映射出錯(cuò),鑰匙和鎖信息都是相同的
    ?
    TbKey [id=1000, name=鐵牛鑰匙, tbLock=TbLock [id=1000, name=鐵牛鑰匙]]
    ?
    造成以上問(wèn)題的原因是因?yàn)門bKey和TbLock兩個(gè)JavaBean類中的屬性名字相同造成的,由此可以看出 association 標(biāo)簽映射Java對(duì)象時(shí)采用的是通過(guò)名稱映射的,在兩個(gè)JavaBean屬性名字相同時(shí)斯嚎,在映射時(shí)候就會(huì)出現(xiàn)映射不清的問(wèn)題。</pre>

  • 解決方案: 采用多SQL聯(lián)查的方式

<resultMap type="tbKey" id="tbKeyMap">
<id property="id" column="id"/>
<result property="name" column="name"/>
<association property="tbLock" javaType="tbLock" column="lock_id" select="com.im.mapper.TbLockMapper.getLockInfo"/>
</resultMap>
<select id="getKeyInfo" parameterType="Integer" resultMap="tbKeyMap">
SELECT * FROM tb_key WHERE id=#{keyId}
</select></pre>


第九章 mybatis的懶加載

9.1 什么是懶加載

懶加載又稱延時(shí)加載,就是在我們獲取數(shù)據(jù)時(shí)堡僻,有些數(shù)據(jù)是不需要實(shí)時(shí)獲取的糠惫,當(dāng)需要時(shí)在獲取,這樣的加載數(shù)據(jù)的方式被稱為懶加載</pre>

9.2 懶加載的使用

  • 添加jar包如果是maven依賴,可以不加

cglib-2.2.2.jar
asm-3.3.1.jar</pre>

  • 在mybatis全局配置文件中開(kāi)啟懶加載

關(guān)閉及時(shí)加載 aggressiveLazyLoading
開(kāi)啟懶加載 lazyLoadingEnabled</pre>

<settings>

<setting name="mapUnderscoreToCamelCase" value="true"/>

<setting name="lazyLoadingEnabled" value="true"/>

<setting name="aggressiveLazyLoading" value="false"/>
</settings></pre>

  • 特定關(guān)聯(lián)關(guān)系中可通過(guò)設(shè)置fetchType屬性來(lái)覆蓋該項(xiàng)的開(kāi)關(guān)狀態(tài)

1. 特定關(guān)聯(lián)關(guān)系是指使用關(guān)聯(lián)映射標(biāo)簽
<collection>或者<association>中的select
屬性钉疫,而不是使用多表聯(lián)查的方式.
2. 可以通過(guò)<collection>或者<association>的fetchType屬性設(shè)置成lazy</pre>


第十章 mybatis的緩存

10.1 緩存的優(yōu)缺點(diǎn)

優(yōu)點(diǎn): 減少讀數(shù)據(jù)庫(kù)的讀操作,降低數(shù)據(jù)庫(kù)壓力,加快響應(yīng)速度
缺點(diǎn):可能造成數(shù)據(jù)不一致問(wèn)題,增加成本</pre>

10.2 mybatis的一級(jí)緩存

  • 一級(jí)緩存特點(diǎn)

1. 一級(jí)緩存默認(rèn)是開(kāi)啟的
2. 一級(jí)緩存默認(rèn)是SqlSession級(jí)別的</pre>

  • 驗(yàn)證一級(jí)緩存

1. 在一個(gè)SqlSession下根據(jù)相同條件多次查詢,發(fā)現(xiàn)日志只打印一條SQL,說(shuō)明有緩存存在
2. 在多個(gè)SqlSession下,根據(jù)相同條件查詢,打印多條SQL說(shuō)明一級(jí)緩存是SqlSession級(jí)別的,創(chuàng)新創(chuàng)建SqlSession對(duì)象之后緩存失效</pre>

  • 一級(jí)緩存失效方式

1. 使用sqlSession.clearCache()刷新緩存
2. 關(guān)閉SqlSession之后重新打開(kāi)
3. SqlSession執(zhí)行增刪改之后會(huì)清空緩存</pre>

10.3 mybatis的二級(jí)緩存

  • 二級(jí)緩存特點(diǎn)

1. 二級(jí)緩存需要手動(dòng)配置
2. 二級(jí)緩存是SqlSessionFactory級(jí)別的</pre>

  • 二級(jí)緩存的使用
    ①在myabtis-config.xml全局的開(kāi)啟二級(jí)緩存
    <settings>

    <setting name="cacheEnabled" value="true"/>
    </settings>
    ?
    ②SQL map映射文件中添加<cache/>
    <cache/>標(biāo)簽中屬性的介紹:
    <cache
    eviction="FIFO"
    flushInterval="60000"
    size="512"
    readOnly="true"/>

eviction: 緩存的回收策略
—>LRU – 最近最少使用的:移除最長(zhǎng)時(shí)間不被使用的對(duì)象
—>FIFO – 先進(jìn)先出: 按對(duì)象進(jìn)入緩存的順序來(lái)移除它們
—>SOFT – 軟引用: 移除基于垃圾回收器狀態(tài)和軟引用規(guī)則的對(duì)象
—>WEAK – 弱引用: 更積極地移除基于垃圾收集器狀態(tài)和弱引用規(guī)則的對(duì)象
?
flushInterval: 刷新間隔,默認(rèn)不刷新硼讽,可以設(shè)置任意的正整數(shù),毫秒數(shù)
?
size: 引用數(shù)目->可以被設(shè)置為任意正整數(shù),要記住你緩存的對(duì)象數(shù)目和你運(yùn)行環(huán)境的可用內(nèi)存資源數(shù)目,默認(rèn)值是1024。
?
readOnly: 是否只讀默認(rèn)是false->只讀的緩存會(huì)給所有調(diào)用者返回緩存對(duì)象的相同實(shí)例牲阁。因此這些對(duì)象不能被修改固阁。這提供了很重要的性能優(yōu)勢(shì)〕蔷眨可讀寫(xiě)的緩存會(huì)返回緩存對(duì)象的拷貝(映射數(shù)據(jù)庫(kù)的實(shí)體類必須實(shí)現(xiàn)序列化) 您炉。這會(huì)慢一些,但是安全,因此默認(rèn)是 false</pre>

  • 二級(jí)緩存設(shè)置成功的標(biāo)志

日志中會(huì)出現(xiàn)緩存命中率,并且在每一次查詢結(jié)束之后都要提交事務(wù),否則二級(jí)緩存不會(huì)起作用,緩存命中率不會(huì)發(fā)生變化.
?
Cache Hit Ratio [com.im.mapper.UserMapper]: 0.0</pre>

10.4 集成第三方緩存ehcache

使用二級(jí)緩存產(chǎn)品ehcache步驟</pre>

  • 添加jar包或者依賴

ehcache-2.10.4.jar
mybatis-ehcache-1.0.0.jar</pre>

  • 添加ehcache產(chǎn)品配置文件ehcache.xml

  • 配置Ehcache

在SQL map 文件中配置<cache/>標(biāo)簽
?
<cache type="org.mybatis.caches.ehcache.EhcacheCache">

<property name="timeToIdleSeconds" value="3600"/>

<property name="timeToLiveSeconds" value="3600"/>

<property name="maxEntriesLocalHeap" value="1000"/>

<property name="maxEntriesLocalDisk" value="1000000"/>

<property name="memoryStoreEvictionPolicy" value="LRU"/>
</cache></pre>

第十一章 MYSQL分頁(yè)

11.1 分頁(yè)準(zhǔn)備

  • 操作數(shù)據(jù)庫(kù)的接口代碼

/**

  • 操作數(shù)據(jù)庫(kù)表的接口
    /
    public interface UserMapper {
    /

  • 原生SQL分頁(yè)

  • @Param:方法入?yún)槎鄠€(gè)時(shí)要使用此注解指定入?yún)?否則mybatis表達(dá)式(#{xxx})會(huì)找不到方法入?yún)?br> /
    List<User> getUserPage(@Param("offset")int offset,@Param("pageSize")int pageSize);
    /

  • 分頁(yè)插件分頁(yè)
    */
    List<User> getUserPage_();
    }</pre>

  • 注冊(cè)接口的xml配置文件

<?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="com.im.mapper.UserMapper">

<select id="getUserPage" resultType="user">
SELECT * FROM user LIMIT #{offset},#{pageSize}
</select>

<select id="getUserPage_" resultType="user">
SELECT * FROM user
</select>
</mapper></pre>

11.2 原生分頁(yè)

/*

  • 原生分頁(yè)
    */
    @Test
    public void testGetUserPage() throws IOException {
    //加載外部屬性資源文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    //創(chuàng)建SqlSessionFactory
    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
    //創(chuàng)建SqlSession
    SqlSession session = sessionFactory.openSession();

UserMapper mapper = session.getMapper(UserMapper.class);
int pageNo=3;//當(dāng)前頁(yè)
int pageSize=2;//每頁(yè)顯示的條數(shù)
//mysql分頁(yè)的第一個(gè)參數(shù),轉(zhuǎn)換公式
int offset=(pageNo-1)*pageSize;
List<User> page = mapper.getUserPage(offset, pageSize);
System.out.println(page);
//提交
session.commit();
//關(guān)閉會(huì)話
session.close();
}</pre>

11.3 分頁(yè)插件(PageHelper)

  • 添加jar包或者依賴

jsqlparser-0.9.5.jar
pagehelper-5.1.2.jar</pre>

  • 在mybatis-config.xml中配置PageHelper


<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">

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

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

<property name="params" value="pageNum=pageNumKey;pageSize=pageSizeKey;"/>
</plugin>
</plugins></pre>

  • Junit單元測(cè)試

/*

  • pageHelper分頁(yè)
    */
    @Test
    public void testGetUserPage_() throws IOException {
    //加載外部屬性資源文件
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    //創(chuàng)建SqlSessionFactory
    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
    //創(chuàng)建SqlSession
    SqlSession session = sessionFactory.openSession();
    UserMapper mapper = session.getMapper(UserMapper.class);
    //在查詢?nèi)繑?shù)據(jù)之前直接調(diào)用PageHelper.startPage(2, 2);方法進(jìn)行分頁(yè)
    //注意不能再兩個(gè)方法之間插入其他的代碼方法入?yún)榈谝粋€(gè):pageNo役电;第二個(gè):pageSize
    PageHelper.startPage(2, 2);
    List<User> page_ = mapper.getUserPage_();
    for (User user : page_) {
    System.out.println(user);
    }

//提交
session.commit();
//關(guān)閉會(huì)話
session.close();
}</pre>


第十二章 mybatis和spring框架的整合

spring + mybatis 框架整合
整合步驟:</pre>

  • 創(chuàng)建Java普通項(xiàng)目(因?yàn)闆](méi)有頁(yè)面所以不需要web項(xiàng)目)

  • 添加jar包目或者maven依賴

commons-logging-1.2.jar
druid-1.1.6.jar
jsqlparser-0.9.5.jar
log4j-1.2.17.jar
mybatis-3.4.6.jar
mybatis-spring-1.3.1.jar
mysql-connector-java-5.1.7-bin.jar
pagehelper-5.1.2.jar
slf4j-api-1.7.25.jar
slf4j-log4j12-1.7.25.jar
spring-aop-4.3.10.RELEASE.jar
spring-aspects-4.3.10.RELEASE.jar
spring-beans-4.3.10.RELEASE.jar
spring-context-4.3.10.RELEASE.jar
spring-context-support-4.3.10.RELEASE.jar
spring-core-4.3.10.RELEASE.jar
spring-expression-4.3.10.RELEASE.jar
spring-jdbc-4.3.10.RELEASE.jar
spring-orm-4.3.10.RELEASE.jar
spring-oxm-4.3.10.RELEASE.jar
spring-test-4.3.10.RELEASE.jar
spring-tx-4.3.10.RELEASE.jar</pre>

  • 創(chuàng)建jdbc.properties配置文件

jdbc_user=root
jdbc_password=root
jdbc_url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8</pre>

  • 創(chuàng)建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>
<settings>

<setting name="cacheEnabled" value="true"/>

<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">

<property name="reasonable" value="true"/>
</plugin>
</plugins>
</configuration></pre>

  • 創(chuàng)建applicationContext.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
?

<context:property-placeholder location="classpath:jdbc.properties" />

<context:component-scan base-package="com.sc" />

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">

<property name="url" value="{jdbc_url}" /> <property name="username" value="{jdbc_user}" />
<property name="password" value="${jdbc_password}" />

<property name="initialSize" value="1" />
<property name="minIdle" value="1" />
<property name="maxActive" value="20" />

<property name="maxWait" value="60000" />

<property name="timeBetweenEvictionRunsMillis" value="60000" />

<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="validationQuery" value="SELECT 'x'" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />

<property name="poolPreparedStatements" value="false" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="20" />

<property name="filters" value="stat" />
</bean>

<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="typeAliasesPackage" value="com.sc.entity" />
<property name="configLocation" value="classpath:mybatis-config.xml" />
</bean>

<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>

<tx:annotation-driven transaction-manager="transactionManager" />

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
<property name="basePackage" value="com.sc.mapper" />
<property name="annotationClass" value="org.springframework.stereotype.Repository" />
</bean>
</beans></pre>

  • 添加log4j.xml配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration
xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="STDOUT"
class="org.apache.log4j.ConsoleAppender">
<param name="Encoding" value="UTF-8" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" />
</layout>
</appender>
<logger name="java.sql">
<level value="debug" />
</logger>
<logger name="org.apache.ibatis">
<level value="debug" />
</logger>
<root>
<level value="debug" />
<appender-ref ref="STDOUT" />
</root>
</log4j:configuration></pre>


第十三章 spring框架的單元測(cè)試

spring和mybatis框架整合完成之后赚爵,需要測(cè)試整合是否成功,接下來(lái)需要進(jìn)行測(cè)試,測(cè)試采用spring框架的spring-tx-4.3.10.RELEASE.jar 依賴進(jìn)行單元測(cè)試.</pre>

  • 使用mybatis上面的例子進(jìn)行測(cè)試

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations= {"classpath:applicationContext.xml"})
public class UserMapperTest {
?
@Autowired
private UserMapper userMapper;

@Test
public void test01() {
List<User> users = userMapper.getUsers();
System.out.println(users);
}
}</pre>


第十四章 mybatis映射MYSQL5.7新增的JSON數(shù)據(jù)類型

14.1 mybatis 5.7 json數(shù)據(jù)類型介紹

MYSQL5.7的GA版本開(kāi)始支持json格式的數(shù)據(jù)
json格式有兩種一種單個(gè)對(duì)象{};另一種就是集合格式[]</pre>

14.2 Java對(duì)象和json數(shù)據(jù)的互通

看看mybatis是怎么實(shí)現(xiàn)將Java的對(duì)象保存到數(shù)據(jù)庫(kù)中的json數(shù)據(jù)格式,又怎么將數(shù)據(jù)庫(kù)中的json數(shù)據(jù)格式查詢出來(lái)保存成Java對(duì)象</pre>

  • 創(chuàng)建數(shù)據(jù)庫(kù)表

CREATE TABLE tb_order(
order_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
users json NOT NULL,
user json NOT NULL
)ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=UTF8;</pre>

  • 創(chuàng)建映射數(shù)據(jù)庫(kù)表的Java實(shí)體類

//測(cè)試數(shù)據(jù)庫(kù)兩種數(shù)據(jù)類型
public class Order {
?
private Integer orderId;
//[{"id":1001,"name":"李雷"},{"id":1001,"name":"李雷"}]
private List<User> users;
//{"id":1001,"name":"李雷"}
private User user;

}
?
public class User {
// 用戶ID
private Integer userId;
// 用戶名
private String userName;

}</pre>

  • 創(chuàng)建自定義類型轉(zhuǎn)換器進(jìn)行JSON和POJO的轉(zhuǎn)換

    • 集合類型處理器(處理集合數(shù)據(jù)) JsonArrayTypeHandler.java

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
?
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
?
import com.alibaba.fastjson.JSON;
import com.im.entity.User;
/*

  • 數(shù)組類型的相互轉(zhuǎn)換

  • JSON轉(zhuǎn)換使用的是阿里巴巴的fastjson
    /
    public class JsonArrayTypeHandler extends BaseTypeHandler<List<User>> {
    ?
    /

  • 使用列名獲取數(shù)據(jù)庫(kù)中保存的json數(shù)據(jù)

  • 并將其數(shù)據(jù)類型轉(zhuǎn)換成List集合
    /
    @Override
    public List<User> getNullableResult(ResultSet arg0, String arg1) throws SQLException {
    String string = arg0.getString(arg1);
    return JSON.parseObject(string, List.class);
    }
    /
    *

  • 使用索引獲取數(shù)據(jù)庫(kù)中保存的json數(shù)據(jù)

  • 并將其數(shù)據(jù)類型轉(zhuǎn)換成List集合
    /
    @Override
    public List<User> getNullableResult(ResultSet arg0, int arg1) throws SQLException {
    String string = arg0.getString(arg1);
    return JSON.parseObject(string, List.class);
    }
    ?
    /
    *

  • 使用索引獲取數(shù)據(jù)庫(kù)中保存的json數(shù)據(jù)

  • 并將其數(shù)據(jù)類型轉(zhuǎn)換成List集合
    /
    @Override
    public List<User> getNullableResult(CallableStatement arg0, int arg1) throws SQLException {
    String string = arg0.getString(arg1);
    return JSON.parseObject(string,List.class);
    }
    ?
    /
    *

  • 將集合的實(shí)體對(duì)象轉(zhuǎn)換成JSON保存到數(shù)據(jù)庫(kù)中
    */
    @Override
    public void setNonNullParameter(PreparedStatement arg0, int arg1, List<User> arg2, JdbcType arg3)
    throws SQLException {
    arg0.setString(arg1, JSON.toJSONString(arg2));
    }
    }</pre>

    • 單個(gè)對(duì)象處理器(處理單個(gè)對(duì)象) JsonTypeHandler.java

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
?
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
?
import com.alibaba.fastjson.JSON;
import com.im.entity.User;
/**

  • 自定義類型處理器

  • @author hushuang

  • json轉(zhuǎn)換使用阿里巴巴的fastjson
    */
    public class JsonTypeHandler extends BaseTypeHandler<User> {
    ?
    @Override
    public User getNullableResult(ResultSet arg0, String arg1) throws SQLException {
    return JSON.parseObject(arg0.getString(arg1), User.class);
    }
    ?
    @Override
    public User getNullableResult(ResultSet arg0, int arg1) throws SQLException {
    return JSON.parseObject(arg0.getString(arg1), User.class);
    }
    ?
    @Override
    public User getNullableResult(CallableStatement arg0, int arg1) throws SQLException {
    return JSON.parseObject(arg0.getString(arg1), User.class);
    }
    ?
    @Override
    public void setNonNullParameter(PreparedStatement arg0, int arg1, User arg2, JdbcType arg3) throws SQLException {
    arg0.setString(arg1, JSON.toJSONString(arg2));
    }
    ?
    }</pre>

    • 注冊(cè)自定義類型轉(zhuǎn)換器

在mybatis-config.xml配置文件中注冊(cè)
?
<typeHandlers>
<typeHandler handler="com.im.handler.JsonTypeHandler" />
<typeHandler handler="com.im.handler.JsonArrayTypeHandler" />
</typeHandlers></pre>

  • 創(chuàng)建注解操作接口的xml配置文件

<?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="com.im.mapper.OrderMapper">

<insert id="addOrder" parameterType="order">
INSERT INTO tb_order(users,user)
VALUES(#{users,typeHandler=com.im.handler.JsonArrayTypeHandler},#{user,typeHandler=com.im.handler.JsonTypeHandler})
</insert>

<resultMap type="order" id="orderMap">
<id property="orderId" column="order_id"/>
<result property="users" column="users" typeHandler="com.im.handler.JsonArrayTypeHandler"/>
<result property="user" column="user" typeHandler="com.im.handler.JsonTypeHandler"/>
</resultMap>
<select id="getOrder" resultMap="orderMap">
SELECT * FROM tb_order WHERE order_id=#{id}
</select>
</mapper></pre>


第十五章 相關(guān)文檔

mybatis中文官網(wǎng)地址:https://mybatis.org/mybatis-3/zh/index.html
Druid中文官網(wǎng)地址:https://github.com/alibaba/druid/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98
pageHelper官網(wǎng)地址:https://pagehelper.github.io/docs/howtouse/
ehcache 官網(wǎng)地址:http://mybatis.org/ehcache-cache/</pre>

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市法瑟,隨后出現(xiàn)的幾起案子冀膝,更是在濱河造成了極大的恐慌,老刑警劉巖霎挟,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窝剖,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡酥夭,警方通過(guò)查閱死者的電腦和手機(jī)赐纱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)熬北,“玉大人疙描,你說(shuō)我怎么就攤上這事⊙纫” “怎么了起胰?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)巫延。 經(jīng)常有香客問(wèn)我效五,道長(zhǎng),這世上最難降的妖魔是什么炉峰? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任畏妖,我火速辦了婚禮,結(jié)果婚禮上疼阔,老公的妹妹穿的比我還像新娘戒劫。我一直安慰自己半夷,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布谱仪。 她就那樣靜靜地躺著玻熙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪疯攒。 梳的紋絲不亂的頭發(fā)上嗦随,一...
    開(kāi)封第一講書(shū)人閱讀 49,166評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音敬尺,去河邊找鬼枚尼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛砂吞,可吹牛的內(nèi)容都是我干的署恍。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼蜻直,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼盯质!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起概而,我...
    開(kāi)封第一講書(shū)人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤呼巷,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后赎瑰,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體王悍,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年餐曼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了压储。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡源譬,死狀恐怖集惋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情瓶佳,我是刑警寧澤芋膘,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站霸饲,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏臂拓。R本人自食惡果不足惜厚脉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望胶惰。 院中可真熱鬧傻工,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至泄伪,卻和暖如春殴蓬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蟋滴。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工染厅, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人津函。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓肖粮,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親尔苦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子涩馆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344