Mybatis(一)
来源:互联网 发布:mssql分布式数据库 编辑:程序博客网 时间:2024/05/22 17:39
Mybatis与Hibernate区别
- Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句,不过mybatis可以通过XML或注解方式灵活配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,最后将sql执行的结果再映射生成java对象。
- Mybatis学习门槛低,简单易学,程序员直接编写原生态sql,可严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。
- Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用hibernate开发可以节省很多代码,提高效率。但是Hibernate的缺点是学习门槛高,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡,以及怎样用好Hibernate需要具有很强的经验和能力才行。
MyBatis的一级缓存和二级缓存?
- Mybatis首先去缓存中查询结果集,如果没有则查询数据库,如果有则从缓存取出返回结果集就不走数据库。Mybatis内部存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象
- Mybatis的二级缓存即查询缓存,它的作用域是一个mapper的namespace,即在同一个namespace中查询sql可以从缓存中获取数据。二级缓存是可以跨SqlSession的。
介绍
- MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
- Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatement、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
名词解释
- pojo:不按mvc分层,只是java bean有一些属性,还有get set方法
- domain:不按mvc分层,只是java bean有一些属性,还有get set方法
- po:用在持久层,还可以再增加或者修改的时候,从页面直接传入action中,它里面的java bean 类名等于表名,属性名等于表的字段名,还有对应的get set方法
- vo: view object表现层对象,主要用于在高级查询中从页面接收传过来的各种参数.好处是扩展性强
- bo: 用在servie层,现在企业基本不用.
这些po,vo, bo,pojo可以用在各种层面,因为都是普通的java bean没有语法错误,但是在企业最好不要混着用,因为这些都是设计的原则,混着用比较乱.不利于代码维护.
MyBatis与Hibernate的理解
- 相同点:屏蔽jdbc api的底层访问细节,使用我们不用与jdbc api打交道,就可以访问数据。
- Hibernate是一个全自动的orm映射工具,它可以自动生成sql语句,ibatis需要我们自己在xml配置文件中写sql语句,hibernate要比ibatis功能负责和强大很多。因为hibernate自动生成sql语句,我们无法控制该语句,我们就无法去写特定的高效率的sql。对于一些不太复杂的sql查询,hibernate可以很好帮我们完成。
Mybatis架构
- 解释
- SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。
- mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。
- 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
- 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
- mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。
- Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。
- Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
- Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。
环境搭建
- jar包
- SqlMapConfig.xml是mybatis核心配置文件
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration> <!-- 和spring整合后 environments配置将废除--> <environments default="development"> <environment id="development"> <!-- 使用jdbc事务管理--> <transactionManager type="JDBC" /> <!-- 数据库连接池--> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" /> <property name="username" value="root" /> <property name="password" value="123" /> </dataSource> </environment> </environments></configuration>
- 日志配置
#Global logging configurationlog4j.rootLogger=DEBUG, stdout# Console output...log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
- sql 映射文件约束
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
- mybatis框架需要加载映射文件,将Users.xml添加在SqlMapConfig.xml,如下:
<mappers> <mapper resource="User.xml"/></mappers>
可以进行CRUD操作(示例:根据id查询用户信息)
测试程序:
public class Mybatis_first {
private SqlSessionFactory sqlSessionFactory;
@Before
public void createSqlSessionFactory() throws IOException {
String resource = “SqlMapConfig.xml”;
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testFindUserById() {
// 数据库会话实例
SqlSession sqlSession = null;
try {
sqlSession = sqlSessionFactory.openSession();
User user = sqlSession.selectOne(“test.findUserById”, 10);
System.out.println(user);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (sqlSession != null) {
sqlSession.close(); } }}}
细节
- 1) 映射文件中namespace要等于接口的全路径名称
2) 映射文件中sql语句id要等于接口的方法名称
3) 映射文件中传入参数类型要等于接口方法的传入参数类型
4) 映射文件中返回结果集类型要等于接口方法的返回值类型- #{}占位符:占位
如果传入的是基本类型,那么#{}中的变量名称可以随意写
如果传入的参数是pojo类型,那么#{}中的变量名称必须是pojo中的属性.属性.属性…${}
拼接符:字符串原样拼接
如果传入的是基本类型,那么${}
中的变量名必须是value
如果传入的参数是pojo类型,那么${}
中的变量名称必须是pojo中的属性.属性.属性…
注意:使用拼接符有可能造成sql注入,在页面输入的时候可以加入校验,不可输入sql关键字,不可输入空格- 映射文件:
1)传入参数类型通过parameterType属性指定
2)返回结果集类型通过resultType属性指定- hibernate和mybatis区别:
hibernate:它是一个标准的orm框架,比较重量级,学习成本高.
优点:高度封装,使用起来不用写sql,开发的时候,会减低开发周期.
缺点:sql语句无法优化
应用场景:oa(办公自动化系统), erp(企业的流程系统)等,还有一些政府项目,
总的来说,在用于量不大,并发量小的时候使用.
mybatis:它不是一个orm框架, 它是对jdbc的轻量级封装, 学习成本低,比较简单
优点:学习成本低, sql语句可以优化, 执行效率高,速度快
缺点:编码量较大,会拖慢开发周期
应用场景: 互联网项目,比如电商,P2p等
总的来说是用户量较大,并发高的项目.
Dao的开发方式
原始Dao的开发方式
- 原始Dao开发方法需要程序员编写Dao接口和Dao实现类。
- 映射文件
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="test"><!-- 根据id获取用户信息 --> <select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User"> select * from user where id = #{id} </select><!-- 添加用户 --> <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User"> <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> select LAST_INSERT_ID() </selectKey> insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address}) </insert></mapper>
- 接口与实现类
Public interface UserDao { public User getUserById(int id) throws Exception; public void insertUser(User user) throws Exception;}Public class UserDaoImpl implements UserDao { private SqlSessionFactory sqlSessionFactory; public UserDaoImpl(SqlSessionFactory sqlSessionFactory){ this.setSqlSessionFactory(sqlSessionFactory);} @Override public User getUserById(int id) throws Exception { SqlSession session = sqlSessionFactory.openSession(); User user = null; try { //通过sqlsession调用selectOne方法获取一条结果集 //参数1:指定定义的statement的id,参数2:指定向statement中传递的参数 user = session.selectOne("test.findUserById", id); System.out.println(user); } finally{ session.close(); } return user; } @Override Public void insertUser(User user) throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); try { sqlSession.insert("insertUser", user); sqlSession.commit(); } finally{ session.close(); } }}
- 测试
private SqlSessionFactory sqlSessionFactory; @Before public void init() throws Exception { SqlSessionFactoryBuilder sessionFactoryBuilder = new SqlSessionFactoryBuilder(); InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); sqlSessionFactory = sessionFactoryBuilder.build(inputStream); } @Test public void testGetUserById() { UserDao userDao = new UserDaoImpl(sqlSessionFactory); User user = userDao.getUserById(22); System.out.println(user); }}
- 原始Dao开发中存在以下问题:
- Dao方法体存在重复代码:通过SqlSessionFactory创建SqlSession,调用SqlSession的数据库操作方法
- 调用sqlSession的数据库操作方法需要指定statement的id,这里存在硬编码,不利于开发维护。
Mapper动态代理方式
- Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。
Mapper接口开发需要遵循以下规范:
- Mapper.xml(映射文件)文件中的namespace等于mapper接口的全路径名称
- Mapper.xml中sql语句id要等于Mapper接口方法名称
- mapper.xml中传入的parameterType的类型等于Mapper接口方法的输入参数类型
- mapper.xml中定义的每个sql的resultType的类型等于Mapper接口方法的返回值类型。
- 定义mapper映射文件UserMapper.xml(内容同Users.xml),需要修改namespace的值为 UserMapper接口路径。将UserMapper.xml放在classpath 下mapper目录 下。
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="cn.itcast.mybatis.mapper.UserMapper"><!-- 根据id获取用户信息 --> <select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User"> select * from user where id = #{id} </select><!-- 自定义条件查询用户列表 --> <select id="findUserByUsername" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User"> select * from user where username like '%${value}%' </select><!-- 添加用户 --> <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User"> <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> select LAST_INSERT_ID() </selectKey> insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address}) </insert></mapper>
- 测试
Public class UserMapperTest extends TestCase { private SqlSessionFactory sqlSessionFactory; protected void setUp() throws Exception { //mybatis配置文件 String resource = "sqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); //使用SqlSessionFactoryBuilder创建sessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } Public void testFindUserById() throws Exception { //获取session SqlSession session = sqlSessionFactory.openSession(); //获取mapper接口的代理对象 UserMapper userMapper = session.getMapper(UserMapper.class); //调用代理对象方法 User user = userMapper.findUserById(1); System.out.println(user); //关闭session session.close(); } @Test public void testFindUserByUsername() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); List<User> list = userMapper.findUserByUsername("张"); System.out.println(list.size()); }Public void testInsertUser() throws Exception { //获取session SqlSession session = sqlSessionFactory.openSession(); //获取mapper接口的代理对象 UserMapper userMapper = session.getMapper(UserMapper.class); //要添加的数据 User user = new User(); user.setUsername("张三"); user.setBirthday(new Date()); user.setSex("1"); user.setAddress("北京市"); //通过mapper接口添加用户 userMapper.insertUser(user); //提交 session.commit(); //关闭session session.close(); }}
SqlMapConfig.xml配置文件
- SqlMapConfig.xml中配置的内容和顺序如下:
- properties(属性)
- settings(全局配置参数)
- typeAliases(类型别名)
- typeHandlers(类型处理器)
- objectFactory(对象工厂)
- plugins(插件)
- environments(环境集合属性对象)
- environment(环境子属性对象)
- transactionManager(事务管理)
- dataSource(数据源)
- mappers(映射器)
properties
- SqlMapConfig.xml可以引用java属性文件中的配置信息如下:
在classpath下定义db.properties文件,
jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8jdbc.username=rootjdbc.password=root
SqlMapConfig.xml引用如下:
<properties resource="db.properties"/> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments>
注意: MyBatis 将按照下面的顺序来加载属性:
- 在 properties 元素体内定义的属性首先被读取。
- 然后会读取properties 元素中resource或 url 加载的属性,它会覆盖已读取的同名属性。
typeAliases
- 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 map Map
- 自定义别名:
在SqlMapConfig.xml中配置:
<typeAliases> <!-- 单个别名定义 --> <typeAlias alias="user" type="cn.itcast.mybatis.po.User"/> <!-- 批量别名定义,扫描整个包下的类,别名为类名(首字母大写或小写都可以) --> <package name="cn.itcast.mybatis.po"/> <package name="其它包"/></typeAliases>
mappers(映射器)
- Mapper配置的几种方法:
<mapper resource=" " />使用相对于类路径的资源如:<mapper resource="sqlmap/User.xml" />
<mapper class=" " />使用mapper接口类路径如:<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
package name=""/>注册指定包下的所有mapper接口如:<package name="cn.itcast.mybatis.mapper"/>
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
- Mybatis(一)
- mybatis (一)
- Mybatis(一)
- Mybatis(一)
- Mybatis一
- mybatis(一)
- MyBatis(一)
- Mybatis(一)
- [MyBatis]MyBatis入门(一)
- Mybatis+eclipse+MySql(一)
- mybatis学习一
- Mybatis学习日记(一)
- mybatis学习(一)
- mybatis(一)
- mybatis一---入门
- Mybatis学习(一)
- mybatis学习(一)
- mybatis入门教程 (一)
- 机器学习算法与Python实践之(六)二分k均值聚类
- SecureCRT串口调试工具配置
- 愿你我都成为自己所希望的最美丽的烟火
- 用中断的方式实现delay延时的一点注释
- 南阳ID:98 成绩转换
- Mybatis(一)
- centos6mini安装网卡设置
- 【深度学习数据预处理2】使用Matlab批量生成声谱图
- A 三角分形 题解
- 你眼中的未来,是我们回不去的曾经
- java-数组的遍历
- o(1), o(n), o(logn), o(nlogn)
- poj1860Currency Exchange(spfa)
- TCP/IP协议栈关于IP分片重组