学习视频来自黑马程序员,感谢!
Mybatis和Hibernate 本质区别和应用场景
Hibernate:是一个标准ORM框架(对象关系映射),入门门槛较高,不需要写sql,sql语句自动生成了。
对sql语句进行优化、修改比较困难。
应用场景: 适用于需求变化不多的中小型项目:比如后台管理系统,arp,orm,oa (不过以基本淘汰)
Mybatis:专注sql本身,需要程序员自己编写sql语句,sql编写优化比较方便,是一个不完全的ORM框架。
应用场景: 需求变化较多的项目,比如:互联网项目。
Mybatis开发dao两种方法
SqlSession使用范围
- 通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory。当成一个工具类,不需用单例管理。
- 通过SqlSessionFactory创建SqlSession,通过单例模式管理sqlSessionFactory
- SqlSession是一个面向用户的接口。提供了很多用于操作数据库的方法。
线程不安全,在SqlSession除了有接口中的方法,还有数据域属性。
最佳应用场合在方法体内,定义成局部数据变量使用
原始dao开发方法
程序员需要写dao接口和实现类
需要向dao实现类中注入SqlSessionFactory ,在方法体内创建SqlSession
- dao接口
public interface UserDao { //根据id查询 public User findUserById(int id) throws Exception; //添加用户 public void insertUser(User user) throws Exception; //删除用户 public void deleteUser(int id) throws Exception; }
- dao实现类
public class UserDaoImpl implements UserDao { private SqlSessionFactory sqlSessionFactory; public UserDaoImpl(SqlSessionFactory sqlSessionFactory){ this.sqlSessionFactory = sqlSessionFactory; } @Override public User findUserById(int id) throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); User user = sqlSession.selectOne("test.findUserById",1); sqlSession.close(); return user; } }
- 原始dao开发问题总结
- dao接口实现类方法中存在大量模版方法,设想能否将代码q提取出来,减轻程序员工作量
- 调用sqlSession方法时,将statement的id硬编码
- 由于sqlSession方法传入变量使用泛型,所以即使变量传入错误,在编译阶段也不报错,不利于程序员开发
Mybatis对mapper代理开发方法
只需要mapper接口(相当于dao接口)
- 思路
- 程序员只需要编写mapper接口
- 编写mapper.xml映射文件,只需遵循一些开发规范,Mybatis可以自动生成mapper接口实现类的代理对象
- 在SqlMapConfig.xml配置。
开发规范:
- mapper.xml 中 namespace等于mapper接口地址
- mapper接口中的方法名和mapper.xml中statement的id一致
- mapper接口中方法输入参数类型,与xml中parameterType一致
- mapper接口中方法返回值类型,与xml中resultType一致
总结: 以上开发规范主要是对下边的代码进行统一生成:
User user = sqlSession.selectOne("test.findUserById", id);
sqlSession.insert("test.insertUser", user);
......
小结
-
代理对象内部调用selectOne或selectList
如果mapper方法返回单个pojo对象(非集合对象),代理对象内部通过selectOne查询数据库。
如果mapper方法返回集合对象,代理对象内部通过selectList查询数据库。 -
mapper接口方法参数只能有一个是否影响系统 开发 mapper接口方法参数只能有一个,系统是否不利于扩展维护。
系统 框架中,dao层的代码是被业务层公用的。
即使mapper接口只有一个参数,可以使用包装类型的pojo满足不同的业务方法的需求。
注意:持久层方法的参数可以包装类型、map。。。,service方法中建议不要使用包装类型(不利于业务层的可扩展)。
Mybatis配置文件
mybatis的全局配置文件SqlMapConfig.xml,配置内容如下:
- properties(属性)
- settings(全局配置参数)
- typeAliases(类型别名)
- typeHandlers(类型处理器)
- objectFactory(对象工厂)
- plugins(插件)
- environments(环境集合属性对象)
- environment(环境子属性对象)
- transactionManager(事务管理)
- dataSource(数据源)
- mappers(映射器)
properties(属性)
需求:
将数据库连接参数单独配置在dp.properties中,只需要在SqlMapConfig.xml加载属性值。在SqlMapConfig.xml中就不需要对数据库连接参数硬编码。
将数据库连接参数只配置在db.properties中,原因:方便对参数进行统一管理,其它xml可以引用该db.properties。
db.properties。
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf8&useSSL=true
jdbc.username=root
jdbc.password=******
加载属性文件
<properties resource="db.properties">
</properties>
<property name="driver" value="${jdbc.driver}" />
注意: MyBatis 将按照下面的顺序来加载属性:
- 在 properties 元素体内定义的属性首先被读取。
- 然后会读取properties 元素中resource或 url 加载的属性,它会覆盖已读取的同名属性。
- 最后读取parameterType传递的属性,它会覆盖已读取的同名属性。
建议:
不要在properties元素体内添加任何属性值,只将属性值定义在properties文件中。
在properties文件中定义属性名要有一定的特殊性,如:XXXXX.XXXXX.XXXX
settings (全局配置参数)
mybatis框架在运行时可以调整一些运行参数。
比如:开启二级缓存、开启延迟加载。
全局参数将会影响mybatis的运行行为。
typeAliases(类型别名)
- 需求
在mapper.xml中,定义很多的statement,statement需要parameterType指定输入参数的类型、需要resultType指定输出结果的映射类型。
如果在指定类型时输入类型全路径,不方便进行开发,可以针对parameterType或resultType指定的类型定义一些别名,在mapper.xml中通过别名定义,方便开发。
有默认别名,详情谷歌
<typeAliases>
针对单个别名定义
type:类型的路径
alias:别名
<typeAlias type="com.caoerzhe.po.User" alias="user"/>
批量别名定义
指定包名,mybatis自动扫描包中的po类,自动定义别名,别名就是类名(首字母大写或小写都可以)
<package name="com.caoerzhe.po"/>
</typeAliases>
typeHandlers(类型处理器)
mybatis中通过typeHandlers完成jdbc类型和java类型的转换。
通常情况下,mybatis提供的类型处理器满足日常需要,不需要自定义.
mappers(映射器)
- 通过resource方法一次加载一个映射文件
- 通过mapper接口加载单个 映射文件
- 批量加载mapper
<mappers>
通过resource方法一次加载一个映射文件
<mapper resource="mapper/UserMapper.xml"/>
通过mapper接口加载单个 映射文件
遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录 中
上边规范的前提是:使用的是mapper代理方法
mapper class="com.caoerzhe.mapper.UserMapper"/>
批量加载mapper
指定mapper接口的包名,mybatis自动扫描包下边所有mapper接口进行加载
遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录 中
上边规范的前提是:使用的是mapper代理方法
<package name="com.caoerzhe.mapper"/>
</mappers>
注意:maven项目的约定配置文件必须放resources里,src目录下的xml文件默认不会编译到target,所以无法使用后两种方法