使用dao开发有两种开发方式,一种是使用普通的接口和接口实现类来进行开发
另一种开发方式是使用mapper代理的开发的方式(直接使用接口)
1.sqlSession的使用范围
1.1.sessionFacthaioryBuidler
SessionFactoryBuidler创建回话工厂sessionFactory
把sessionFactoryBuidler当成一个工具类即可,不需要进行单列模式设计。也
没有进行和spring的整合开发,所以说现在我们还不需要进行单列的设置。直接开发一个工具类,创建SessionFactory的时候直接进行new一个对象即可。
1.2.sqlSessionFactory
sqlSessionFactory生产sqlSession回话,使用单列模式进行创建sqlSessionFactory(工厂一旦创建,只创建一个实例),将mybatis和spring进行整合后使用单列模式进行管理
1.3.sqlSession
sqlSession是面向用户的一个回话接口
sqlSession提供很多操作数据库的方法:selectOne(查询单个对象),selectList(返回单个或者多个对象)
sqlSession是线程不安全的,在sqlSession实现类中除了有查询数据库中的方法外还有数据域属性。
sqlSession最好是在方法内部使用。
2.传统的dao的开发方式
2.1.思路
程序员需要编写dao接口和dao接口实现类
在dao实现类里面进行注入sqlSessionFactory,然后通过sqlSessionFactory创建sqlSession
2.2.dao接口
2.3.dao的实现类
public class UserDaoImpl implements UserDao {
//给dao层注入SessionFactory对象
//使用构造方法进行注入
public SqlSessionFactory sessionFactory;
public UserDaoImpl(SqlSessionFactory sessionFactory){
this.sessionFactory=sessionFactory;
}
public User findUserbyId(int id) {
//获取sqlSession
SqlSession sqlSession = sessionFactory.openSession();
//根据ID进行查询
User user = sqlSession.selectOne("test.selectUserByID", 30);
return user;
}
public List<User> findUserByUsername(String username) {
//获取Session
SqlSession sqlSession = sessionFactory.openSession();
//使用用户名进行模拟查询
List<User> list = sqlSession.selectList("test.selectUserByUsername", username);
return list;
}
public void insertUser(User user) {
SqlSession sqlSession = sessionFactory.openSession();
sqlSession.insert("test.insertUser", user);
}
public void deleteUserById(int id) {
SqlSession sqlSession = sessionFactory.openSession();
sqlSession.delete("test.deleteUserByID", id);
}
}
测试代码
2.5.原始dao总结
1.dao接口中存在着大量的模版方法,能不能提取出来,大量减轻程序员的压力
2.实现类进行操作数据库时对statement的ID进行硬编码了。
3.sqlSession直接进行设置参数,由于sqlsession使用的泛型,设置参数类型不会报错,这样不利于开发。
3.代理Mapper开发模式
程序员只需要编写dao接口代码,不需要编写实现类代码。大大减轻了程序员的压力。
实现类代码是放在配置文件中完成的。
3.1.思路
程序员还需要开发mapper.xml文件。
程序员编写mapper接口需要遵循一些开发规范。Mybatis会自动生成mapper接口实现类代理类。
3.2.开发规范
3.2.1.namespace的地址和mapper.xml的地址相同
Namespace在这里具有特殊的含义:必须是接口Mapper的接口全路径
3.2.2.dao接口中的方法必须和statement的Id必须一致
3.2.3.参数类型匹配
Mapper接口中的方法输入参数必须和对应的Mapper.xml中的parameterType中的参数匹配
3.2.4.返回值类型匹配
Mapper接口返回值类型必须和对应的mapper.xml中resultType输出类型匹配。
3.2.5.总结
采用代理模式进行开发:更方便,更快捷。
底层会自动调用:selectOne() selectList()
3.3.测试开发
3.3.1.映射文件
3.3.2.测试代码
3.4.总结
3.4.1.底层调用原理
Mapper动态代理方式底层根据返回值类型进行判断调用那个方法:
如果是返回单个对象就调用selectOne
如果是返回集合就调用selectList
3.4.2.mapper接口中参数只能是一个
Mapper接口中的参数只能是一个是否影响系统开发系统维护:
注意:dao层代码是被业务层公用的,即使是dao层代码参数只能是一个
业务层包装成不同类型pojo都可以满足不同业务需求。
持久层方法参数可以是map,基本类型,自定义对象,包装类型.
4.sqlMapConfig.xml
4.1.配置内容
SqlMapConfig.xml中配置的内容和顺序如下:
properties(属性)
settings(全局配置参数)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mappers(映射器)
4.2.properties属性文件
sqlMapConfig.xml文件可以引用外部资源文件:
注意:mybatis按照如下的顺序来加载属性:
- 在properties中定义的属性首先被读取
- 然后会读取properties中的resource和url资源
4.3.settings配置
mybatis框架在运行时可以调整一些运行参数。
比如:开启二级缓存、开启延迟加载
全局参数将会影响mybatis的运行行为。
4.4.typeAliases(别名)
在sql的xml文件中有很多的statement,statement需要指定parameterType输入参数类型和resultType输出结果类型
如果在开发时每次都写如全路径,不方便开发,此时就可以给parameterType和resultType定义别名
4.4.1.mybatis默认支持别名
别名 | 映射的类型 |
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
4.4.2.自定义别名
4.4.2.1.单个别名定义
引用别名
测试
4.4.2.2.批量定义别名
4.6.映射配置
4.6.1.通过resource加载单个配置文件
4.6.2.url加载绝对路径映射文件
使用完全限定路径
如:<mapper url="file:///D:\workspace_spingmvc\mybatis01\config\sqlmap\User.xml" />
4.6.3.接口class加载单个配置文件
根据以上要求:接口和配置文件必须在同一个目录
或者:
4.6.4.package批量加载Mapper文件
5.输入映射(parameterType)
通过parameterType指定输入参数类型,参数类型可以是基本类型,pojo,map类型
5.1.传递pojo包装类对象
5.1.1.需求
需求:完成用户的综合信息查询,输入参数比较复杂。(包含用户信息和其他信息)
5.1.2.定义包装类型pojo
注意:我们为什么不直接使用User来进行封装参数呢?
这是因为我们可以在隔离类里面进行封装很多参数,并且我们还有一些其他和业务不相关的查询条件。我们都可以定义在custom中。
在开发中和复杂查询条件也可直接封装在Javabean中,这样叫做非持久化属。
还有一种就是我们进行隔离开发,在定义一个公共封装属性的类。
5.1.3.mapper.xml文件
查询条件有很多,所以封装成一个类,封装类里面的属性可以含有多个pojo
5.1.4.mapper接口代码
5.1.5.测试代码
5.2.传递Map
5.2.1.映射文件
5.2.2.接口代码
5.2.3.测试代码
6.输出映射(resultType|resultMap)
使用resultType进行查询结果映射,只要数据库列名和javabean的属性相同就可以映射成功
如果不相同:resultMap进行映射
如果查询出来对象的列名和javabean的属性全部不一致,不会创建javabean对象。
如果查询结果中仅有一个列名和属性一致,javabean对象就会被创建。
6.1.resultType
6.1.1.输出简单类型
6.1.1.1.需求
查询用户综合信息总记录数,和用户列表就可以实现分页
6.1.1.2.映射文件
6.1.1.3.测试代码
总结:输出结果是简单类型,可以使用简单类型进行映射
6.1.2.输出pojo
无论resultType返回结果是单个对象还是List集合对象,resultType返回类型都是一样的。
但是在代码中需要指定返回值结果类型。
尤其是在接口代理中:mybatis是根据返回值类型进行判断调用selectOne还是selectList
6.1.2.1.输出pojo对象
6.1.2.2.输出pojo集合
6.2.resultMap
mybatis使用resultMap完成高级映射
使用方法:如果mybatis查询结果列名和Javabean属性不一致,通过resultMap把javabean属性和数据库的列名进行关系映射。
column对应的是列名,property对应的是属性名
6.2.1.映射文件
6.2.2.输出类型(resultMap)
使用resultMap作为输出结果集类型:
如果不在同一个Mapper文件中,需要指明包名。
6.2.3.接口代码
6.2.4.测试代码
6.3.总结
使用resultType进行映射:pojo中的属性必须和查询的类名相同
使用resultMap进行映射:pojo中的属性和查询的类名可以相同也可以不相同
.动态sql(掌握)
7.1.什么是动态sql
Mybatis对sql进行灵活操作,可以通过mybatis语法的判断对sql进行灵活封装,拼接
7.2.需求
用户信息综合查询列表和用户信息查询总记录使用动态sql进行查询
对查询条件进行判断:
如果值为空就不能进行sql的拼接
mybatis自带条件筛选where标签,条件满足判断if标签
7.3.映射文件
7.4.接口代码
7.5.测试代码
7.6.sql片段
7.6.1.需求
将上面的动态sql判断代码进行抽取,组成一个sql片段,其他的statement可以引用这个片段,方便程序员开发。
7.6.2.定义sql片段
7.6.3.引用sql片段
7.7.foreach
向mybatis传递数组,或者List集合使用foreach就可以解析
7.7.1.需求
在用户综合信息查询时使用多个ID进行查询:
SELECT * FROM USER WHERE id=1 OR id=10 OR id=16
SELECT * FROM USER WHERE id IN(1,10,16)
单独传递集合和数组
7.7.2.输入参数中定义集合List<Integer>
7.7.3.映射文件(修改)
WHERE id=1 OR id=10 OR id=16
在查询条件中,查询条件定义成一个sql片段,需要修改sql片段。
7.7.4.测试代码
7.7.5.另一个IN(…)实现