1:使用maven導(dǎo)入mybatis的依賴
1.0:使用idea創(chuàng)建一個(gè)maven項(xiàng)目
1.1:一個(gè)maven的空項(xiàng)目娘汞,目錄大概這樣
1.2:在pom.xml中導(dǎo)入mybatis的依賴姻氨,大概需要以下依賴
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<!--slf4j-api提供日志的api標(biāo)準(zhǔn),不能直接打印-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.29</version>
</dependency>
<!--log4j-over-slf4j 提供 slf4j 與 log4j 直接的鏈接-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
<scope>test</scope>
</dependency>
<!--log4j 日志-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!--測試依賴-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
2:開始配置mybatis
2.0:創(chuàng)建測試數(shù)據(jù)庫表
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`student_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '編號(hào)',
`name` VARCHAR(20) DEFAULT NULL COMMENT '姓名',
`phone` VARCHAR(20) DEFAULT NULL COMMENT '電話',
`email` VARCHAR(50) DEFAULT NULL COMMENT '郵箱',
`sex` TINYINT(4) DEFAULT NULL COMMENT '性別',
`locked` TINYINT(4) DEFAULT NULL COMMENT '狀態(tài)(0:正常,1:鎖定)',
`gmt_created` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '存入數(shù)據(jù)庫的時(shí)間',
`gmt_modified` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改的時(shí)間',
PRIMARY KEY (`student_id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='學(xué)生表';
這是根據(jù)上面的表穆壕,創(chuàng)建的實(shí)體類StudentModel,也可以采用mybatis逆向生成的方式生成其屏,后面會(huì)講到
package mybatis.entity;
import java.io.Serializable;
import java.util.Date;
public class StudentModel implements Serializable {
/**
* 編號(hào)
*/
private Integer student_id;
/**
* 姓名
*/
private String name;
/**
* 電話
*/
private String phone;
/**
* 郵箱
*/
private String email;
/**
* 性別
*/
private Byte sex;
/**
* 狀態(tài)(0:正常,1:鎖定)
*/
private Byte locked;
/**
* 存入數(shù)據(jù)庫的時(shí)間
*/
private Date gmt_created;
/**
* 修改的時(shí)間
*/
private Date gmt_modified;
private static final long serialVersionUID = 1L;
public Integer getStudent_id() {
return student_id;
}
public void setStudent_id(Integer student_id) {
this.student_id = student_id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name == null ? null : name.trim();
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone == null ? null : phone.trim();
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email == null ? null : email.trim();
}
public Byte getSex() {
return sex;
}
public void setSex(Byte sex) {
this.sex = sex;
}
public Byte getLocked() {
return locked;
}
public void setLocked(Byte locked) {
this.locked = locked;
}
public Date getGmt_created() {
return gmt_created;
}
public void setGmt_created(Date gmt_created) {
this.gmt_created = gmt_created;
}
public Date getGmt_modified() {
return gmt_modified;
}
public void setGmt_modified(Date gmt_modified) {
this.gmt_modified = gmt_modified;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", student_id=").append(student_id);
sb.append(", name=").append(name);
sb.append(", phone=").append(phone);
sb.append(", email=").append(email);
sb.append(", sex=").append(sex);
sb.append(", locked=").append(locked);
sb.append(", gmt_created=").append(gmt_created);
sb.append(", gmt_modified=").append(gmt_modified);
sb.append(", serialVersionUID=").append(serialVersionUID);
sb.append("]");
return sb.toString();
}
}
2.1:接著需要?jiǎng)?chuàng)建mybatis的xml的配置文件喇勋,配置文件的一些屬性可以參考https://mybatis.org/mybatis-3/zh/configuration.html#properties,當(dāng)前的目錄
配置文件mybatis.config.xml的內(nèi)容
<?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">
<!--注意配置參數(shù)的順序-->
<configuration>
<!--引用外部的屬性文件-->
<properties resource="sql/jdbc.properties"></properties>
<settings>
<!--使mybatis打印出sql語句-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--對(duì)類的完全包名進(jìn)行重命名:mybatis.entity.StudentModel -> StudentModel漫玄,后面直接使用 StudentModel 就可以了-->
<typeAliases>
<!--單個(gè)實(shí)體模式 和 包模式-->
<!--<typeAlias alias="StudentModel" type="mybatis.entity.StudentModel"/>-->
<package name="mybatis.entity"/>
</typeAliases>
<!--可以配置其他的環(huán)境茄蚯,開發(fā)和發(fā)布等-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">
<property name="" value=""/>
</transactionManager>
<!--數(shù)據(jù)庫的參數(shù)-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClass}"/>
<property name="url" value="${jdbc.connectionURL}"/>
<property name="username" value="${jdbc.userId}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!--映射文件的路徑,可以是包路徑也可以設(shè)置單個(gè)文件的路徑-->
<mappers>
<mapper resource="myBatisMapper/StudentDao.xml"/>
</mappers>
</configuration>
jdbc.properties文件內(nèi)容
#mysql驅(qū)動(dòng)的路徑
jdbc.driverLocation=/Users/apple/Tomcat/apache-tomcat-9.0.14/webapps/ROOT/WEB-INF/lib/mysql-connector-java-5.1.6.jar
jdbc.driverClass=com.mysql.cj.jdbc.Driver
#修改為自己的數(shù)據(jù)庫地址
jdbc.connectionURL=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8&useSSL=false&useServerPrepStmts=true&cachePrepStmts=true
jdbc.userId=root
jdbc.password=*******
2.2:創(chuàng)建映射接口與映射文件StudentDao.xml
映射接口StudentDao
package mybatis.dao;
import mybatis.entity.StudentModel;
import java.util.List;
public interface StudentDao {
// int deleteByPrimaryKey(Integer student_id);
// 單條數(shù)據(jù)插入
int insert(StudentModel record);
// 批量插入
int insertBatch(List<StudentModel> list);
// 校驗(yàn)參數(shù)插入
int insertSelective(StudentModel record);
//
// StudentModel selectByPrimaryKey(Integer student_id);
//
// int updateByPrimaryKeySelective(StudentModel record);
//
// int updateByPrimaryKey(StudentModel record);
}
特別注意:在<insert>語句中 insert into student 這里的 student 不能帶有雙引號(hào) "student"睦优,因?yàn)楹竺娌捎胢ybatis逆向生成時(shí)自動(dòng)增加的雙引號(hào)渗常,導(dǎo)致執(zhí)行時(shí)報(bào)錯(cuò)
<?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">
<!--指定對(duì)應(yīng)的映射接口-->
<mapper namespace="mybatis.dao.StudentDao">
<!--定義一個(gè)返回類型的映射,這里的type原本應(yīng)該是完整的包路徑汗盘,但是在配置文件中使用了<typeAliases>皱碘,所以可以直接寫成類名-->
<resultMap id="BaseResultMap" type="StudentModel">
<id column="student_id" jdbcType="INTEGER" property="student_id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="phone" jdbcType="VARCHAR" property="phone" />
<result column="email" jdbcType="VARCHAR" property="email" />
<result column="sex" jdbcType="TINYINT" property="sex" />
<result column="locked" jdbcType="TINYINT" property="locked" />
<result column="gmt_created" jdbcType="TIMESTAMP" property="gmt_created" />
<result column="gmt_modified" jdbcType="TIMESTAMP" property="gmt_modified" />
</resultMap>
<!--定義sql語句使用的參數(shù)名稱,后面引用 Base_Column_List 就可以使用里面的參數(shù)名稱-->
<sql id="Base_Column_List">
student_id, name, phone, email, sex, locked, gmt_created, gmt_modified
</sql>
<sql id="insert_Column_List">
name, phone,
email, sex, locked,
gmt_created, gmt_modified
</sql>
<!--單條數(shù)據(jù)插入 useGeneratedKeys="true" keyProperty="student_id" 插入并返回主鍵-->
<insert id="insert" useGeneratedKeys="true" keyProperty="student_id" parameterType="StudentModel" >
insert into student
(<include refid="insert_Column_List"/>)
values (#{name,jdbcType=VARCHAR}, #{phone,jdbcType=VARCHAR},
#{email,jdbcType=VARCHAR}, #{sex,jdbcType=TINYINT}, #{locked,jdbcType=TINYINT},
#{gmt_created,jdbcType=TIMESTAMP}, #{gmt_modified,jdbcType=TIMESTAMP})
</insert>
<!--批量數(shù)據(jù)插入-->
<insert id="insertBatch">
insert into student (name, phone,
email, sex, locked,
gmt_created, gmt_modified)
VALUES
<foreach collection ="list" item="item" separator =",">
(#{item.name,jdbcType=VARCHAR}, #{item.phone,jdbcType=VARCHAR},
#{item.email,jdbcType=VARCHAR}, #{item.sex,jdbcType=TINYINT}, #{item.locked,jdbcType=TINYINT},
#{item.gmt_created,jdbcType=TIMESTAMP}, #{item.gmt_modified,jdbcType=TIMESTAMP})
</foreach >
</insert>
<!--prefix="(" suffix=")" suffixOverrides="," 指定字符串開頭和截取最后,-->
<insert id="insertSelective" useGeneratedKeys="true" keyProperty="student_id" parameterType="StudentModel">
insert into student
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="name != null">
name,
</if>
<if test="phone != null">
phone,
</if>
<if test="email != null">
email,
</if>
<if test="sex != null">
sex,
</if>
<if test="true">
locked,
</if>
<if test="gmt_created != null">
gmt_created,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="name != null">
#{name,jdbcType=VARCHAR},
</if>
<if test="phone != null">
#{phone,jdbcType=VARCHAR},
</if>
<if test="email != null">
#{email,jdbcType=VARCHAR},
</if>
<if test="sex != null">
#{sex,jdbcType=TINYINT},
</if>
<if test="true">
#{locked,jdbcType=TINYINT},
</if>
<if test="gmt_created != null">
#{gmt_created,jdbcType=TIMESTAMP},
</if>
</trim>
</insert>
</mapper>
3:開始使用mybatis隐孽,
3.1:創(chuàng)建mybatis的操作類癌椿,請(qǐng)參考https://mybatis.org/mybatis-3/zh/getting-started.html
這里采用單例模式,來保證 SqlSessionFactory 只被創(chuàng)建一次
package mybatis;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
//sqlSessionFactory 的單例模式
public class MyBatisSessionFactory {
private SqlSessionFactory factory;
/**
* 類級(jí)的內(nèi)部類菱阵,也就是靜態(tài)的成員式內(nèi)部類踢俄,該內(nèi)部類的實(shí)例與外部類的實(shí)例
* 沒有綁定關(guān)系,而且只有被調(diào)用到才會(huì)裝載晴及,從而實(shí)現(xiàn)了延遲加載
*/
private static class SingletonHolder {
/**
* 靜態(tài)初始化器都办,由JVM來保證線程安全
*/
private static MyBatisSessionFactory instance = new MyBatisSessionFactory();
}
/**
* 私有化構(gòu)造方法
*/
private MyBatisSessionFactory() {
// 通過配置文件創(chuàng)建 sqlSessionFactory 的實(shí)列,sqlSessionFactory 用來生成 sqlSession
String resource = "myBatis/mybatis.config.xml";
try {
InputStream inputStream = Resources.getResourceAsStream(resource);
factory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (Exception e) {
e.printStackTrace();
}
}
public static MyBatisSessionFactory getInstance(){
return SingletonHolder.instance;
}
public SqlSessionFactory getFactory() {
return factory;
}
}
3.2:創(chuàng)建測試類虑稼,添加測試方法
package mybatis;
import mybatis.dao.StudentDao;
import mybatis.entity.StudentModel;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Date;
import org.slf4j.Logger;
public class MybatisTest {
private static final Logger logger = LoggerFactory.getLogger(MybatisTest.class);
// 單條插入
@Test
public void insert() {
long start = System.currentTimeMillis();
SqlSession session = myBatisSessionFactory.getInstance().getFactory().openSession();
StudentDao studentDaoMapper = session.getMapper(StudentDao.class);
for (int i = 0; i < 500; i++) {
StudentModel model = buildStudentModel(i);
int result = studentDaoMapper.insert(model);
logger.debug("插入 = " + String.valueOf(result) + ", student_id =" + model.getStudent_id());
}
// 提交
session.commit();
long end = System.currentTimeMillis();
logger.info("時(shí)間----" +(end - start));
// insertBatch();
}
// 批量插入
@Test
public void insertBatch() {
long start = System.currentTimeMillis();
SqlSession session = myBatisSessionFactory.getInstance().getFactory().openSession();
StudentDao studentDaoMapper = session.getMapper(StudentDao.class);
ArrayList<StudentModel> arrayList = new ArrayList<StudentModel>();
for (int i = 0; i < 1500; i++) {
StudentModel model = buildStudentModel(i);
arrayList.add(model);
}
studentDaoMapper.insertBatch(arrayList);
// 提交
session.commit();
long end = System.currentTimeMillis();
logger.info("時(shí)間----" +(end - start));
}
// 判斷插入值為空琳钉,則不插入此值
@Test
public void insertSelective() {
SqlSession session = myBatisSessionFactory.getInstance().getFactory().openSession();
StudentDao studentDaoMapper = session.getMapper(StudentDao.class);
StudentModel model = buildStudentModel(0);
int result = studentDaoMapper.insertSelective(model);
logger.info("插入 = " + String.valueOf(result) + ", student_id =" + model.getStudent_id());
// 提交
session.commit();
}
static double phone = 10000000000.f;
static int name = 1;
static int email = 1;
private StudentModel buildStudentModel(int i) {
StudentModel model = new StudentModel();
model.setName("二天" + name);
model.setPhone(String.valueOf(phone));
model.setSex(Byte.parseByte("1"));
model.setEmail("email" + email);
model.setGmt_created(new Date());
model.setStudent_id(1);
return model;
}
}
測試打印
Reader entry: ????1?
Checking to see if class mybatis.entity.StudentModel matches criteria [is assignable to Object]
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Opening JDBC Connection
Created connection 351877391.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@14f9390f]
==> Preparing: insert into student ( name, phone, email, sex, locked, gmt_created, gmt_modified ) values (?, ?, ?, ?, ?, ?, ?)
==> Parameters: 二天1(String), 1.0E10(String), email1(String), 1(Byte), null, 2020-04-11 16:44:43.363(Timestamp), null
<== Updates: 1
Committing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@14f9390f]
四月 11, 2020 4:44:43 下午 mybatis.MybatisTest insert
信息: 循環(huán)插入時(shí)間----872
測試大量數(shù)據(jù)插入的有效方法
1500條數(shù)據(jù)插入的對(duì)比
四月 11, 2020 4:48:25 下午 mybatis.MybatisTest insert
信息: 循環(huán)插入時(shí)間----1827
四月 11, 2020 4:48:25 下午 mybatis.MybatisTest insertBatch
信息: 批量插入時(shí)間----418
參考的文章:
https://mybatis.org/mybatis-3/zh/getting-started.html
https://www.cnblogs.com/homejim/p/9613205.html
https://www.cnblogs.com/huangjinyong/p/11209753.html