1.Mybatis 快速入門
2.Mybatis 相關API
3.Mybatis 映射配置文件
4.Mybatis 核心配置文件
5.Mybatis 傳統(tǒng)方式實現(xiàn)Dao層
框架介紹
- 框架就是半成品軟件,我們可以基于這個半成品軟件繼續(xù)開發(fā),完成個性化需求
ORM介紹
- ORM(Object Relational Mapping): 對象關系映射
- 指的是持久化數(shù)據和實體對象的映射模式,為了解決面向對象與關系型數(shù)據庫存在的互不匹配的現(xiàn)象的技術
- 映射規(guī)則
數(shù)據表-> 類
表字段-> 類屬性
表數(shù)據-> 對象
原始JDBC的操作弊端
- 原始JDBC的操作問題分析
1.頻繁創(chuàng)建和銷毀數(shù)據庫的連接會造成系統(tǒng)資源浪費從而影響系統(tǒng)性能
2.SQL語句在代碼中硬編寫,如果要修改sql語句,就需要修改java代碼,造成代碼不易維護
3.查詢操作時,需要手動將結果集中的數(shù)據結構封裝到實體對象中
4.增刪改查操作需要參數(shù)時,需要手動將實體對象的數(shù)據設置到sql語句的占位符- 原始JDBC的操作問題解決方案
1.使用數(shù)據庫連接池初始化連接資源
2.將sql語句抽取到配置文件中,讀取配置文件
3.使用反射,內省等底層技術,將實體與表進行屬性和字段的自動映射
MyBatis介紹
- MyBatis是一個優(yōu)秀的基于java的持久層框架,它內部封裝了JDBC,時開發(fā)這只需要關注SQL語句本省,而不需要花費精力去處理加載驅動,創(chuàng)建連接,創(chuàng)建執(zhí)行對象等復雜的操作
- MyBatis通過XML或注解的方式將要執(zhí)行的各種Statement配置起來,并通過java對象和Statement中SQL的動態(tài)參數(shù)進行映射生成最終要執(zhí)行的SQL語句
- 最后MyBatis框架執(zhí)行完SQL并將結果映射為Java對象返回.采用ORM思想解決了實體和數(shù)據庫映射的問題,對JDBC進行了封裝,屏蔽了JDBC API底層訪問細節(jié),使我們不用和JDBC API打交道,就可以完成對數(shù)據庫的持久化操作
1.快速入門
1.環(huán)境搭建(創(chuàng)建user數(shù)據表宋雏、編寫Student實體類)
2.編寫StudentMapper映射文件
mapping文件約束頭
<?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">
<?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="StudentMapper">
<select id="selectAll" resultType="com.itheima.bean.Student">
SELECT * FROM student
</select>
</mapper>
3.編寫MyBatisConfig核心文件
核心文件約束頭
<?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">
<?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="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://數(shù)據庫地址/庫名"/>
<property name="username" value="賬號"/>
<property name="password" value="密碼"/>
</dataSource>
</environment>
</environments>
<!--加載映射文件-->
<mappers>
<mapper resource="StudentMapper.xml"></mapper>
</mappers>
</configuration>
4.編寫測試類
package com.itheima.dao;
import com.itheima.bean.Student;
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 org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class StudentTest01 {
/*
查詢全部
*/
@Test
public void selectAll() throws IOException {
//1.加載核心配置
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
//2.獲取SqlSession工廠對象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通過SqlSession工廠對象獲取SqlSession對象
SqlSession sqlSession = sqlSessionFactory.openSession();
//4.執(zhí)行映射配置文件中的sql語句,并接收結果
List<Student> list = sqlSession.selectList("StudentMapper.selectAll");
//5.處理結果
for (Student student : list) {
System.out.println(student);
}
//6.釋放資源
sqlSession.close();
is.close();
}
}
2.相關API
Resource
- org,apache.ibatis.io.Resource: 加載資源的工具類
核心方法:
返回值: InputStream
方法名: getResourceAsStream(String fileName)
說明: 通過類加載器返回指定資源的字節(jié)輸入流
SqlSessionFactoryBuilder
- org.apache.ibatis.session.SqlSessionFactoryBuilder: 獲取SqlSessionFactory工廠類對象的功能類
核心方法:
返回值: SqlSessionFactory
方法名: build(InputStream is)
說明: 通過指定資源字節(jié)輸入流獲取SqlSession工廠類對象
SqlSessionFactory
- org.apache.ibatis.session.SqlSessionFactpory: 獲取SqlSession構架者對象的工廠類接口
返回值: SqlSession
方法名: openSession()
說明: 獲取SqlSession構建者對象,并開啟手動提交事務
返回值: SqlSession
方法名: openSession(boolean autoCommit)
說明: 獲取SqlSession構建者對象,如果參數(shù)為true,則開啟自動提交事務
SqlSession
org.apache.ibatis.session.SqlSession: 構建者對象接口,用于執(zhí)行SQL,管理事務,接口代理
3.映射配置文件
- 映射配置文件包含了數(shù)據和對象之間的映射關系以及要執(zhí)行的SQL語句
- 1.<mapper>: 核心根標簽
namespace屬性: 名稱空間- 2.<select>: 查詢功能的標簽
- 4.<insert>: 新增功能標簽
- 5.<update>: 修改功能標簽
- 6.<delete>: 刪除功能標簽
標簽相同屬性
1.id屬性: 唯一標識,配合命名空間使用
2.resultType屬性: 指定結果映射對象類型
3.parameterType屬性: 指定參數(shù)隱射對象類型- 7.SQL獲取參數(shù): #{屬性名}
測試單元代碼
package com.itheima.dao;
import com.itheima.bean.Student;
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 org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class StudentTest01 {
/*
查詢全部
*/
@Test
public void selectAll() throws IOException {
//1.加載核心配置
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
//2.獲取SqlSession工廠對象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通過SqlSession工廠對象獲取SqlSession對象
SqlSession sqlSession = sqlSessionFactory.openSession();
//4.執(zhí)行映射配置文件中的sql語句,并接收結果
List<Student> list = sqlSession.selectList("StudentMapper.selectAll");
//5.處理結果
for (Student student : list) {
System.out.println(student);
}
//6.釋放資源
sqlSession.close();
is.close();
}
/*
根據id進行查詢
*/
@Test
public void selectById() throws IOException {
//加載核心配置文件
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
//獲取SqlSession工廠對象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//通過工廠對象獲取SqlSession對象
SqlSession sqlSession = sqlSessionFactory.openSession();
//執(zhí)行映射配置文件中的sql語句,并接收結果
Student stu = sqlSession.selectOne("StudentMapper.selectById", 1);
//打印結果
System.out.println(stu);
//釋放資源
sqlSession.close();
is.close();
}
/*
新增學生方法
*/
@Test
public void insert() throws IOException {
//加載核心配置文件
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
//獲取工廠類對象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//通過工廠類對象獲取SqlSession對象
//SqlSession sqlSession = sqlSessionFactory.openSession();
//通過給定布爾類型的參數(shù)為true,開啟自動提交事務
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//執(zhí)行映射配置文件中的sql語句,并接收結果
Student stu = new Student(5, "周期", 77);
int insert = sqlSession.insert("StudentMapper.insert",stu);
//對于增刪改,提交事務
//sqlSession.commit();
System.out.println(insert);
//釋放資源
sqlSession.close();
is.close();
}
/*
修改學生方法
*/
@Test
public void update() throws IOException {
//加載核心配置文件
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
//獲取工廠類對象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//通過工廠類對象獲取SqlSession對象
SqlSession sqlSession = sqlSessionFactory.openSession();
//執(zhí)行映射配置文件中的sql語句,并接收結果
Student stu = new Student(5, "周七", 27);
int result = sqlSession.update("StudentMapper.update",stu);
//對于增刪改,提交事務
sqlSession.commit();
System.out.println(result);
//釋放資源
sqlSession.close();
is.close();
}
/*
刪除學生方法
*/
@Test
public void delete() throws IOException {
//加載核心配置文件
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
//獲取工廠類對象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//通過工廠類對象獲取SqlSession對象
SqlSession sqlSession = sqlSessionFactory.openSession();
//執(zhí)行映射配置文件中的sql語句,并接收結果
int result = sqlSession.delete("StudentMapper.delete",5);
//對于增刪改,提交事務
sqlSession.commit();
System.out.println(result);
//釋放資源
sqlSession.close();
is.close();
}
}
映射配置文件
<?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="StudentMapper">
<!-- 查詢功能-->
<select id="selectAll" resultType="com.itheima.bean.Student">
SELECT * FROM student
</select>
<!-- 根據id查詢-->
<select id="selectById" resultType="com.itheima.bean.Student" parameterType="java.lang.Integer">
select * FROM student where id = #{id}
</select>
<!-- 新增功能-->
<insert id="insert" parameterType="com.itheima.bean.Student">
insert into student values (#{id},#{name},#{age})
</insert>
<!-- 修改功能-->
<update id="update" parameterType="com.itheima.bean.Student">
update student set name=#{name},age=#{age} where id=#{id}
</update>
<!-- 刪除功能-->
<delete id="delete" parameterType="java.lang.Integer">
delete from student where id=#{id}
</delete>
</mapper>
4.核心配置文件
- 核心配置文件包含了MyBatis最核心的設置和屬性信息,如數(shù)據庫的連接,事務,連接池信息等
對配置文件進行說明
<?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配置數(shù)據庫環(huán)境標簽,環(huán)境可以有多個,default屬性指定使用的是哪個-->
<!-- 利用environment標簽可以配置多個數(shù)據庫信息標簽如mysql1,mysql2等等,最終使用哪個,要environments 標簽中的 default屬性來選擇-->
<environments default="mysql">
<!-- environment配置數(shù)據庫信息標簽 id屬性代表唯一的標識-->
<environment id="mysql">
<!-- transactionManager事務的管理標簽 type屬性,采用JDBC默認的事務-->
<transactionManager type="JDBC"></transactionManager>
<!-- dataSource數(shù)據源標簽 type屬性 連接池-->
<dataSource type="POOLED">
<!-- property獲取數(shù)據庫連接的數(shù)據信息標簽-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://IP地址:3306/庫名"/>
<property name="username" value="用戶"/>
<property name="password" value="密碼"/>
</dataSource>
</environment>
</environments>
<!-- mappers引入映射配置文件標簽-->
<mappers>
<!-- mapper 引入指定的映射配置文件 resource屬性: 指定映射配置文件的名稱-->
<mapper resource="StudentMapper.xml"></mapper>
</mappers>
</configuration>
數(shù)據庫配置文件引入
- <properties>: 引入數(shù)據庫連接信息配置文件標簽
- 屬性
resource: 數(shù)據庫連接配置文件路徑- 獲取數(shù)據庫連接參數(shù): ${鍵名}
編寫一個JDBC數(shù)據庫配置文件
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://IP地址:3306/數(shù)據庫名
username=用戶
password=密碼
在核心配置文件中引入JDBC數(shù)據庫配置文件,其他配置不變
<!--引入數(shù)據庫連接的配置文件-->
<properties resource="JDBC.properties"/>
<!--property獲取數(shù)據庫連接的數(shù)據信息-->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
核心配置文件-起別名的使用
- <typeAliases>: 為全類名起別名的父標簽
- <typeAlias>: 為全類名起別名的子標簽
- 屬性
type: 指定全類名
alias: 指定別名- <package>: 為指定包下所有類型起別名的子標簽(別名就是類名)
在核心配置文件<configuration>標簽中添加起別名標簽,其他配置不變
<!-- 起別名-->
<typeAliases>
<typeAlias type="com.itheima.bean.Student" alias="student"/>
</typeAliases>
映射配置文件修改 對com.itheima.bean.Student全類名的引用,其他配置文件不變
<?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="StudentMapper">
<!-- 查詢功能-->
<select id="selectAll" resultType="student">
SELECT * FROM student
</select>
<!-- 根據id查詢-->
<select id="selectById" resultType="student" parameterType="java.lang.Integer">
select * FROM student where id = #{id}
</select>
<!-- 新增功能-->
<insert id="insert" parameterType="student">
insert into student values (#{id},#{name},#{age})
</insert>
<!-- 修改功能-->
<update id="update" parameterType="student">
update student set name=#{name},age=#{age} where id=#{id}
</update>
<!-- 刪除功能-->
<delete id="delete" parameterType="student">
delete from student where id=#{id}
</delete>
</mapper>
常見的自帶的別名
5.Mybatis 傳統(tǒng)方式實現(xiàn)Dao層
Dao 層傳統(tǒng)實現(xiàn)方式
- 分層思想: 控制層(controller),業(yè)務層(service),持久層(dao)
- 調用流程
控制層->業(yè)務層->持久層->DB
1.三個配置文件內容不變
2.編寫的Student類和之前一樣,成員變量和Mysql的表字段對齊
3.持久層mapper目錄下的StudentMapperImpl實現(xiàn)類和StudentMapper接口代碼
package com.itheima.mapper;
import com.itheima.bean.Student;
import java.util.List;
/*
持久層接口
*/
public interface StudentMapper {
//查詢全部
public abstract List<Student> selectAll();
//條件查詢
public abstract Student selectById(Integer id);
//新增數(shù)據
public abstract Integer insert(Student stu);
//更新全部
public abstract Integer update(Student stu);
//刪除全部
public abstract Integer delete(Integer id);
}
package com.itheima.mapper.impl;
import com.itheima.bean.Student;
import com.itheima.mapper.StudentMapper;
import com.sun.corba.se.impl.resolver.SplitLocalResolverImpl;
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;
import java.util.List;
/*
持久層實現(xiàn)類
*/
public class StudentMapperImpl implements StudentMapper {
//查詢全部
@Override
public List<Student> selectAll() {
InputStream is = null;
SqlSession sqlSession = null;
List<Student> list = null;
try {
//加載核心配置文件
is = Resources.getResourceAsStream("MyBatisConfig.xml");
//獲取SqlSession工廠對象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//通過工廠對象獲取SqlSession對象
sqlSession = sqlSessionFactory.openSession(true);
//執(zhí)行映射配置文件中的sql語句,并接收結果
list = sqlSession.selectList("StudentMapper.selectAll");
} catch (Exception e) {
e.printStackTrace();
} finally {
//釋放資源
if (sqlSession != null) {
sqlSession.close();
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//返回結果
return list;
}
//根據id查詢
@Override
public Student selectById(Integer id) {
InputStream is = null;
SqlSession sqlSession = null;
Student stu = null;
try {
//加載核心配置文件
is = Resources.getResourceAsStream("MyBatisConfig.xml");
//獲取SqlSession工廠對象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//通過工廠對象獲取SqlSession對象
sqlSession = sqlSessionFactory.openSession(true);
//執(zhí)行映射配置文件中的sql語句,并接收結果
stu = sqlSession.selectOne("StudentMapper.selectById", id);
} catch (Exception e) {
e.printStackTrace();
} finally {
//釋放資源
if (sqlSession != null) {
sqlSession.close();
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//返回結果
return stu;
}
//新增數(shù)據
@Override
public Integer insert(Student stu) {
InputStream is = null;
SqlSession sqlSession = null;
Integer result = null;
try {
//加載核心配置文件
is = Resources.getResourceAsStream("MyBatisConfig.xml");
//獲取SqlSession工廠對象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//通過工廠對象獲取SqlSession對象
sqlSession = sqlSessionFactory.openSession(true);
//執(zhí)行映射配置文件中的sql語句,并接收結果
result = sqlSession.insert("StudentMapper.insert", stu);
} catch (Exception e) {
e.printStackTrace();
} finally {
//釋放資源
if (sqlSession != null) {
sqlSession.close();
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//返回結果
return result;
}
//修改數(shù)據
@Override
public Integer update(Student stu) {
InputStream is = null;
SqlSession sqlSession = null;
Integer result = null;
try {
//加載核心配置文件
is = Resources.getResourceAsStream("MyBatisConfig.xml");
//獲取SqlSession工廠對象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//通過工廠對象獲取SqlSession對象
sqlSession = sqlSessionFactory.openSession(true);
//執(zhí)行映射配置文件中的sql語句,并接收結果
result = sqlSession.update("StudentMapper.update", stu);
} catch (Exception e) {
e.printStackTrace();
} finally {
//釋放資源
if (sqlSession != null) {
sqlSession.close();
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//返回結果
return result;
}
//刪除數(shù)據
@Override
public Integer delete(Integer id) {
InputStream is = null;
SqlSession sqlSession = null;
Integer result = null;
try {
//加載核心配置文件
is = Resources.getResourceAsStream("MyBatisConfig.xml");
//獲取SqlSession工廠對象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//通過工廠對象獲取SqlSession對象
sqlSession = sqlSessionFactory.openSession(true);
//執(zhí)行映射配置文件中的sql語句,并接收結果
result = sqlSession.delete("StudentMapper.delete", id);
} catch (Exception e) {
e.printStackTrace();
} finally {
//釋放資源
if (sqlSession != null) {
sqlSession.close();
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//返回結果
return result;
}
}
4.業(yè)務層Service目錄下的StudentServiceImpl實現(xiàn)類和StudentService接口代碼
package com.itheima.service;
import com.itheima.bean.Student;
import java.util.List;
/*
業(yè)務層接口
*/
public interface StudentService {
//查詢全部
public abstract List<Student> selectAll();
//根據id查詢
public abstract Student selectById(Integer id);
//新增數(shù)據
public abstract Integer insert(Student stu);
//修改數(shù)據
public abstract Integer update(Student stu);
//刪除數(shù)據
public abstract Integer delete(Integer id);
}
package com.itheima.service.Impl;
import com.itheima.bean.Student;
import com.itheima.mapper.StudentMapper;
import com.itheima.mapper.impl.StudentMapperImpl;
import com.itheima.service.StudentService;
import java.util.List;
/*
業(yè)務層實現(xiàn)類
*/
public class StudentServiceImpl implements StudentService {
//創(chuàng)建持久層對象
private StudentMapper mapper = new StudentMapperImpl();
@Override
public List<Student> selectAll() {
return mapper.selectAll();
}
@Override
public Student selectById(Integer id) {
return mapper.selectById(id);
}
@Override
public Integer insert(Student stu) {
return mapper.insert(stu);
}
@Override
public Integer update(Student stu) {
return mapper.update(stu);
}
@Override
public Integer delete(Integer id) {
return mapper.delete(id);
}
}
LOG4J
- 在日常開發(fā)過程中,排查問題是難免需要輸出MyBatis真正執(zhí)行的SQL語句,參數(shù),結果等信息,我們就可以借助LOG4J的功能來實現(xiàn)執(zhí)行信息的輸出
- 使用步驟
1.導入jar包
2.修改核心配置文件,添加<settings>標簽
<!-- 繼承LOG4J日志信息-->
<settings>
<setting name="logImpl" value="log4j"/>
</settings>
原因: 注意標簽的先后順序<settings>標簽要在<properties>后面,
3.在src下編寫LOG4J配置文件,配置文件為log4j.properties要不然會報錯
# Global Logging configuration
# ERROR WARN INFO DEBUG
log4j.rootLogger=DEBUG,stdout
# Console output...
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %5p [%t] - %m%n