这里介绍一下mybatis 根据mybatis的官网说明,mybatis是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。mybatis的特点
- 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
- 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql基本上可以实现我们不使用数据访问框架可以实现的所有功能,或许更多。
- 解除sql与程序代码的耦合:通过提供DAL层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
- 提供映射标签,支持对象与数据库的orm字段关系映射
- 提供对象关系映射标签,支持对象关系组建维护
- 提供xml标签,支持编写动态sql。
mybatis也不是完美的
缺点:
- 编写SQL语句时工作量很大,尤其是字段多、关联表多时,更是如此。 这个非常非常麻烦和hibernate相比就是个弟弟 就是个弟弟 然而偏偏还很常用。。
- SQL语句依赖于数据库,导致数据库移植性差,不能更换数据库。
- 框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改。
- 二级缓存机制不佳
首先mybatis官网上说明我觉得很详细了但是有的还是很繁琐,初学应该看不懂,这里假设读者看不懂官网来讲一下。
首先时安装 如果使用maven的话直接依赖maven对应的版本即可
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>x.x.x</version> </dependency>
也可以点击这里下载 这是我上传的一些jar包选择下载。
首先说一下配置文件吧 左边的db,properties不是必须配置的 暂时可以忽略(实际开发会用 就是存一些配置,然后让框架从中读取)重点是sqlMapConfig.xml名字不能取错了 然后也要放到classpath下 如果是建了个文件夹然后不知道怎么放的话可以参照如下方法:选中右键你的文件夹 -》build Path-》add to BuildPath即可 移除的话remove即可下面是sqlMapConfig.xml中约束文件的一些说明
这里给出其参数的内容
SqlMapConfig.xml中配置的内容和顺序如下:
properties(属性)
settings(全局配置参数)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mappers(映射器)
1 <?xml version="1.0" encoding="UTF-8" ?>
2 <!DOCTYPE configuration
3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
4 "http://mybatis.org/dtd/mybatis-3-config.dtd">
5 <configuration>
6 <properties resource="jdbc.properties"/>
7 <!-- 别名 包以其子包下所有类 头字母大小都行-->
8 <typeAliases>
9 <!-- <typeAlias type="com.dabai.mybatis.pojo.User" alias="User"/> -->
10 <package name="com.dabai.mybatis.pojo"/>
11 </typeAliases>
12 <!-- 和spring整合后 environments配置将废除 -->
13 <environments default="development">
14 <environment id="development">
15 <!-- 使用jdbc事务管理 -->
16 <transactionManager type="JDBC" />
17 <!-- 数据库连接池 -->
18 <dataSource type="POOLED">
19 <property name="driver" value="${jdbc.driver}" />
20 <property name="url"
21 value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
22 <property name="username" value="root" />
23 <property name="password" value="root" />
24 </dataSource>
25 </environment>
26 </environments>
27
28 <!-- Mapper的位置 Mapper.xml 写Sql语句的文件的位置 -->
29 <mappers>
30 <!--这里应当写全 为了简化我删掉了几个-->
31 <!-- <mapper resource="sqlmap/User.xml" class="" url=""/> -->
32 <!-- <mapper class="com.itheima.mybatis.mapper.UserMapper" /> -->
33 <!-- <mapper url="" /> -->
34 <package name="com.dabai.mybatis.mapper"/>
35 </mappers>
36 </configuration>
<properties> 很明显我这里使用了db.properties里面的配置 使用方法就是那样的,要使用什么值就${}加上对应的参数名
<typeAliases>这个比较高级 而且常用 取别名 好比spring中的id 或name <typeAlias type="com.dabai.mybatis.pojo.User" alias="user"/> 这个意思就是User这个类在 UserMapper.xml文件中可以在需要用User类名的地方简写成user比如下面这样 就那个parameterType那 写成user对应哪个User类 ,别名还可以根据包名写 相应的package里面所有的pojo都能简写成对应的user 或者User首字母不区分大小写,就是这样式的 然而 配置package的话只能配置一个 即所有的pojo或者实体都要放一个包内,所以我用的比较多的是 type 加 alias
接下来是<environments>这个写过jdbc的同学很好理解吧 就是配置连接信息之类的 实际中不怎么用,毕竟不可能只是用mybatis一个框架不要其他的
还一个mappers 也很好理解 参照hibernate的实体映射文件 mybatis的这里是XXXMapper。xml文件所在的地方 XXXMapper.xml是用来写sql的地方 两个配置文件需要关联.注意一下在与spring配合使用时可以让spring扫描Mapper.xml文件 所以这个是可以省略的。如下上面那个是让spring加载管理mybatis的SqlSessionFactory的 下面那个就能扫描XXXMapper.xml文件 你就可以少些<mappers>这条配置了,暂时看不懂也ok后面有整个项目搭建 先了解mybatis。接下来给出UserMapper.xml即关于User的sql
1 <?xml version="1.0" encoding="UTF-8" ?>
2 <!DOCTYPE mapper
3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
5 <!-- 写Sql语句 -->
6 <mapper namespace="com.dabai.mybatis.mapper.UserMapper">
7 <!-- 通过ID查询一个用户 -->
8 <select id="findUserById" parameterType="Integer" resultType="User">
9 select * from user where id = #{v}
10 </select>
11
12 <!-- //根据用户名称模糊查询用户列表
13 #{} select * from user where id = ? 占位符 ? == '五'
14 ${} select * from user where username like '%五%' 字符串拼接
15
16 -->
17 <select id="findUserByUsername" parameterType="String" resultType="com.dabai.mybatis.pojo.User">
18 select * from user where username like "%"#{haha}"%"
19 </select>
20
21 <!-- 添加用户 -->
22 <insert id="insertUser" parameterType="com.dabai.mybatis.pojo.User">
23 <selectKey keyProperty="id" resultType="Integer" order="AFTER">
24 select LAST_INSERT_ID()
25 </selectKey>
26 insert into user (username,birthday,address,sex)
27 values (#{username},#{birthday},#{address},#{sex})
28 </insert>
29
30 <!-- 更新 -->
31 <update id="updateUserById" parameterType="com.dabai.mybatis.pojo.User">
32 update user
33 set username = #{username},sex = #{sex},birthday = #{birthday},address = #{address}
34 where id = #{id}
35 </update>
36
37 <!-- 删除 -->
38 <delete id="deleteUserById" parameterType="Integer">
39 delete from user
40 where id = #{vvvvv}
41 </delete>
42
43
44 </mapper>
<mapper namespace="com.dabai.mybatis.mapper.UserMapper"> 用于与UserMapper.java对应 保证方法调用唯一 起关联作用 很重要 不能少
其他的见使用来理解
注意一下调用mapper的语句中若是参数只有一个简单类型如int啊 String啊 #{}括号内写成什么样都可以,如果是对象类的话按照对象的属性名填写,在后面加对应的数据库的类型如传过来的参数是User类 那么就要写成 parameterType=“User” 没配别名的话要写完整类名如:com.dai.pojo.User,对应的参数写成#{username,jdbcType=varchar}VARCHAR 这个不区分大小写 美观而已。但是其中id字段必须唯一,用于与Mapper.java对应
#{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换。#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
${}表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, ${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value。
1.1.1. parameterType和resultType
parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。
resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。如果有多条数据,则分别进行映射,并把对象放到容器List中
说了sqlMapConfig和XXXMapper.xml还要说一个Interface这个接口提供给service层操作dao层的方法 即调用。Mybatis建议使用者只开发接口 不开发实现类下面给出UserMapper.java当然写了也没什么问题,不写有mybatis代理实现而已,结果都一样
1 public interface UserMapper {
2
3
4 //遵循四个原则
5 //接口 方法名 == User.xml 中 id 名
6 //返回值类型 与 Mapper.xml文件中返回值类型要一致
7 //方法的入参类型 与Mapper.xml中入参的类型要一致
8 //命名空间 绑定此接口
9 public User findUserById(Integer id);
10 //这里只写一个 事实上还有insertUser updateUserByid deleteUserById 请读者编写 感受 注意方法名对应这id名 参数看准来
11 }
接下来给出测试类验证
1 public class MapperTest {
2
3
4 @Test
5 public void testMapper() throws Exception {
6 //加载核心配置文件
7 String resource = "sqlMapConfig.xml";
8 InputStream in = Resources.getResourceAsStream(resource);
9 //创建SqlSessionFactory
10 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
11 //创建SqlSession
12 SqlSession sqlSession = sqlSessionFactory.openSession();
13
14 //SqlSEssion帮我生成一个实现类 (给接口)
15 UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
16
17
18 User user = userMapper.findUserById(1);
19 //要打印的话 记得覆写user类的 toString方法 在这里再强调一些
20 System.out.println(user);
21 }
22 }
关于sqlSession
1.1. SqlSession的使用范围
SqlSession中封装了对数据库的操作,如:查询、插入、更新、删除等。
SqlSession通过SqlSessionFactory创建。
SqlSessionFactory是通过SqlSessionFactoryBuilder进行创建。
1.1.1. SqlSessionFactoryBuilder
SqlSessionFactoryBuilder用于创建SqlSessionFacoty,SqlSessionFacoty一旦创建完成就不需要SqlSessionFactoryBuilder了,因为SqlSession是通过SqlSessionFactory创建的。所以可以将SqlSessionFactoryBuilder当成一个工具类使用,最佳使用范围是方法范围即方法体内局部变量。
1.1.2. SqlSessionFactory
SqlSessionFactory是一个接口,接口中定义了openSession的不同重载方法,SqlSessionFactory的最佳使用范围是整个应用运行期间,一旦创建后可以重复使用,通常以单例模式管理SqlSessionFactory。
1.1.3. SqlSession
SqlSession是一个面向用户的接口,sqlSession中定义了数据库操作方法。
每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能共享使用,它也是线程不安全的。因此最佳的范围是请求或方法范围。绝对不能将SqlSession实例的引用放在一个类的静态字段或实例字段中。
打开一个 SqlSession;使用完毕就要关闭它。通常把这个关闭操作放到 finally 块中以确保每次都能执行关闭。