1. MyBatis
MyBatis 是基于 JAVA 的持久层框架,它内部封装了 JDBC
通过 xml 或者 注解 方式使将要的执行各种 statement 配置起来 , 并通过 java对象和statement中SQL的动态参数进行映射生成最终执行的SQL语句
执行完SQL语句 并将结果映射为java对象返回 使用ORM 思想解决问题
2. ORM
Object Relational Mapping 对象关系映射 持久化数据和实体对象的映射模式
3. 使用
导入 mybatis.jar 和mysql.jar
在src下创建映射配置文件 名字无所谓
- ```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">
-在src下创建核心配置文件-```xml<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><!-- 默认配置--><environments default="ie"><!-- 配置名--><environment id="ie"><transactionManager type="JDBC"></transactionManager><dataSource type="POOLED"><!-- 驱动--><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://127.0.0.1:3306/mysql"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment></environments><!-- 映射类--><mappers><!-- 映射类名称--><mapper resource="StudentMapper.xml"/></mappers></configuration>
加核心配置文件
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
获取sqlsession 工厂对象
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is);
执行映射配置文件的sql语句
List<Object> objects = sqlSession.selectList("StudentMapper.any");
释放资源
sqlSession.close();is.close();
4. Resources 加载资源工具类
- Resources.getResourceAsStream(String fileName) 通过类加载器返回指定资源的字节输入流 与获取类加载 加载指定资源字节输入流一样
5. SqlSessionFactoryBuilder 工厂对象功能类
- new SqlSessionFactoryBuilder().build(is); 通过指定资源字节输入流获取SqlSessionFactory工厂对象
6. SqlSessionFactory 对象
- openSession() 获取sqlsession 构建者对象 并开启手动提交事务
- openSession(boolean auotoCommit) 获取sqlsession 构建者对象 true为自动提交事务
7. SqlSession
构建者对象接口 用于执行 SQL 管理事务 接口代理
- selectList(String Statement , object parameter) 执行查询语句 并返回list集合
- selectList(String Statement , object parameter) 执行查询语句 返回一个结果对象
- inser(String Statement , object parameter) 执行新增语句,返回影响行数
- update(String Statement , object parameter) 执行修改语句,返回影响行数
- delete(String Statement , object parameter) 执行删除语句,返回影响行数
- commit() 提交事务
- rollback() 回滚事务
- getMapper(Class
<T>cls) 获取指定接口的代理实现类对象 - close() 释放资源
8. 映射配置文件
mapper 核心根标签
- namespace属性 名称空间
select 查询标签
- id属性 唯一标识
- resultType属性 指定结果映射对象类型 类路径 增删改可以不指定类因为返回的是一个影响行数
- parameterType属性 指定参数映射对象类型 指定执行时传递的parameter类型
- SQL语句获取参数 #{属性名}
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="StudentMapper"><select id="any" resultType="com.xxx..xx" parameterType="java.lang.long">select * from mysql where id = #{id}</select><insert id="insert" parameterType="笔记.jdbc.src.Student">insert into studen value (#{id},#{name},#{age})-- 从Student 中传递 id name age属性</insert></mapper>
9. 核心配置文件
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><!-- configuration根标签--><configuration><!-- environments配置数据库环境 default属性指定使用哪一个--><environments default="ie"><!-- environment配置数据库环境 id属性唯一标识--><environment id="ie"><!-- transactionManager事务管理 type属性 采用jdbc默认的事务管理--><transactionManager type="JDBC"></transactionManager><!-- dataSource数据源信息 type属性 连接池 --><dataSource type="POOLED"><!-- property连接数据库的配置信息--><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://127.0.0.1:3306/mysql"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment></environments><!-- mappers引入映射配置文件--><mappers><!-- mapper 引入指定的映射配置 resource属性 指定映射配置文件的名名称--><mapper resource="StudentMapper.xml"/></mappers></configuration>
10. 数据库连接配置引入
<properties>引入数据库连接配置文件标签- resource属性 数据库连接配置文件路径
获取连接参数
- ${键名}
driver=com.mysql.jdbc.Driverurl=jdbc:mysql://127.0.0.1:3306/mysqlusername=rootpassword=123456
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><!-- configuration根标签--><configuration><!-- environments配置数据库环境 default属性指定使用哪一个--><properties resource="笔记/mybatis/src/config.properties"><environments default="ie"><!-- environment配置数据库环境 id属性唯一标识--><environment id="ie"><!-- transactionManager事务管理 type属性 采用jdbc默认的事务管理--><transactionManager type="JDBC"></transactionManager><!-- dataSource数据源信息 type属性 连接池 --><dataSource type="POOLED"><!-- property连接数据库的配置信息--><property name="driver" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/></dataSource></environment></environments><!-- mappers引入映射配置文件--><mappers><!-- mapper 引入指定的映射配置 resource属性 指定映射配置文件的名名称--><mapper resource="StudentMapper.xml"/></mappers></configuration>
11. 起别名
在映射配置中 我们resultType属性需要提供 类的全路径 可以在核心配置文件中起别名来简写
<typeAliaser>为全类名起别名的父标签<typeAlias>为全类名起步名的子标签属性:
- type 指定全类名
- alias 指定别名
<package>为指定包下所有类起别的子标签 别名就是类名
<typeAliases><typeAlias type="笔记.jdbc.src.Student" alias="student"></typeAlias></typeAliases>

12. LOG4J
在核心配置文件添加
<settings><setting name="logImpl" value="log4j"/></settings>
并配置好log4j.properties 配置
13. 分层思想
控制层(controller) ====> 业务层(service) ====> 持久层(dao)
持久层 对接数据库
业务层 处理业务逻辑 此处只是暂时直接调用dao层的方法
控制层 使用 test类
14. 接口代理
通过接口代理 我们只需要写dao层的接口 由MyBatis 框架根据接口的定义来创建接口的动态代理对象
- 映射配置文件中的名称空间必须与dao层接口的全类名相同
- 映射配置文件中的增删改查的id属性必须和dao层接口的方法名相同
- 映射配置文件中的增删改查标签的parameterType属性必须和dao层接口方法的参数相同
- 映射配置文件中的增删改查标签的resultType属性必须和dao层接口的返回值相同
getMapper(Class<T> cls) 获取指定接口的代理实现类对象
mybatisdemo01 mapper = sqlSession.getMapper(mybatisdemo01.class);
14.1. 源码分析
通过getMapper()方法 获取到 org.apache.ibatis.binding.MapperProxy 代理对象 底层使用 JDK 的动态代理技术 帮我们实现代理实现类对象
执行方法时调用了 mapperMethod.execute()方法 通过switch语句 判断操作类型是增删改查操作
通过SqlSession 方法来执行
15. 动态SQL
可以根据SQL语句动态根据条件查询
<where>条件标签 如果有动态条件 则使用该标签替代where关键字<if>条件判断标签 test属性 条件控制 如果成立则拼接SQL语句
<select id="dongtaisql" resultType="studen">select * from stden<where><if test="id != null">id = #{id}</if><if test="age != null">and age = #{age}</if></where></select>
<foreach>循环遍历标签 适用于多个参数或者的关系- collection属性 参数容器类型(list集合 array数组)
- open属性 开始的sql语句
- close属性 结束的sql语句
- item属性 参数变量名
- separator属性 分隔符
<!-- select * forme studen id in(1,2,3)--><select id="selectbyids" resultType="studen" parameterType="list">select * from studen<where><foreach collection="list" open="id in(" close=")" separator="," item="id">#{id}</foreach></where></select>
16. SQL 片段抽取
将一些重复性的SQL语句进行抽取 达到复用的效果
<sql>标签 抽取sql语句标签 id属性唯一标识<include>引入sql片段标签 refid属性需要引用片段的唯一标识
<sql id="select">select * from studen</sql><select id="qsq" resultType="student" parameterType="student"><include refid="select"></include> where id = #{id}</select>
17. 获取自增的ID 再插入数据
先执行LAST_INSERT_ID() 返回一个id并封装在对象 再执行inser语句
<insert id="add" parameterType="com.itheima.pojo.CheckGroup"><selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">select LAST_INSERT_ID()</selectKey>insert into t_checkgroup(code, name, sex, helpCode, remark, attention)values (#{code}, #{name}, #{sex}, #{helpCode}, #{remark}, #{attention})</insert>
18. 分页插件
mybatis不带分页功能的 mysql中分页使用 limit 语句 不同的数据库实现的关键字也不同
PageHelper 第三方分页助手
导入jar包 pagehelper.jar jsqlparser.jar
在核心配置文件中集成分页助手
<plugins><plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin></plugins>
在测试类中使用分页功能
PageHelper.startPage(1,3);// PageHelper.startPage(第几页,每页显示多少个); 设置分页参数
18.1. Pageinfo 封装分页相关参数的功能类
- getTotal() 获取总条数
- getPages() 获取总页数
- getPageNum() 获取当前页
- getPageSize() 获取每页显示条数
- getPrePage() 获取上一页
- getNextPage() 获取下一页
- islsFiresPage() 获取是否是第一页
- islsLastPage() 获取是否是最后一页
PageInfo<Student> info =new PageInfo<>(list);int total = info.getTotal();
19. 多表操作
19.1. 一对一
<mapper namespace="1v1"><!--resultMap 配置字段和实体对象属性的映射关系id为唯一标识type为映射对象路径--><resultMap id="oneToOne" type="card"><!--id为主键标签 column为表中列名 property为对象属性名称result为其他列标签--><id column="cid" property="id"/><result column="number" property="number" /><!--association: 配置被包含对象的映射关系 对象内的对象property: 被包含对象的变量名 对象内的对象变量名是什么javaType:被包含对象的数据类型--><association property="prs" javaType="person"><id column="pid" property="id"></id><result column="name" property="name"/><result column="age" property="age"/></association></resultMap><!--resultMap 为多表操作映射--><select id="selectall" resultMap="oneToOne">select c.id cid,number,pid,name,age from card c,person p where c.pid=p.id;</select></mapper>
<resultMap>配置字段和实体对象属性的映射关系- id属性 唯一标识
- type属性 实体对象类型
<id>配置主键映射关系标签<result>配置非主键映射关系标签- column属性 表中字段名称
- property属性 实体对象变量名称
<association>配置被包含对象的映射关系标签- property属性 被包含对象的变量名
- javaType属性 被包含对象的数据类型
19.2. 一对多
<mapper><resultMap id="onetomany" type="classes"><id column="cid" property="id"/><result column="canem" property="name"/><!--collection: 配置被包含的集合对象映射关系property属性 被包含集合对象的变量名ofType属性 被包含集合对象元素的数据类型--><collection property="students" ofType="student"><id column="sid" property="id"/><result column="sname" property="name"/><result column="sage" property="age"/></collection></resultMap><select id="selectall" resultMap="onetomany">select c.id cid,c.name cname,s.id sid,s.name sname,s.age sage from classes c,student s where c.id=s.id</select></mapper>
<collection>配置被包含的集合对象映射关系- property属性 被包含集合对象的变量名
- ofType属性 被包含集合对象元素的数据类型
19.3. 多对多
<mapper><resultMap id="manytomany" type="sstdent"><id column="sid" property="id"/><result column="sname" property="name"/><result column="sage" property="age"/><collection property="coures" ofType="corse"><id column="cid" property="id"/><result column="cname" property="name"/></collection></resultMap><select id="selectall" resultMap="manytomany">select sc.sid,s.name sname,s.age sage,sc.cid,c.name cname from stdent s,course c,stu,_cr sc where sc.sid=s.id and sc.cid=c.id</select></mapper>
<collection> 配置被包含的集合对象映射关系
- property属性 被包含集合对象的变量名
- ofType属性 被包含集合对象元素的数据类型
20. 注解
- @Select(“查询的SQL语句”) 指定参数还是#{key}
- @Insert(“新增的SQL语句”) 如:@Insert(“inser into student value (#{id},#{age},#{name})”)
- @Update(“修改的SQL语句”)
- @Delete(“删除的SQL语句”)
通过注解形式的操作 不需要创建映射配置文件 映射配置内容 写在核心配置文件中
<mappers><!-- name为接口所在的包路径 可以指定类或者指定包下的所有类 --><package name="com.xxx.xxx.stdentmapper"/></mappers>
19. 多表操作
19.1. 一对一
@Select("select * fome card")@Results({@Result(column = "id" ,property = "id"),@Result(column = "number" , property = "number"),@Result(property = "p", // 被包含对象的变量名javaType = Person.class, // 被包含对象的实现数据类型类column = "pid", // 根据上面select查询出来表中的哪个字段来查询第二个表/*one = @one() 一对一写法select属性 指定调用哪个接口的哪个方法*/one = @One(select = "com.xxx.xxx接口.selectByid方法"))})List<Card> selectAll();//@one注解调用的接口方法@Select("select * from person where id=#{id}")Person selectByid(Integer id);
@Results 封装映射关系的父注解 Result[] vlue() 定义了Result数组
@Result 封装映射关系的子注解
- column属性 查询出的表中字段名称
- property属性 实体对象中的属性名称
- javaType属性 被包含对象的数据类型
one 属性 一对一查询
@One一对一查询注解
- select属性 指向要调用某个接口中的方法
19.2. 一对多
//一对多@Select("select * fome classes")@Results({@Result(column = "id" ,property = "id"),@Result(column = "number" , property = "number"),@Result(property = "students", // 被包含对象的变量名javaType = List.class, // 被包含对象的实现数据类型类column = "id", // 根据上面select查询出来表中的哪个字段来查询第二个表/* many = @Many() 一对多写法select属性 指定调用哪个接口的哪个方法*/many= @Many(select = "com.xxx.xxx接口.xxx方法"))})List<Classes> selectAll();//@one注解调用的接口方法@Select("select * from student where cid=#{cid}")List<Student> selectByid(Integer cid);
many属性 一对多查询
@Many一对多查询注解
- select属性 指向要调用某个接口中的方法
19.3. 多对多
//多对多@Select("select distinct s.id,s.name fome studebt s,stu_cr sc where sc.sid = s.id")@Results({@Result(column = "id" ,property = "id"),@Result(column = "number" , property = "number"),@Result(property = "students", // 被包含对象的变量名javaType = List.class, // 被包含对象的实现数据类型类column = "id", // 根据上面select查询出来表中的哪个字段来查询第二个表/* many = @Many() 一对多写法select属性 指定调用哪个接口的哪个方法*/many= @Many(select = "com.xxx.xxx接口.xxx方法"))})List<Student> selectAll();//@one注解调用的接口方法@Select("select c.id,c.name from stu_cr sc,course c where sc.cid=c.id and sc.sid=#{id}")List<Course> selectByid(Integer id);
many属性 一对多查询
@Many一对多查询注解
- select属性 指向要调用某个接口中的方法
21. SQL 构建

public static void main(String[] args) {System.out.println(getSelectall());//SELECT *//FROM student}public static String getSelectall(){return new SQL(){{SELECT("*");FROM("student");}}.toString();}
@SelectProvider(type = SQL构造的类.class , mehod = “要执行类中方法”) 查询
@InsertProvider((type = SQL构造的类.class , mehod = “要执行类中方法”) 新增
public static String getInsert(Student stu){return new SQL(){{INSERT_INTO("student");INTO_VALUES("#{id},#{age},#{name}");}}.toString();}
@UpdateProvider((type = SQL构造的类.class , mehod = “要执行类中方法”) 更新
@DeleteProvider((type = SQL构造的类.class , mehod = “要执行类中方法”) 删除
