MyBatis框架
来源:互联网 发布:java中offset什么意思 编辑:程序博客网 时间:2024/06/08 09:27
- MyBatis框架
- MyBatis框架引言
- 1-1 MyBatis框架的基本概念
- 1-2 MyBatis框架与JDBC对比
- 1-3 MyBatis框架的核心编程思路
- 第一个MyBatis程序的开发HelloWorld
- 2-1 环境搭建OpenSource
- 2-1-1 导入jar包
- 2-1-2 引入配置文件
- 2-1-2-1 log4jproperties可选
- 2-1-2-2 MyBatis-configxml
- 2-1-2-3 Mapper文件
- 2-1-3 初始化配置
- 2-1-3-1 补充MyBatis-config中的配置信息
- 2-2 MyBatis API
- 2-2-1 Resources
- 2-2-2 SqlSessionFactory
- 2-2-3 SqlSession
- 2-3 MyBatis 的开发步骤
- 2-1 环境搭建OpenSource
- 参数绑定
- 3-1 Mybaits代码中形参名与mapper文件中的的名字没有必然联系
- 3-2 Mapper文件中可以通过下标的形式代表接口中的形参
- 3-3 多参数形式的查询解决方案
- 3-3-1 可以通过下标的形式进行操作
- 3-3-2Param注解进行参数绑定建议
- 3-3-3 使用集合map进行传参早期
- MyBatis中CUD增删改
- 4-1 删除
- 4-2 修改
- 4-3 插入
- MyBatisUtil工具类的封装
- ResultMap结果映射结果对应关系
- 6-1 定义ResultMap
- 6-2 使用ResultMap
- MyBatis框架进行多表操作
- 7-1 实体之间的关系分类
- 7-2 MyBatis中如何处理管理关系
- 7-2-1 entity处理
- 7-2-2 表
- 7-2-3 DAO接口
- 7-2-4 Mapper文件处理
- 关联关系的实战开发
- 8-1 11关联关系
- 8-2 1关联关系重点
- 8-3 关联关系了解
- 8-4 关联关系总结
- 8-4-1 Entity 关系属性
- 8-4-2 Table外键
- 8-4-3 Mapper文件
- 动态SQL
- 9-1 Sql片段
- 9-2 where语句的动态Sql
- 9-3 修改操作的动态Sql
- 9-4 批量操作批量删除批量查询
- MyBatis的缓存Cache
- 10-1 缓存简述
- 10-2 缓存开启步骤
- 10-2-1 开启MyBatis的全局缓存
- 10-2-2 设置需要存储在缓存中的数据
- 10-2-3 放置在缓存中的实体对象都需要实现serializable接口
参考网站
mybatis中文文档
mybatis源码中文注释
**
MyBatis框架
**
1 MyBatis框架引言
1-1 MyBatis框架的基本概念
MyBatis是一个持久层框架,完成对数据库的访问(CRUD)
1-2 MyBatis框架与JDBC对比
jdbc访问和操作数据库存在的问题:
i.大量的代码冗余
ii.手工处理ORM(麻烦)
iii.没有对数据库进行优化(Cache)
解决JDBC访问和操作数据库存在 的问题,是对原有JDBC技术的封装。
1-3 MyBatis框架的核心编程思路
在原来的JDBC三层模型汇总,先进行书写DAO接口后实现DAO实现类,MyBatis的解决思路是使用mapper xml类型文件代替DAO实现类的功能。
2 第一个MyBatis程序的开发(HelloWorld)
2-1 环境搭建(OpenSource)
i.Ibatis是MyBatis的前身,apache组织
ii.IBatis从3.0开始改名为MyBatis google code
iii.MyBatis 属于GitHub
2-1-1 导入jar包
- MyBatis的核心jar包
- 第三方依赖jar
- 相关数据库的驱动jar
2-1-2 引入配置文件
2-1-2-1 log4j.properties[可选]
log4日志文件放置在src目录下
2-1-2-2 MyBatis-config.xml
建议放置在src目录下
配置的是MyBatis运行的相关参数
2-1-2-3 Mapper文件
实现DAO接口
位置建议xxxDao接口放在同一目录下
2-1-3 初始化配置
MyBatis-config.xml配置
oracle数据库配置
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "mybatis-3-config.dtd" ><configuration> <environments default="oracle"> <environment id="oracle"> <transactionManager type="JDBC"></transactionManager> <dataSource type="POOLED"> <property name="driver" value="oracle.jdbc.OracleDriver" /> <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe" /> <property name="username" value="hr" /> <property name="password" value="hr" /> </dataSource> </environment> </environments> <mappers> <mapper resource="com/baizhi/dao/UserMapper.xml" /> </mappers></configuration>
< environments default=”oracle”> — 默认环境
< environment id=”oracle”> — 环境的唯一标识
< transactionManager type=”JDBC”> — 采用JDBC的事务控制
< dataSource type=”POOLED”> — MyBatis原生的连接池
< mapper resource=”com/baizhi/dao/UserMapper.xml” /> — 注册Mapper文件
2-1-3-1 补充MyBatis-config中的配置信息
别名TypeAlias
实体的权限定名
<typeAlias> <typeAlias type="com.hibiscidai.entity.User" alias="A" /></typeAlias>
<select id="selectByNameAndPassword" resultType="A"> select * from t_user where username=#{username} and password=#{passowrd}</select>
配置内容参数化
问题:在mybatis-config文件中有经常需要修改的字符串相关(数据库相关)
解决方案:把在mybatis-config配置文件中经常需要修改的字符串信息提取到小配置文件中
i.读取小配置文件
<!-- 读取小配置文件 --><properties resource="jdbc.properties"></properties>
resource=”jdbc.properties”——小配置文件存放路径
ii.${key}获取小配置文件中对应的值
<dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/ <property name="password" value="${password}"/></dataSource>
driver = oracle.jdbc.OracleDriverurl = jdbc:oracle:thin:@localhost:1521:xeusername = hrpassword = hr
2-2 MyBatis API
三个重要的类
2-2-1 Resources
读取mybaitis-fonfig配置文件,打开IO
2-2-2 SqlSessionFactory
通过SqlSessionFactory这个工厂创建SqlSession对象
2-2-3 SqlSession
作用:
i.根据程序员书写的Mapper文件,自动创建mapper文件对应的java类(DAO接口的实现类)
ii.SqlSession内部封装了Connection对象
iii.SqlSession控制事务
SqlSession.commit——Connection.commit
SqlSession.rollback——Connection.rollback
注意:实战开发中,增删改需要控制事务 查询不需要控制事务
2-3 MyBatis 的开发步骤
i.建表
ii.写实体
iii.DAO接口
iiii.Mapper文件做DAO的实现
public User selectByID(Integer id);
<select id="selectByID" parameterType="int" resultType="com.hibiscidai.entity.User"> select * from t_user where id=#{id}</select>
User — resultType=”com.hibiscidai.entity.User”
selectByID — id=”selectByID”
Integer id — parameterType=”int”
v.Mapper文件的注册
<mappers> <mapper resource = "com/hibiscidai/dao/UserMapper.xml" /></mappers>
vi.MyBatis核心API测试
@Testpublic void testMybatis() throws Exception { // 读取mybatis-config配置文件 InputStream stream = Resources.getResourceAsStream("mybatis-config.xml"); // 创建SqlSessionFactory对象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(stream); // 创建SqlSession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); // 创建DAO的实现类 UserDAO userDAO = sqlSession.getMapper(UserDAO.class); // 调用DAO中相关方法 User user = userDAO.selectByID(1); System.out.println(user);}
3 参数绑定
3-1 Mybaits代码中形参名与mapper文件中的#{}的名字没有必然联系
public User selectByID(Integer id);
<select id="selectByID" parameterType="int" resultType="com.hibiscidai.entity.User"> select * from t_user where id=#{hibiscidai}</select>
Integer id–hibiscidai
3-2 Mapper文件中可以通过下标的形式,代表接口中的形参
public User selectByID(Integer id);
<select id="selectByID" parameterType="int" resultType="com.hibiscidai.entity.User"> select * from t_user where id=#{0}</select>
Integer id–0
下标默认从0开始
3-3 多参数形式的查询解决方案
注意:在mybatis进行查询时,paramterType是可以省略的,不能随意指定#{},名字
3-3-1 可以通过下标的形式进行操作
public User selectByNameAndPassword(String username, String password);
<select id="selectByNameAndPassword" resultTpe="com.baizhi.entity.User"> select * from t_user where username=#{0} and password=#{1}</select>
3-3-2@Param注解进行参数绑定[建议]
public User selectByNameAndPassword(@Param("u")String username, @Param("p") String password);
<select id="selectByNameAndPassword" resultType="com.hibiscidai.entuty.User"> select * from t_user where username=#{u} and password=#{p}</select>
3-3-3 使用集合(map)进行传参[早期]
Map<String, String> map = new HashMap<String, String>();map.put("username", "hibiscidai");map.put("passowrd", "123456");User user = userDAO.selectByNameAndPassword(map);
select * from t_user where username=#{username} and password=#{passowrd}
public User selectByNameAndPassword(Map<String, String> params);
4 MyBatis中CUD(增删改)
注意:在MyBatis应用的过程中,处理CUD时,必须要手工控制事务,否则操作不执行
sqlSession.commit();sqlSession.rollback();
4-1 删除
public void delete(Integer id);
<delete id="delete"> delete from t_user where id=#{id}</delete>
4-2 修改
public void update(User user);
User { id username password}
<update id="update"> update t_user set username=#{username}, password=#{password} where id=#{id}</update>
4-3 插入
Sequence序列进行主键插入[Oracle]
public void insert(User user);
User { id = null username = hibiscidai passowrd = 123456}
<insert id="insert"> <selectKey keyProperty="id" order="BEFORE" resultType="int"> select z.newxval from dual </selectKey> inset int t_user (id, username, password) values(#{id}, #{usename}, #{password})</insert>
5 MyBatisUtil工具类的封装
对于MyBatis三种类对象的分析
Resources类
特点:读取MyBatis-config配置文件 IO
建议:一次性通过IO读取所有的数据
SqlSessionFactory类
特点:创建SqlSession 重量级的资源 内存占用多 功能多
建议:每一个应用只创建一个 线程安全
SqlSession类
特点:清零及资源 不能被多线程共享
1.创建DAO接口的实现类(动态代理设计思想 动态字节码技术)
2.SqlSession内部封装Connnection 一个SqlSession对应一个Connection
3.事务控制
SqlSession.commit
SqlSession.rollback
import java.io.IOException;import java.io.InputStream;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;public class mybatisutils { public static SqlSessionFactory sqlSessionFactory; public static ThreadLocal<SqlSession> tl = new ThreadLocal<SqlSession>(); /* 静态代码块加载基础信息 */ static { InputStream stream = null; try { // 读取mybatis-config配置文件 stream = Resources.getResourceAsStream("mybatis-config.xml"); // 创建SqlSessionFactory对象 sqlSessionFactory = new SqlSessionFactoryBuilder().build(stream); } catch (IOException e) { // TODO: handle exception e.printStackTrace(); throw new RuntimeException("读取配置文件失败"); } finally { // 关闭流 try { stream.close(); } catch (Exception e2) { // TODO: handle exception e2.printStackTrace(); } } } /* 获取SqlSession对象 */ public static SqlSession opSqlSession() { SqlSession sqlSession = tl.get(); // 非空判断 if (null == sqlSession) { sqlSession = sqlSessionFactory.openSession(); tl.set(sqlSession); } return sqlSession; } /* 关闭SqlSession对象 */ public static void closeSqlSession() { // 获取SqlSession SqlSession sqlSession = opSqlSession(); sqlSession.close(); tl.remove(); } /* 事务提交 */ public static void commit() { SqlSession sqlSession = opSqlSession(); sqlSession.commit(); closeSqlSession(); } /* 事务回滚 */ public static void rollback() { SqlSession sqlSession = opSqlSession(); sqlSession.rollback(); closeSqlSession(); } /* 获取DAO实现 */ public static Object getMapper(Class clazz) { SqlSession sqlSession = opSqlSession(); return sqlSession.getMapper(clazz); }}
6 ResultMap(结果映射,结果对应关系)
作用:解决了实体类与数据库中的表不匹配
6-1 定义ResultMap
<resultMap type="Customer" id="CustomerResultMap"> <id property="id" column="t_id" /> <result property="username" column="t_username" /> <result property="password" column="t_password" /></resultMap>
< id >
标签表示对主键的处理 < result >
标签表示对费主键的处理
property
– 代表实体的名字 column
– 代表数据库中的列名
6-2 使用ResultMap
<resultMap type="Customer" id="CustomerResultMap"> <id property="id" column="t_id" /> <result property="username" column="t_username" /> <result property="password" column="t_password" /></resultMap><select id="selectByID" resultType="CustomerResultMap" > select * from t_customer where t_id=#{id}</select>
注意:如果在开发中,只解决列名不一致的问题,有简化的方式,起别名
<typeAliases> <typeAlias type="com.baizhi.entity.Customer" alias="Customer"/></typeAliases><select id="selectByID" resultType="Customer" > select t_id as id,t_username as username,t_password as password from t_customer where t_id=#{id}</select>
7 MyBatis框架进行多表操作
7-1 实体之间的关系分类
i.实体之间有关联关系(有 从属 has a)【重点】
a) 1 : 1
b) 1 : *
c) * : *
ii.实体之间继承关系(is a)
7-2 MyBatis中如何处理管理关系
7-2-1 entity处理
关系属性:把关系另一方作为本方属性进行存储
关系的方向性:
单向关系:只能从关系其中一方 找到关系的另一方
双向关系:从关系的双方都可以找到关系的另一方
级联查询:
PersonDAO.query(id) —> Person(passport)
PassportDAO.query(id) —> Passport(person)
看似是单表处理 实际完成多张表的操作
7-2-2 表
表中如何简历关联关系:外键
建外键规则:
一对一 随便建
一对多 建在多的一方
多对多 建在第三张表中
表中关系的方向行:天生的双向关系
注意
1.父没有外键 先插入
2.子表没有外键 先删除
7-2-3 DAO接口
有几个DAO, 对应写几个DAO
7-2-4 Mapper文件处理
自定义结果映射
8 关联关系的实战开发
8-1 1:1关联关系
<resultMap type="Person" id="PersonResultMap"> <id column="pid" property="id"/> <result column="pusername" property="username"/> <result column="page" property="age"/> <association property="passport" javaType="Passport"> <id column="sid" property="id"/> <result column="sserial" property="serial"/> <result column="splace" property="place"/> </association> </resultMap>
8-2 1:*关联关系(重点)
例:
部门(Department)与职员(Employee)关系
Employee id username age salary department
Department id departmentname departmentnumber List<Employee> employees
t_employee
t_department
一对多关联关系,集合作为关系属性,需要对集合进行初始化操作。
8-3 * : *关联关系(了解)
例:
学生(Student)与课程(Course)关系
Student id studentnumber studentname age List<Course>
Course id coursename score List<Student>
t_student | 学生表
t_sc | 多对多映射表
t_course | 课程表
8-4 关联关系总结
8-4-1 Entity 关系属性
a)一个对象b)集合 进行初始化
8-4-2 Table外键
一对一 随便建一对多 建在多的一方多对多 建在第三张表中
8-4-3 Mapper文件
ResultMap
一个对象
<association property="" javaType="">
多个对象
<collection property="" oftype="">
9 动态SQL
作用:简化mapper文件的配置
9-1 Sql片段
<sql id="selectAll"> select * from t_teacher</sql><select id="selectByID" resutlType="Teacher"> <include refid="selectAll" />where id=#{id}</select><select id="selectByName" resultType="Teacher"> <include refid="selectAll" />where teachername=#{name}</select>
9-2 where语句的动态Sql
作用:同样的表,根据不同列的内容查询,通过where的动态sql
TeacherDAO文件重构
未使用where
//根据教师的ID查询该教师public Teacher selectByID(Integer id);//根据教师的姓名查询该教师public Teacher selectByName(String name);//根据教师的序列号查询public Teacher selectByNumber(String number);//根据教师的id及姓名查询public Teacher selectByIDAndName(@Param("id")Integer ID,@Param("name")String name);
使用where后
public Teacher selectByWhere(Integer id, String name, String number)
Mapper文件重构
未使用where
<sql id="selectAll"> select * from t_teacher</sql><select id="selectByID" resutlType="Teacher"> <include refid="selectAll" />where id=#{id}</select><select id="selectByName" resultType="Teacher"> <include refid="selectAll" />where teachername=#{name}</select><select id="selectByNumber" resultType="Teacher"> <include refid="selectAll" />where teachernumber=#{number}</select><select id="selectByIDAndName" resultType="Teacher"> <include refid="selectAll" />where id=#{id} and teachername=#{name}</select>
使用where后
<sql id="selectAll"> select * from t_teacher</sql><select id="selectByWhere" resultType="Teacher"> <include refid="selectAll" /> <where> <if test="id!=null"> id=#{id} </if> <if test="name!=null"> and name=#{name} </if> <if test="number!=null"> and number=#{number} </if> select * from t_teacher where id=#{id} select * from t_teacher where name=#{name} select * from t_teacher where number=#{number} select * from t_teacher where id=#{id} and name=#{name} </where></select>
xml逻辑映射:
name=null, number=null where id=#{id}id=null, number=null where name=#{name}id=null, name=null where number=#{number}number=null where id=#{id} and number=#{number}
<select id="selectByDynamic" resultType="Teacher"> <include refid="selectAll" /> <where> <if test="id!=null"> id=#{id} </if> <if test="teachername!=null"> and teachername=#{teachername} </if> <if test="teachernumber!=null"> and teachernumber=#{teahcernumber} </if> </where>
注意:用where动态sql时候,多参数做参数绑定时,要与数据库中的列名保持一致。
如果起始条件为null则忽略and号
新的写法:
<trim prefix="where" prefixOverrides="and/or"> <if test="id!=null"> id=#{id} </if> <if test="teachername!=null"> and teachername=#{teachername} </if> <if test="teachernumber!=null"> and teachernumber=#{teachernumber} </if></trim>
prefix
忽略前缀 prefixOverrides
忽略前缀and或者or
9-3 修改操作的动态Sql
<update id="updateTeacher"> update t_teacher <set> <if test="teachername!=null"> teachername=#{teachername}, </if> <if test="teachernumber!=null"> teachernumber=#{teachernumber}, </if> <if test="age!=null"> age=#{age} </if> </set> where id=#{id}</update>
新的写法
<trim prefix="set" suffixOverrides=","> <if test="teachername!=null"> teachername=#{teachername}, </if> <if test="teachernumber!=null"> teachernumber#={teachernumber}, </if> <if test="age!=null"> age=#{age} </if></trim>where id=#{id}
9-4 批量操作(批量删除,批量查询)
<select id="selectByIDs" resyltType="Teacher"> select * from t_teacher where id in <foreach collection="array" open="(" items="ids" separator="," close=")"> #{ids} </froeach></select>
select * from t_teacher where id in<foreach collection="list" open="(" item="ids" separator=","close=")"></foreach>
如果参数是list集合 collection属性值设置为list
10 MyBatis的缓存(Cache)
10-1 缓存简述
作用:
在应用程序与数据库之间建立内存缓冲,存储用户曾经查询过的数据
好处:
1.减少与数据库之间的频繁通信
2.内存中随机读写效率高于硬盘
问题:
1.内存造价高,内存物理上线不大 无法缓存海量数据
2.数据安全性差
原则:
缓存中存储的数据一定是经常需要查询的数据,而且不是经常需要修改的数据
10-2 缓存开启步骤
10-2-1 开启MyBatis的全局缓存
Mybatis-config.xml配置
<!-- 激活全局缓存 --><settings> <setting name="cacheEnabled" value="true" /></setting>
10-2-2 设置需要存储在缓存中的数据
<!-- cache标签的作用:本mapper文件中的所有有关查询的操作都会放入mybatis的缓存中 --><cache></cache><select id="selectByID" resultType="Person"> select * from t_person where id=#{id}</select>
注意实体类起别名
10-2-3 放置在缓存中的实体对象都需要实现serializable接口
public class Person implements Serializable { private Integer id; private String username; private String password; private Integer age; public Integer getId() {} ...}
序列化目的:唤出策略(用少的数据写入硬盘中)
注意:
只有session关闭时,MyBatis才会把数据存储在缓存中
事务提交时(CUD),MyBatis会自动清空缓存
建议:
查询方法不需要控制,但是一定要关闭SQLsession
CUD必须要控制事务
单表查询建议采用MyBatis缓存
第三方缓存:
eacache,redis,memcache
- mybatis框架
- MyBatis框架
- Mybatis框架
- Mybatis框架
- Mybatis框架
- MyBatis框架
- MyBatis框架
- Mybatis框架
- MyBatis框架
- Mybatis框架
- myBatis框架
- mybatis框架
- myBatis框架
- MyBatis框架
- MyBatis框架
- Mybatis框架
- 框架:Mybatis
- MyBatis框架
- NOIP2017普及复赛 (~~题解)
- 单片机编程规范,模块化编程
- Android 自定义Camera全屏拍照,支持前后摄像头
- 内联框架跳转页面
- spark学习-32-SparkEnv的构造步骤
- MyBatis框架
- PythonStock(12):使用python,pandas进行股票分析
- Java学习——StringBuffer和StringBuilder类
- HDU1970 John(经典尼姆博奕)
- JS时间格式化
- 16秋计算机JAVA第五节课作业
- Linux 企业运维人员最常用 150 个命令汇总! 收藏了!
- 从头梳理 Java 的诞生,语言特点-阅读笔记
- isset(), empty()和is_null()的区别