初學Mybatis筆記
Mybatis
一、初識mybatis
中文文件:https://mybatis.org/mybatis-3/zh/getting-started.html
(1)Mybatis是一個數據持久層的框架
(2)實現SQL與程式碼分離
(3)避免了JDBC程式碼以及手動設定引數和獲取結果集
二、第一個Mybatis程式
基本步驟:
0、先匯入包 -- 連線資料庫的驅動包、Mybatis依賴包、Junit測試包、Lombok
1、獲取執行SQL的sqlSession物件(xml配置檔案 -> SqlSessionFactory -> SqlSession) -- 封裝為一個工具類
https://www.cnblogs.com/yulinfeng/p/6002379.html
2、獲取sqlSession物件需要載入mybatis-config.xml配置檔案
3、常規操作編寫資料類dto|pojo
4、編寫mapper(以前的Dao介面)
5、編寫對應的mapper.xml(以前的Dao的實現類)
6、編寫測試類進行測試
0、先匯入包 -- 連線資料庫的驅動包、Mybatis依賴包、Junit測試包、Lombok
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.ch</groupId> <artifactId>jdbcstudy</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!-- 新增連線資料庫的驅動 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <!-- 新增mybatis依賴包 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency> <!-- 新增測試類Junit測試包 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <!-- 簡化資料類的get,set等方法,匯入lombok依賴包 --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> </dependency> </dependencies> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources> </build> </project>
1、獲取執行SQL的sqlSession物件(xml配置檔案 -> SqlSessionFactory -> SqlSession) -- 封裝為一個工具類
package com.ch.util; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.IOException; import java.io.InputStream; /** * 獲取執行SQL的SQLSession物件 * * 獲取的步驟:載入配置檔案 -> sqlSessionFactory -> sqlSession * * 參照官方文件理解sqlSessionFactoryBuilder、SQLSessionFactory、SQLSession的區別。 */ public class SqlSessionUtil { private static SqlSessionFactory ssf; static { //1、載入mybatis的配置檔案 String resource = "mybatis-config.xml"; try { InputStream inputStream = Resources.getResourceAsStream(resource); //2、獲取sqlSessionFactory物件 ssf = new SqlSessionFactoryBuilder().build(inputStream); } catch (IOException e) { e.printStackTrace(); } } //3、獲取SqlSession物件 public static SqlSession getSqlSession(){ return ssf.openSession(); } }
2、獲取sqlSession物件需要載入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>
<!-- 官網複製 -->
<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/mysqlstudy?serverTimezone=GMT&characterEncoding=utf8&useSSL=true"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 特別注意:每一個mapper.xml都需要在mybatis的核心配置檔案中進行註冊 -->
<mappers>
<mapper resource="com/ch/mapper/StudentMapper.xml"/>
</mappers>
</configuration>
3、常規操作編寫資料類dto|pojo
@Data
public class Student {
private int id;
private int score;
private String name;
}
4、編寫mapper(以前的Dao介面)
public interface StudentMapper {
List<Student> getAll();
}
5、編寫對應的mapper.xml(以前的Dao的實現類)
namespace:名稱空間,一定要和mapper中介面類的包名
id:名稱空間下唯一標識,就是對應的方法名
resultType:返回值的型別
parameterType:引數型別
<?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">
<!-- 使用namespace繫結對應的介面 -->
<mapper namespace="com.ch.mapper.StudentMapper">
<!-- id對應介面中的方法名,resultType對應返回值的型別 -->
<select id="getAll" resultType="com.ch.dto.Student">
select * from mysqlstudy.student;
</select>
</mapper>
6、編寫測試類進行測試
@Test
public void getAll(){
//獲取執行SQL的物件
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
//拿到SQL可以通過介面mapper,或者通過mapper.xml檔案
//因為是面向介面開發,所以通過介面mapper獲取
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> all = mapper.getAll();
for (Student s : all){
System.out.println(s);
}
}
三、CRUD
特別注意:
增刪改需要提交事務
-
可以手動提交:sqlSession.commit();
-
也可以設定為自動提交:在工具類中設定
//3、獲取SqlSession物件 public static SqlSession getSqlSession(){ return ssf.openSession(); }
insert
<!-- 增 -->
<insert id="insert" parameterType="com.ch.dto.Student">
insert into student (id, score, name) values (#{id},#{score},#{name});
</insert>
delete
<!-- 刪 -->
<delete id="delete" parameterType="_int">
delete from student where id = #{id};
</delete>
select
<!-- 查 -->
<select id="select" resultType="com.ch.dto.Student">
select * from student where id = #{id};
</select>
update
<!-- 改 -->
<update id="update" parameterType="com.ch.dto.Student">
update student set score = #{score},name=#{name} where id = #{id};
</update>
MapperTest
//增
@Test
public void insert(){
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student student = new Student();
student.setId(10);
student.setScore(82);
student.setName("喜羊羊");
int insert = mapper.insert(student);
System.out.println(insert > 0 ? "插入成功" : "插入失敗");
//增刪改一定要提交
sqlSession.commit();
sqlSession.close();
}
//刪
@Test
public void delete(){
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
int delete = mapper.delete(10);
System.out.println(delete > 0 ? "刪除成功" : "刪除失敗");
sqlSession.commit();
sqlSession.close();
}
//查
@Test
public void select(){
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student student = mapper.select(10);
System.out.println(student);
sqlSession.close();
}
//改
@Test
public void update(){
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student student = new Student();
student.setId(10);
student.setScore(82);
student.setName("美羊羊");
mapper.update(student);
sqlSession.commit();
sqlSession.close();
}
Map傳值
map可以隨意製造引數
(1)多個引數使用Map傳值,或者使用註解
(2)如果資料表字段太多,可以考慮使用map
int update2(Map<String,Object> map);
<update id="update2" parameterType="map">
update student set score = #{sc} where id = #{id} and name = #{sname};
</update>
模糊查詢
1、直接在傳值的使用萬用字元
List<Student> students = mapper.queryByLike("%小%");
2、可以在SQL中固定死萬用字元
select * from student where name like "%"#{value}"%";
或
select * from student where `name` like concat('%',#{value},'%');
四、初始配置檔案
mybatis-config.xml
事務管理器:JDBC(預設)、MANAGED
資料來源型別:UNPOOLED、POOLED(預設)、JNDI
<configuration>
<!-- 官網複製 -->
<!-- environments可以適應多種環境,但是每個SqlSessionFactory只能選擇一種環境 -->
<!-- default選擇預設環境,對應環境的唯一id -->
<environments default="development">
<environment id="development">
<!-- transactionManager事務管理器,Mybatis中有兩種:JDBC和MANAGED -->
<transactionManager type="JDBC"/>
<!-- 資料來源【連線資料庫】-> dbcp、c3p0、druid -->
<!-- 內建了三種資料來源型別:unpooled、pooled、jndi -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mysqlstudy?serverTimezone=GMT&characterEncoding=utf8&useSSL=true"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 特別注意:每一個mapper.xml都需要在mybatis的核心配置檔案中進行註冊 -->
<mappers>
<mapper resource="com/ch/mapper/StudentMapper.xml"/>
</mappers>
</configuration>
五、配置優化
0、類型別名
別名 | 對映的型別 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
object | Object |
map | Map |
hashmap | HashMap |
list | List |
arraylist | ArrayList |
collection | Collection |
iterator | Iterator |
1、屬性(properties)優化
我們可以使用properties來引入配置檔案
*注意問題:
(1)properties的位置
元素型別為 "configuration" 的內容必須匹配"(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)"
(2)優先順序
如果properties和xml(properties中配置的相關欄位)中均使用了同一欄位,優先使用外部配置檔案
db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mysqlstudy?serverTimezone=GMT&characterEncoding=utf8&useSSL=true
username=root
password=root
mybatis-config.xml
<!-- 引入配置檔案 -->
<properties resource="db.properties">
<!-- <property name="username" value="root"/> -->
</properties>
2、別名(typeAliases)優化
介面實現類xml中,每個返回值型別或者引數型別,都需要寫對應實體類的完整包名,所以使用別名優化
可以有三種方式:(賬戶以設定別名在配置檔案中的位置)
1、固定死,每一個實體類對應一個別名
<typeAliases> <typeAlias type="com.ch.dto.Student" alias="student"></typeAlias> </typeAliases>
2、較靈活,只用設定包即可,使用的是對應包下的每個實體類類名,首字母小寫
<typeAliases> <package name="com.ch.dto"/> </typeAliases>
3、最靈活,在所需要的設定的實體類上面添加註解即可
@Data @Alias("student") public class Student { private int id; private int score; private String name; }
3、對映器(Mapper)
使用對映器繫結我們的mapper檔案,有3中方式繫結
方式一:直接繫結對應的mapper.xml檔案【推薦使用】
<mappers>
<mapper resource="com/ch/mapper/StudentMapper.xml"/>
</mappers>
方式二:使用類class進行繫結
<mappers>
<mapper class="com.ch.mapper.StudentMapper"></mapper>
</mappers>
注意:
- 介面和mapper配置檔案必須同名
- 介面和mapper配置檔案必須在同一個包下
方式三:使用包對映進行繫結
<mappers>
<package name="com.ch.mapper"/>
</mappers>
注意:
- 介面和mapper配置檔案必須同名
- 介面和mapper配置檔案必須在同一個包下
六、解決屬性和欄位不一致
問題描述:實體類中的屬性和資料表中的欄位名不一致,導致最後查詢的結果為null
方式一:
as起別名的方式來進行欄位和屬性對應
<select id="getAll" resultType="student">
select id, score, name as sName from mysqlstudy.student;
</select>
方式二:【推薦使用】
使用ResultMap進行屬性和欄位名的對映
<!-- 使用resultMap進行對映,只需對映不一樣的欄位即可 -->
<resultMap id="st" type="student">
<result column="name" property="sName"></result>
</resultMap>
<select id="getAll" resultMap="st">
select id, score, name as sName from mysqlstudy.student;
</select>
七、Mybatis註解開發
- 適用於簡單的SQL語句,複雜的SQL語句推薦使用xml配置檔案
- 本質是使用反射來獲取註解
- 底層是動態代理
1、在介面上添加註解
@Select("select * from student")
List<Student> getAll1();
2、新增mapper對映(使用類名來進行繫結)
<mappers>
<mapper class="com.ch1.mapper.StudentMapper"></mapper>
</mappers>
CRUD
@Insert("insert into student value(#{id},#{score},#{name})")
int insert1(Student student);
@Delete("delete from student where id = #{id}")
int delete1(@Param("id") int id);
@Select("select * from student where id = #{id}")
Student select1(@Param("id") int id);
@Update("update student set score = #{score} where id = #{id}")
int update1(Student student);