SqlSession范围:
1、SqlSessionFactoryBuilder:通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory。
将SqlSessionFactory当成一个工具类使用即可,不需要使用单例管理SqlSessionFactoryBuilder,在需要创建SqlSessionFactory时,只需要new一次SqlSessionFactoryBuilder即可。
2、SqlSessionFactory:通过SqlSessionFactory创建SqlSession,使用单例模式管理sqlSessionFactory。在Mybatis和spring整合后,使用单例模式管理SqlSessionFactory。
3、SqlSession:
SqlSession是一个面向用户的接口。它提供了很多的操作数据库方法。
SqlSession是线程不安全的,在SqlSession实现类中除了有接口中的方法,还有数据域属性。
SqlSession最佳应用场合在方法体内。定义成局部变量使用。
原始开发方式:
程序需要编写dao接口和dao实现类。在dao的实现类中需要注入SqlSessionFactory,在方法体内通过SqlSessionFactory创建SqlSession。
public class TestDaoImpl implements TestDao { //通过构造函数方法注入SqlSessionFactory private SqlSessionFactory sqlSessionFactory; public TestDaoImpl(SqlSessionFactory sqlSessionFactory){ this.sqlSessionFactory=sqlSessionFactory; } public User findUserById(int id) throws Exception{ SqlSession sqlSession=sqlSessionFactory.openSession(); User user=sqlSession.selectOne("test.findUserById",id); sqlSession.close(); return user; } public List<User> findUserByName(String username) throws Exception{ SqlSession sqlSession=sqlSessionFactory.openSession(); List<User> list = sqlSession.selectList("test.findUserByName",username); sqlSession.close(); return list; } ...... }
由上述实例可发现原始开发方式存在的问题:
1、dao接口实现类方法中存在大量模板方法。若将这些代码提取,将大大降低工作量。
2、调用SqlSession方法时将statement的id实施了硬编码。
3、调用sqlSession方法时传入的变量,由于sqlSession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,所以不利于开发。
代理开发方式:
1、配置mapper.xml映射文件。同时需要在SqlMapConfig.xml中加载UserMapper.xml。
2、编写mapper接口,需要遵循的一些开发规范,mybatis可以自动生成mapper接口实现类代理对象
开发规范:
》在mapper.xml中namespace的属性值为mapper接口地址。
<?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"> <!-- namespace:属性值指定mapper接口的地址 --> <mapper namespace="cn.ccir.mybatis.entity.UserMapper"> </mapper>
》mapper接口中的方法名和mapper.xml中statement的id一致。
》mapper接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致。
》mapper接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致。
public interface UserMapper{ public User findUserById(int id) thorws Exception; public List<User> findUserByName(String name) throws Exception; } public class UserMapperTest{ private SqlSessionFactory sqlSessionFactory; //指定测试方法前执行。 @Before public void setUp() throws Exception{ String resource="SqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsString(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } public void testFindUserById(){ SqlSession sqlSession = sqlSessionFactory.openSession(); //创建UserMapper对象,Mybatis自动生成mapper代理对象。 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = userMapper.findUserById(1); } }
mapper接口方法参数只能有一个参数。在系统框架中,dao层的代码是被业务层公用的。即使mapper接口只有一个参数,也可以使用包装类型的pojo来满足不同的业务方法的需求。
注:持久层方法的参数可以包装类型map,但service方法中不建议使用包装类型。因为不利于业务层的扩展。
Mybatis配置文件SqlMapConfig.xml:
Mybatis的全局配置文件,配置内容如下:
properties:属性。
Mybatis将按照下面的顺序来加载属性:
1、在properties元素体内定义的属性首先被读取。
2、然后读取properties元素中resource/url加载的属性,它会覆盖已读取的同名属性。
3、最后读取parameterType传递的属性,它会覆盖已读取的同名属性。
建议:
不要在properties元素体内添加任何属性值,只将属性值定义在properties文件中。在properties文件中定义属性名要有一定的特殊性。
settings:全局参数配置。
Mybatis框架在运行时可以调整一些运行参数。如:开启二级缓存、开启延迟加载等。全局参数将会影响Mybatis的运行行为。
typeAliases:类型别名。
如:在mapper.xml中,定义很多的statement,statement需要parameterType指定输入参数的类型,需要resultType指定输出结果的映射类型。
若在指定类型时输入类型全路径,不方便进行开发,可以针对parameterType或resultType指定的类型定义一些别名,在mapper.xml中通过别名定义,方便开发。
Mybatis有一些默认的别名(https://www.cnblogs.com/zltao/p/10546214.html),而pojo的类型定义别名则需要定义别名:
<!-- 定义别名 --> <typeAliases> <!-- 针对单个别名定义 --> <typeAlias type="cn.ccir.mybatis.entity.User" alias="user"> <!-- 批量别名定义 指定包名,mybatis自动扫描包中的类,自动定义别名,别名就是类型 --> <package name="cn.ccir.mybatis.entity"/> </typeAliases>
typeHandlers:类型处理器。
Mybatis中通过typeHandlers完成jdbc类型和java类型的转换。
Mybatis默认支持的类型处理器:https://www.cnblogs.com/zltao/p/10546288.html
通常情况下,mybatis提供的类型处理器已经满足日常需要,不需要自定义。
objectFactory:对象工厂
pluglns:插件
environments:环境集合属性对象
> environment:环境子属性对象
> transactionManager:事务管理
> dataSource:数据源
mappers:映射配置
<mappers> <!-- 一次加载一个映射文件 --> <mapper resource="sqlmap/User.xml"/> <!-- 通过mapper接口加载单个映射文件 遵循的一些规范: 需要将mapper接口类型和mapper.xml映射文件名称保持一致,且在一个目录中。 遵循的规范的前提:使用的时mapper代理方法 --> <mapper resource="cn.ccir.mybatis.entity.TestDaoMapper"/> <!-- 批量加载mapper 指定mapper接口包名。mybatis自动扫描包下百年所有mapper接口进行加载。 遵循的一些规范: 需要将mapper接口类型和mapper.xml映射文件名称保持一致,且在一个目录中。--> <mapper resource="cn.ccir.mybatis.entity"/> </mappers>