一芽突、重點(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_url}" />
<property name="username" value="{password}" />
</dataSource>
</environment>
</environments></pre>
- typeAliases: 解決別名的問(wèn)題
在mybatis-config.xml配置文件中配置別名
?
<typeAliases>
<package name="com.im.entity"/>
</typeAliases></pre>
??
</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>
??
</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>
??
</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>
??
</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>
??
</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" 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_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>