2. MyBatis - 深度學習 - 基本使用

前言

本文整理一下MyBatis的基本使用,這裏非工作中使用的場景,主要爲了分析源碼而做準備

預備數據庫

如果你使用docker的話,推薦看看我的文章把 [Docker 實戰系列 - MySQL環境](…/…/Docker/實戰系列/Docker 實戰系列 - MySQL環境.md)

創建數據庫

# 創建庫
create database mybatis_demo;

創建表

CREATE TABLE `student` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `cls_id` int(10) NOT NULL COMMENT '班級ID',
  `name` varchar(32) NOT NULL COMMENT '名字',
  `age` int(3) NOT NULL COMMENT '年齡',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE `cls` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL COMMENT '班級名稱',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

插入測試數據

INSERT INTO `student`(`id`, `cls_id`, `name`, `age`, `create_time`) VALUES (1, 1, '張三', 13, now());
INSERT INTO `student`(`id`, `cls_id`, `name`, `age`, `create_time`) VALUES (2, 2, '李四', 14, now());
INSERT INTO `cls`(`id`, `name`, `create_time`) VALUES (1, '初一1班', now());
INSERT INTO `cls`(`id`, `name`, `create_time`) VALUES (2, '初一2班', now());

創建項目

在上文中已經創建好了mybatis的源碼環境,現在我們開始創建自己的項目

在這裏插入圖片描述
設置自己的包名,我爲了以後複習所以用了 chapter1

在這裏插入圖片描述

準備工作

配置properties文件

vim application.properties
jdbc.driver=com.mysql.jdbc.Driver
default.environment=dev

全局配置

vim mybatis-config.xml

屬性配置優先級

  • build方式
  • 外部的 properties 文件
  • xml配置的properties
<?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>
    <!-- 這裏只是演示,正常你使用 app.properties 配置即可 -->
    <properties resource="application.properties">
        <property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
    </properties>
    <!-- 如果需要遠程加載的話可以使用url 只能選一種-->
    <!-- <properties url=""> -->

    <environments default="${default.environment}">
        <!-- 測試環境 -->
        <environment id="dev">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="jdbc:mysql://localhost/mybatis_demo"/>
                <property name="username" value="root"/>
                <property name="password" value="a123456"/>
            </dataSource>
        </environment>
        <!-- 生產環境 -->
        <environment id="pro">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="jdbc:mysql://192.168.160.130/mybatis_online"/>
                <property name="username" value="root"/>
                <property name="password" value="Aa123456"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
  		...
    </mappers>
</configuration>

定義 Student 並使用 lombok [Lombok 的使用](…/…/Java/編程技巧/Lombok 的使用.md)

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
    private Integer id;
    private Integer clsId;
    private String name;
    private Date createTime;
}

現在項目結構

├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── xm
    │   │           └── chapter1
    │   │               ├── MainTest.java
    │   │               ├── Student.java
    │   │               └── StudentMapper.xml
    │   └── resources
    │       ├── application.properties
    │       └── mybatis-config.xml
    └── test
        └── java

XML方式

自定義Mapper.xml

vim StudentMapper.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.xm.chapter1.StudentMapper">
    <select id="selectStudentXml" resultType="com.xm.chapter1.Student" >
        select * from student where id = #{id}
     </select>
</mapper>

修改全局配置的mapper,並引入我們的文件

vim mybatis-config.xml
<configuration>
  ...
    <mappers>
        <mapper resource="com/xm/chapter1/StudentMapper.xml"/>
    </mappers>
</configuration>

運行

public class MainTest {
    private SqlSession session;

    @Before
    public void init() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        session = sqlSessionFactory.openSession(true);
    }

    @Test
    public void test1() throws IOException {
        // 通過xml查詢
        Student result = session.selectOne(
          "com.xm.chapter1.StudentMapper.selectStudentXml", 1);
        System.out.println(result.toString());
    }
}

對於結果的轉移,不知道你有沒有發現兩個字段(createTime,clsId)爲空,我們來修改一下

<?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.xm.chapter1.StudentMapper">

    <resultMap id="StudentMap" type="com.xm.chapter1.Student">
        <id property="id" column="id"/>
        <result property="clsId" column="cls_id"/>
        <result property="createTime" column="create_time"/>
    </resultMap>

    <select id="selectStudentXml" resultMap="StudentMap" >
        select * from student where id = #{id}
     </select>

</mapper>

接口方式

爲了避免混淆,可以先把上面的xml刪除,或者不刪除屏蔽掉下面的即可

修改全局配置,引入接口方式

<configuration>
    ...
    <mappers>
        <mapper class="com.xm.chapter1.StudentMapper"/>
    </mappers>
</configuration>

創建mapper接口

public interface StudentMapper {
    @Select("select * from student where id = #{id}")
    Student selectInterface(Integer id);
}

運行

public class MainTest {
		....
    @Test
    public void test2(){
        StudentMapper mapper = session.getMapper(StudentMapper.class);
        Student student = mapper.selectInterface(1);
        System.out.println(student);
    }
}

對於結果的轉移,不知道你有沒有發現兩個字段(createTime,clsId)爲空,我們來修改一下

public interface StudentMapper {

  @Select("select id,name,cls_id as clsId,create_time as createTime from student where id = #{id}")
  Student selectInterface(Integer id);
}

類型處理器

持久層框架其中比較重要的工作就是處理數據的映射轉換,把java 類型轉換成jdbc 類型的參數,又需要把jdbc 類型的結果集轉換成java 類型。

public interface TypeHandler<T> {
  void setParameter(
    PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;
  T getResult(ResultSet rs, String columnName) throws SQLException;
  T getResult(ResultSet rs, int columnIndex) throws SQLException;
  T getResult(CallableStatement cs, int columnIndex) throws SQLException;
}

我們將上面的student的事件類型,修改爲long試下

...
  public class Student {
    private Integer id;
    private String name;
    private Integer clsId;
    // 改這裏
    private Long createTime;
}

運行後發現結果不符合我們預期

Student(id=1, name=張三, clsId=1, createTime=2019)

自定義TypeHandler解決這個問題

public class LongTimeHandler extends BaseTypeHandler<Long> {
  @Override
  public void setNonNullParameter(
    PreparedStatement ps, int i, Long parameter, JdbcType jdbcType) throws SQLException {
    ps.setDate(i, new Date(parameter));
  }

  @Override
  public Long getNullableResult(ResultSet rs, String columnName) throws SQLException {
    return rs.getDate(columnName).getTime();
  }

  @Override
  public Long getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
    return rs.getDate(columnIndex).getTime();
  }

  @Override
  public Long getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
    return cs.getDate(columnIndex).getTime();
  }
}

全局配置的方式 - 任選一

<configuration>
  <typeHandlers>
    <typeHandler handler="com.xm.chapter1.LongTimeHandler"
                 javaType="long" jdbcType="TIMESTAMP" />
  </typeHandlers>
</configuration>
// 如果嫌棄上面寫 javaType、jdbcType 麻煩,可以使用註解
@MappedJdbcTypes(JdbcType.TIMESTAMP)
@MappedTypes(Long.class)
public class LongTimeHandler extends BaseTypeHandler<Long> {
	....
}

針對單個返回值 - 任選一

<mapper namespace="com.xm.chapter1.StudentMapper">
  <resultMap id="StudentMap" type="com.xm.chapter1.Student">
     ...
      <result property="createTime" 
              column="create_time" typeHandler="com.xm.chapter1.LongTimeHandler"/>
  </resultMap>
	....
</mapper>

返回結果

Student(id=1, name=張三, clsId=1, createTime=1562342400000)

日誌

創建文件

vim resources/log4j.properties

log4j.properties

### 設置日誌級別 ###
log4j.rootLogger = debug,stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern =  %d{ABSOLUTE} %5p %c:%L - %m%n
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章