核心配置文件
映射配置文件和接口的目录结构一致,映射文件中的名称空间namespace="接口的全限定名称"
映射文件中的标签的id和接口方法名一致
基本注解:
核心配置文件+接口
接口的方法上面使用这下面基本注解
@select @Delete
2.Mybatis原理
架构体系: 准备核心配置文件 mybatis-config.xml 要被解析 Resources就来读取配置文件内容 将配置文件内容--->每一个标签--->封装到一个类中,作为它的属性:Configuration类 加载映射器 Mappers --->里面配置的mapper的sql映射文件--->MapperRegister:Mapper注射器 //创建SqlSessionFactoreyBuidlder--->构建者,就是将资源输入流的内容,封装Configerarion类 //创建 创建SqlSession:执行对象:-->底层接口Executor执行器 PrepareStatement:预编译对象 getMapper --->Mapper代理 底层就是一个JDK动态代理,针对XXXMapper接口 产生代理对象(JDK动态代理前提基于接口实现) MapperProxy implements InvocationHandler
Mybatis核心配置文件中的其他配置
1.jdbc.propertise 从里面获取连接信息,配置到数据源中 2.Java实体类别名包扫描配置 在映射文件中,写的查询,添加,删除,修改,有返回值或有参数的--都可以使用别名 <typeAliases> <package name="com.qf.pojo"/> 3.映射文件的包扫描 mapper的别名包扫描 <package name="com.qf.mapper">
团队内部协作开发
正常开发过程中,组长创建组织,上传自己的私有仓库,将所有组织成员邀请为仓库成员 组长搭建项目,按模块划分--组长写登录模块,其他人写其他模块,先定义好接口---写上对应的映射文件 在开发分支上 开发完毕,合并自己本地主分支,从自己本地分支上提交本地库,推送到远程的主分支上 当前
今日内容
不想出现黄色块儿的话,去掉Mybatis映射文件的黄色提示块儿:
回退上一个版本
1.Mybatis中其他高级使用
1.1 注解@param参数绑定
Mybatis提供了一个注解@Param:参数绑定
StudentMapper
通过学生名称和地址获取学生 StudetnfindStudetnByNameAndAddress(Stringname,Stringaddress) 在映射文件中我们要写parameterType,现在不用写 //Param (将指定的参数绑定到这个注解中) StudetnfindStudetnByNameAndAddress(@Param("name")Stringname,@Param("addr")Stringaddress) 查的时候: <selectid="findStudetnByNameAndAddress" resultType="student"> select*fromstudentwherename=#{name} andaddress=#{addr} </select>
StudentMapper.xml
<!-- StudentfindStudentByNameAndAddress(@Param("name") Stringname, @Param("addr") Stringaddress 参数绑定的使用 --> <selectid="findStudentByNameAndAddress" resultType="student"> select*fromstudentwherename=#{name} and address=#{addr} </select>
注解本身是一个接口
ElementType指的是可以使用的范围
1.2 Mapper集合作为方法形参,参数为复杂类型
参数为复杂类型 Map
Map 就是实体<K,V> ,添加任何实体信息
map.put("name","刘桑")
map.put("birthday","日期")
StudentMapper.java
StudentfindStudentByNameAndBirthday(Mapvalues) ;
StudentMapper.xml
参数为复杂类型的Map集合 <selectid="findStudentByNameAndBirthday"resyltType="student"> select*fromstudentwherename=#{name} andbirthday=#{birthday} </select>
Test
//创建一个Map集合 Mapmap=newHashMap<>() ; //给映射文件中的参数进行赋值 map.put("name","刘桑") ; map.put("birthday","1996-12-10 00:00:00") ; Studentstudent=mapper.findStudentByNameAndBirthday(map) ;
2.Mybatis中连接池(自带的)--可以自定义或者以后使用druid德鲁伊
原理
连接池 特点:创建一些固定的可重用的连接对象,重复利用它 当某个连接对象被某个持有的线程使用完毕之后,然后归还到连接池中 线程要保证线程安全
1) 线程访问连接池
2) 线程使用连接池对象, 两个连接对象从连接池出来,连接池其他对象重新进行队列编号
3) 线程使用完毕,归还连接对象到连接池中
Mybatis原码: Mybatis 启用连接池启用 jndi pooled unpooled 这三个连接池
Mybatis-config 有一个 POOLED
PooledDataSourceFactory 工厂 来创建连接池 对象PooledDataSource
往下走 PooledDataSource 类
UnpooledDataSource 类
PoolState 类 连接池状态
启用Mybatis自带的连接池 查询所有学生,通过日志观察:
<dataSource type="org.apache.ibatis.datasource.pooled.PooledDataSourceFactory">
不启用Mybatis自带的连接池,查询所有学生,通过日志观察:
区别就在于最后是直接释放了连接对象,
当下一次再使用时,需要创建一个新的连接对象
<dataSource type="org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory">
使用德鲁伊的数据源,自定义一个类继承 PooledDataSourceFactory
publicclassMyDruidDataSourceFactoryextendsPooledDataSourceFactory{ //构造方法 publicMyDruidDataSourceFactory(){ //创建德鲁伊的数据源对象 this.dataSource=newDruidDataSource() ; } }
导入Druidjar包
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.13</version> </dependency>
调整Jdbc.properties的配置信息更改为druid的
jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/myee_2113 jdbc.username=root jdbc.password=123456 jdbc.maxActive=123456
调整Mybatis-config中的环境配置
<!--使用自己的连接池:自定义一个工厂类继承了 mybatis里面的PooledDataSourceFactory--> <dataSourcetype="com.qf.datasource.MyDruidDataSourceFactory"> <propertyname="driverClass"value="${jdbc.driverClassName}"/> <propertyname="url"value="${jdbc.url}"/> <propertyname="username"value="${jdbc.username}"/> <propertyname="password"value="${jdbc.password}"/> <!--最大激活数量--> <propertyname="maxActive"value="${jdbc.maxActive}"/> </dataSource>
2.1 Mybatis高级映射: resultMap
高级映射应用的场景:
1) 当实体类的属性名称 和 数据库表中的字段 不对应时 可以用到高级映射
private Integer sId ; private String sName ; private Integer stuAge ; private
此时select * from student
出现了10条null 值 ,因为字段不匹配
方式 1: 在查询的时候不使用* 而是给出具体的字段名称 别名和实体类属性名称一致即可
select s.id stuId, s.name stuName, s.age stuAge, s.address stuAdress, s.birthday stuBirthday from student
方式2 :Mybatis高级映射 : resultMap
首先在映射文件中定义resultMap,
然后在具体的增删改查,查询语句中,
将resultMap引入
resultMap里面就是可以将每一个字段和实体类的属性一一映射
StudentMapper.xml中 定义resultMap
id : resultMap它的标识id
type : 就是实体类的全限定名称/别名 (返回值类型)
<resultMap id="myMap" typr="student"> 配置主键字段: 表中主键字段 id 和 实体类属性id 一致 property:实体类的属性名称 id column:表中字段列的名称 主键id <id property="stuId" column="id"></id> 普通字段和实体类的其他属性名称一一对应 <result property="stuName" column="name"></result> ... </resultMap> 引入resultMap <select id="findAll" resultMap="maMap">
2) Mybatis多表查询
2.2 动态Sql
1) if
StudentMapper.java
通过一些条件来查询用户数据,可能是一个条件,或者是多个条件 List<Student> findStudentByCondition(Student student)
StudentMapper.xml
根据不同条件来查询学生列表数据 条件有一个或者多个,引入动态sql语句 <select id="findStudentByCondition" resultMap="myMap"> select * from student where //此时根据后面的条件进行判断,当这些属性不为null的时候才能查询 //Mybatis提供了常用的动态sql语句,if标签 //test属性:判断当前实体类属性是否满足条件,true还是false,true则执行 <if test="stuName != null"> name = #{stuName} </if> <if test="stuAddress != null"> and address = #{stuAddress} </if> </select>
Test
再优化
Mybatis 提供动态的where 标签
根据不同条件来查询学生列表数据 条件有一个或者多个,引入动态sql语句 <select id="findStudentByCondition" resultMap="myMap"> select * from student <where> <if test="stuName != null"> name = #{stuName} </if> <if test="stuAddress != null"> and address = #{stuAddress} </if> </where> </select>
Sql片段----封装复用重复的sql
动态的sql片段,将重复性的sql抽取出来,在其他sql中引入这个sql片段即可
<sql id="mySelectSql"> select * from student </sql> <select id="findStudentByCondition" resultMap="myMap"> 引入sql片段 refid:引入sql片段 <include refid="mySelectSql" >
for each
想把查询的结果遍历出来
用一下QueryVo
通过 vo实体里面的集合属性来查询学生列表
List<Student> findStudentByVO(QueryVo vo)
StudentMapper.xml中:
<select id="findStudentByVO" parameterType="queryvo" resuleMap="myMap"> 引入sql片段 <include refid="mySelectSql" /> <where> 使用foreach标签将里面的数据遍历出来 foreach标签里面的属性 collection:当前实体类中封装的集合属性名称 QueryVO中的ids open: 使用子查询 in(x,x,x) 表示以什么格式开始查询 现在以 "id in (" 为开头 separator:分割符号 现在以 , 隔开 close:以什么格式结束 以 ) 结束 item:循环遍历过程中的变量名称 foreach中间的内容 #{item里面指定的变量名称} <foreach collection="ids" open="id in(" separator="," close=")" item="id"> #{id} </where> </select>
Test
trim自定义
3.Mybatis的高级一对多,或者多对多的映射关系配置(多表之间的映射配置)
账户表和用户表之间 一个用户可以拥有多个账户:一对多 一个账户从属某个用户:一对一 角色表和用户表之间:多对多关系 有一个中间表 user_role 一个用户可以赋予多个角色 这个用户:项目经理:同时还是一个程序员 一个角色,包含多个用户
创建一个库
create database EE_2113_mybatis_practice ;
创建用户表
创建账户表
一个用户有多个账户 : 一对多关系 one to many
创建一个项目
下一个插件,User
Lombok 提供set/getXXX方法以及构造方法,将所有东西封装到@Data注解中
不写setget方法
UserMapper.java
List<User> findAll
不出现警告线
UserMapper
从账户角度考虑:
一个账户从属于某个用户
select
a.id aid, --账户编号
a.UID, --从属的用户编号
a.Money,
u.username,
u.address
from account a ,User u ;
这样查造成笛卡尔乘积
拿左外查
或
where a.uid = u.id
定义一个类 AccountUser 继承自Account实体类
4.servlet和Mybatis进行整合(应用操作上)
register.html ---> jQuery的Ajax方式
当用户输入用户名--->文本输入框失去焦点,触发事件-->控制器--->业务持久层:Mybatis
定义一个工具:MybatisUtils
之前的jdbcUtils-->创建connection
现在:创建SqlSession
最终目的-->就是要产生接口的代理对象--->调用接口中的数据访问接口(XXXMapper)的方法