目录
(4)在SqlMapConfig.xml配置文件加载映射文件
学习过的持久层框架:DBUtils , Hibernate
Mybatis就是类似于hibernate的orm持久层框架。
为什么学Mybatis?
1.目前最主流的持久层框架为hibernate与mybatis,而且国内目前情况使用Mybatis的公司比hibernate要多。
2.Hibernate学习门槛不低,要精通门槛更高。门槛高在怎么设计O/R映射,在性能和对象模型之间如何权衡取得平衡,以及怎样用好Hibernate缓存与数据加载策略方面需要你的经验和能力都很强才行。国内目前前的情况精通hibernate技术大牛非常少。
3.sql优化方面,Hibernate的查询会将表中的所有字段查询出来,这一点会有性能消耗。当然了,Hibernate也可以自己写SQL来指定需要查询的字段,但这样就破坏了Hibernate开发的简洁性。说得更深入一些,如果有个查询要关联多张表,比如5张表,10张表时,而且,我们要取的字段只是其中几张表的部分字段。这时用hibernate时就会显得非常力不从心。就算用hibernate的sqlquery,后续的维护工作也会让人发狂。
Jdbc访问数据库的过程:
1.加载数据库驱动
2.创建数据库连接
3.创建statement
4./设置sql语句
5.设置查询参数
6.执行查询,得到ResultSet
7.解析结果集ResultSet
8.释放资源
这里是传统jdbc方式的写法,但是存在着很多问题:
存在的问题:
1.数据库连接频繁开启和关闭,会严重影响数据库的性能。
2.代码中存在硬编码,分别是数据库部分的硬编码和SQL执行部分的硬编码。
1.MyBatis的框架核心(重点)
- mybatis配置文件,包括Mybatis全局配置文件和Mybatis映射文件,其中全局配置文件配置了数据源、事务等信息;映射文件配置了SQL执行相关的信息。
- mybatis通过读取配置文件信息(全局配置文件和映射文件),构造出SqlSessionFactory,即会话工厂。
- 通过SqlSessionFactory,可以创建SqlSession即会话。Mybatis是通过SqlSession来操作数据库的。
- SqlSession本身不能直接操作数据库,它是通过底层的Executor执行器接口来操作数据库的。Executor接口有两个实现类,一个是普通执行器,一个是缓存执行器(默认)。
- Executor执行器要处理的SQL信息是封装到一个底层对象MappedStatement中。该对象包括:SQL语句、输入参数映射信息、输出结果集映射信息。其中输入参数和输出结果的映射类型包括HashMap集合对象、POJO对象类型。
2.环境准备
1.创建数据库表
2.下载MyBatis
mybaits的代码由github.com管理,下载地址:Releases · mybatis/mybatis-3 · GitHub
3.创建项目导包
4.添加log4j.properties
Mybatis使用的日志包是log4j的,所以需要添加log4j.properties。
在classpath下创建log4j.properties如下:
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
日志级别在开发阶段设置成DEBUG,在生产阶段设置成INFO或者ERROR。
3.开发步骤
- 创建PO(model)类,根据需求创建;
- 创建全局配置文件SqlMapConfig.xml;
- 编写映射文件;
- 加载映射文件,在SqlMapConfig.xml中进行加载;
- 编写测试程序,即编写Java代码,连接并操作数据库。
思路:
- 读取配置文件;
- 通过SqlSessionFactoryBuilder创建SqlSessionFactory会话工厂。
- 通过SqlSessionFactory创建SqlSession。
- 调用SqlSession的操作数据库方法。
- 关闭SqlSession。
(1)创建PO类
PO(Persistent Object):持久化对象,它跟持久层(通常是关系型数据库)的数据结构形成一一对应的映射关系,如果持久层是关系型数据库,那么,数据表中的每个字段(或若干个)就对应PO的一个(或若干个)属性。
(3)创建SqlMapConfig.xml
在classpath(src)下,创建SqlMapConfig.xml文件
也可以将jdbc的连接信息写入到properties文件中
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--这里properties的路径是相对于src的-->
<properties resource="jdbc.properties"/>
<typeAliases>
<package name="com.gdut.entity"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/gdut/mapper/Dep.xml"></mapper>
</mappers>
</configuration>
(3)映射文件
在classpath下,创建sqlmap文件夹。在sqlmap目录下,创建User.xml映射文件。
【Mybatis的映射文件头(可以从mybatis-3.2.7.pdf文件中拷贝)】
这里要注意#[ ]的使用,如果是基础数据类型的话里面的值是可以任意写的,要是类的引用类型的话就需要写类的属性
(4)在SqlMapConfig.xml配置文件加载映射文件
注意:这个一般是写在配置的最后
(5)测试类
注意:selectOne中的方法一般要加上命名空间也就是test.findUserById
4.更多案例讲解
(1)模糊查询用户信息
上面的这种模糊查询的话可能会造成sql注入,一般的 话我们可以使用下面这种
select * from user where username like "%"#{value}"%"
因为#{…}解析成sql语句时候,会在变量外侧自动加单引号’ ',所以这里 % 需要使用双引号" ",不能使用单引号 ’ ',不然会查不到任何结果。
测试类
(2)插入用户信息
测试类
(3)删除用户
测试类
(4)更新用户
测试
注意:这里的增删改要注意事务的提交,事务的提交有两种方式
1.手动提交,也就是上面的session.commit();
2.自动提交,就是在openSession(true)加上一个true
5.主键返回之MySQL自增主键
思路:
- MySQL自增主键,是指在insert之前MySQL会自动生成一个自增的主键。
- 我们可以通过MySQL的函数获取到刚插入的自增主键:
LAST_INSERT_ID()
- 这个函数是在insert语句之后去调用。
这里的自增长还有一个比较简单的写法(这是比较推荐的写法)
这样的话就可以把下面繁琐的写法给替换掉,也就是讲下面的写法给替换
oracle的主键自增长
keyProperty就是用来储存我们查询的结果的
主键返回之MySQL自增UUID
这里的selectkey里面的SELECT UUID(),相当于将查询出来的数据存入到名字叫id的变量中,所以下面在真正查询的时候就直接使用id就可以了
ORCLE主键
SELECT user_seq.nextval() FROM dual
总结:
6.MyBatis的Dao编写 【一般不用,有更多好方式】
Dao(两种)
这里所书写的方式是通过注入的方式来使用的,在测试的时候会将配置文件注入
测试
另一种方式是打包成工具类方便使用
package com.itheima.mybatis.utils;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
/**
* SqlSessionFactory工具类
* @author Steven
*
*/
public class SqlSessionFactoryUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
// 创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
// 创建核心配置文件的输入流
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 通过输入流创建SqlSessionFactory对象
sqlSessionFactory = ssfb.build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取SqlSessionFactory
* @return
*/
public static SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory;
}
}
测试的时候可以直接使用工具类得到
这里我们先使用第一种方式,一般情况下第二种方式比较常用
7.MyBatis的Dao编写【mapper代理方式实现】
Mapper代理的开发方式,程序员只需要编写mapper接口(相当于dao接口)即可。Mybatis会自动的为mapper接口生成动态代理实现类。
不过要实现mapper代理的开发方式,需要遵循一些开发规范。
编写步骤
第一步
重新写个UserMapper配置文件和定义mapper映射文件UserMapper.xml(内容同Users.xml,除了namespace的值),放到新创建的目录mapper下。
第二步
测试
8.全局配置文件其它配置
(1)properties数据库文件配置
在src下配置个db.properties文件
修改全局的配置文件
setting【了解】
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 |
自定义别名
mappers
<mapper resource=’’/>
使用相对于类路径的资源
如:<mapper resource="sqlmap/User.xml" />
<mapper url=’’/> 【不用】
使用完全限定路径
如:<mapper url="file:///D:\workspace_spingmvc\mybatis_01\config\sqlmap\User.xml" />
<mapper class=’’/>
使用mapper接口的全限定名
如:<mapper class="cn.gyf.mybatis.mapper.UserMapper"/>
如果一个包下有多个配置文件的话,可以使用以下标签一次性将配置文件导入到核心配置文件中,只需要在配置文件中加入
<package name=’’/>(推荐)
注册指定包下的所有映射文件
如:<package name="cn.gyf.mybatis.mapper"/>
注意:此种方法要求mapper接口和mapper映射文件要名称相同,且放到同一个目录下;