- 持久层框架,它支持自定义SQL、存储过程以及高级映射。
- 免除了几乎所有JDBC代码以及设置参数和获取结果集的工作(底层实现是JDBC)
- 可通过简单的XML或注解来配置和映射原始类型、接口和Java POJO(普通老式 Java 对象)记录在数据库中
软件分层
web层(controller层) -- 处理请求
service层 -- 业务处理
dao层(持久层) -- 与数据库交互
分层代码
不同层代码放在不同的包
controller层 --- com.xxx.controller
service 层 --- com.xxx.service
dao层 --- com.xxx.dao
实体层 --- com.xxx.model
工具类 --- com.xxx.utils
持久层
软件中用于持久化的代码
持久化
将数据保存到可掉电式设备中:txt、图片、数据库
环境搭建
ORM框架:(object relation mapping) -- 实体关系映射
1、建表(数据库)
2、编写对应表的实体类(Java)
3、编写dao层接口
public interface StudentDao {
// 返回值 方法名
// 查询所有学生对象
List<Student> getAllStu();
}
4、导入myBatis核心包和JDBC实现包(lib文件夹内,Bulid Path)
5、每个dao层接口对应一个xml配置文件(文件名与接口类名称必须一致)
<?xml version="1.0" encoding="UTF-8" ?>
<!-- 每个xml文件都以此句开头 -->
<!DOCTYPE mapper
<!-- dtd -- XML文件的约束(规定XML文件的编写规则) -->
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- mapper标签:一个接口对应一个mapper
namespace(命名空间 -- 绑定指定接口)
-->
<mapper namespace="com.xxx.dao.StudentDao">
<!--
不同的操作封装不同功能标签
select -- 对应接口查询操作
update -- 更新
delete -- 删除
insert -- 插入
对接口中每一个抽象方法编写对应操作
每个标签都有一个id属性,id属性绑定对应接口方法名
接口要执行的SQL语句放在标签中
-->
<!-- resultType 告诉Mybatis 查询完毕后封装对象 参照哪个实体类 -->
<select id="getAllStu" resultType="com.xxx.model.Student">
SELECT * FROM student;
</select>
</mapper>
6、每个myBatis应用,都有一个myBatis的全局配置文件(.xml在src文件下)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
<!-- mybatis3config.dtd,myBatis全局配置文件的约束 -->
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--
environments 表示可配置多个数据库环境
每个environments标签可以配置多个environment(每个environment表示一个环境)
想要开启某个环境在environments的default内指定环境名
-->
<environments default="development">
<!-- 每个environment中有一个为该环境命名的id属性 -->
<environment id="development">
<transactionManager type="JDBC"/>
<!-- dataSource:数据源 -->
<dataSource type="POOLED">
<!-- driver:驱动名 -->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<!-- url -->
<property name="url" value="jdbc:mysql://localhost:3306/test75_13?useUnicode=true&characterEncoding=UTF8&serverTimezone=UTC"/>
<!-- username、password 数据库的用户名、密码 -->
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- mapper标签的resource:指定引入的mapper配置(资源路径,以/分割) -->
<mapper resource="com/xxx/dao/StudentDao.xml"/>
</mappers>
</configuration>
7、启动MyBatis
// 默认在src下读取文件
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
// 工厂模式:解析InputStream,生产sqlSession对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// SqlSession对象,放所有myBaits生成的DAO层接口的实现
SqlSession session = sqlSessionFactory.openSession();
// 获取指定的接口实现
StudentDao studentDao = session.getMapper(StudentDao.class);
// 多态调用方法
int count = studentDao.deleteStuByID();
// 更新类需要提交事务
session.commit();
// sqlSessoin是个资源,使用完毕后必须进行关闭
session.close();
可能会遇到的问题:
接口没注册mapper,全局配置文件中没引入mapper配置
Type interface com.woniuxy.dao.StudentDao is not known to the MapperRegistry
参数传递
@param
在接口形参上@param("参数的别名") 参数类型 形参
在XML配置文件中通过 #{别名} 取值
接口类
// 添加学生
int addStudent(@Param("student")Student student);
// 通过姓名和描述查找学生
List<Student> getStuByNameAndByDesc(@Param("name")String name,@Param("desc")String desc);
xml配置文件
<insert id="addStudent">
<!-- #{student.sname}用get方法获取的学生对象的名字 -->
INSERT INTO student VALUES (DEFAULT,#{student.sname},#{student.sdesc});
</insert>
<select id="getStuByNameAndByDesc" resultType="com.woniuxy.model.Student">
SELECT * FROM student WHERE sname = #{name} AND sdesc = #{desc};
</select>
传递Map
在接口写map @param对参数取别名
List<Student> getStuByNameAndByDesc2(@Param("condition")Map<String,Object> condition);
在xml配置文件中通过 #{map.k} 取值
<select id="getStuByNameAndByDesc2" resultType="com.woniuxy.model.Student">
SELECT * FROM student WHERE sname = #{condition.name} AND sdesc = #{condition.desc};
</select>
在调用方法的时候传递map
Map<String,Object> map = new HashMap();
map.put("name", "JERRY");
map.put("desc", "JERRY 是谁");
List<Student> stuByNameAndByDesc2 = studentDao.getStuByNameAndByDesc2(map);
for (Student student : stuByNameAndByDesc2) {
System.out.println(student);
}
session.commit();
session.close();