1.Mybatis简介
Mybatis是一个优秀的基于Java的持久层框架,它内部封装了JDBC,是开发者只需关注SQL语句本身,而不用再花费精力去处理注入注册驱动、创建Connection、配置Statement等繁杂过程。
Mybatis通过XML或注解的方式将要执行的各种statement(statement、preparedStatement等)配置起来,并通过,Java对象和Statement中的SQL的动态参数进行映射生成最终执行的SQL语句,最后由Mybatis框架执行SQL并将结果映射成Java对象并返回。
2.Mybatis与Hibernate
Hibernate框架是提供了全面的数据库封装机制的“全自动”ORM,即实现了POJO和数据库表之间的映射,以及SQL的自动生成和执行。
相对于此,Mybatis只能算作是“半自动”ORM。其着力点,是在POJO类与SQL语句之间的映射关系。也就是说,Mybatis并不会为程序员自动生成SQL语句。具体的SQL需要程序员自己编写,然后通过SQL语句映射文件,将SQL所需的参数,以及返回的结果字段映射到指定POJO。因此,Mybatis成为了“全自动”ORM的一种有益补充。
与Hibernate相比,Mybatis具有以下几个特点:
(1)在XML文件中配置SQL语句,实现了SQL语句与代码分离,给程序员的维护带来了很大的便利。
(2)因为需要程序员自己去编写SQL语句,程序员可以结合数据库自身的特点灵活控制SQL语句,因此能够实现比Hibernate等全自动ORM框架更高的查询效率,能够完成复杂查询。
(3)简单,易于学习,易于使用,上手快。
5.1 jar下载
福利:jar包下载的好地址:https://mvnrepository.com/
(这个网站可以搜索下载jar包)
搜索mybatis–>点击相应的出处–>点击要下载的版本–>点击图片红色处下载jar(就不用到处找和csdn积分下载了),下方还有maven的依赖等(十分好用,支持maven阿里云)。
mysql的jar和log的jar都从这里下载。
// 实体类 数据库中int类型id用Integer(方便传参)
public class UserInfo {
private Integer id;
private String username; // 用户名
private String password; // 密码
private String realname; // 真实姓名
private String sex; // 性别
private String address; // 住址
private String question; // 问题设置
private String answer; // 问题答案
private String email; // 邮箱
private String favorate; // 爱好
private Integer score; // 成绩
private Date regdate; // 时间
// 省略get和set
// ...
}
// 数据库
CREATE TABLE `user_info` (
`id` int(4) NOT NULL AUTO_INCREMENT,
`userName` varchar(16) DEFAULT NULL,
`password` varchar(16) DEFAULT NULL,
`realName` varchar(8) DEFAULT NULL,
`sex` varchar(4) DEFAULT NULL,
`address` varchar(255) DEFAULT NULL,
`question` varchar(50) DEFAULT NULL,
`answer` varchar(50) DEFAULT NULL,
`email` varchar(50) DEFAULT NULL,
`favorate` varchar(50) DEFAULT NULL,
`score` int(4) unsigned DEFAULT '0',
`regDate` date DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
/*Data for the table `user_info` */
insert into `user_info`(`id`,`userName`,`password`,`realName`,`sex`,`address`,`question`,`answer`,`email`,`favorate`,`score`,`regDate`)
values (1,'tom','123456','汤姆','女','江苏省苏州市吴中区','您的出生地是','江苏苏州','[email protected]','电脑,手机,相机',0,'2013-07-14'),
(2,'john','123456','约翰','女','江苏省南京市玄武区','您的出生地是?','江苏南京','[email protected]','电脑,手机,',0,'2013-07-14'),
(3,'my','123456','my','男','江苏省南京市玄武区','您的出生地是?','江苏南京','[email protected]','电脑,手机,',0,'2015-09-16'),
(4,'sj','123456','sj','男','江苏省南京市玄武区','您的出生地是?','江苏南京','[email protected]','手机',0,'2015-09-16'),
(5,'lxf','123456','lxf','男','江苏省南京市玄武区','您父亲的生日是?','1950-1-1','[email protected]','手机',0,'2015-09-16'),
(6,'lj','123456','lj','男','江苏省南京市玄武区','您母亲的生日是?','1949-1-1','[email protected]','手机',0,'2015-09-20');
public interface UserInfoDao {
// 查询所有
List selectUserInfo();
}
mapper.xml中的配置里边:
namespace的作用用于区分命名空间中的同名SQL映射的id(一般开发使用所对应的Dao接口全路径);
select属性中的id:必须为对应Dao接口中的方法名;
resultType为查询出来的结果类型。
// db.properties,用的是mysql8,所以driver是如下
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/digital
jdbc.username=root
jdbc.password=****
主配置文件名可以随意命名,主要完成以下几个功能:
(1)注册存放DB连接四要素的属性文件
(2)注册实体类的全限定性类名的别名
(3)配置Mybatis运行环境,即数据源与事务管理器
(4)注册映射文件
在设置别名typeAliases时,除了自定义的类型的别名外,Mybatis还提供了内置的类型别名:
基本类型(所以前面实体类的id要用Integer):
常用包装类型:
Mybatis的事务管理:JDBC、MANAGED
jdbc:使用jdbc的事务管理机制。即,通过Connection的commit()方法提交,通过rollback()方法回滚。但默认情况下,Mybatis将自动提交功能关闭了,改为了手动提交。即程序中需要显示的对事物进行提交和回滚。从日志的的输出信息中可以看到。
MANAGED:由容器来管理事务的整个生命周期(如Spring容器)。
dataSource标签:
该标签用于配置Mybatis使用的数据源类型与数据库连接基本属性。常见有类型有:UNPOOLED、POOLED、JDNI等。
UNPOOLED:不使用连接池。即每次请求,都会为其创建一个DB连接,使用完毕后,会马上将连接关闭。
POOLED:使用数据库连接池来维护连接。
JNDI:数据源可以定义到应用的外部,通过JNDI容器获取数据库连接。
使用“
(2)映射文件要与接口在同一包中
(3)映射文件中“mapper”的namespace属性值为Dao接口的全类名(接口的全路径)
一般可以使用package来指定包名来指定其包下多个mapper.xml;但需要满足几个条件:
(1)dao使用mapper动态代理实现(上面的配置就是)
(2)映射文件名要与Dao接口名称相同
(3)映射文件要与接口在同一包中
(4)映射文件中mapper的namesapce属性值为dao接口的全类名
public class SqlSessionUtil {
private static SqlSessionFactory sessionFactory;
public static SqlSession getSqlSession() {
try {
// 流关闭了吗??
InputStream iStream = Resources.getResourceAsStream("com/hsc/mybatisconfig.xml");
System.out.println(iStream.toString());
if (sessionFactory == null) {
sessionFactory = new SqlSessionFactoryBuilder().build(iStream);
}
return sessionFactory.openSession();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
相关API详解:
Dao中需要通过SqlSession对象来操作DB。而SqlSession对象的创建,需要其工厂对象SqlSessionFactory。SqlSessionFactory对象,需要通过其构建器对象SqlSessionFactoryBuilder的build()方法,在加载了主配置文件的输入流对象后创建。
Resources类:
顾名思义就是资源,用于读取资源文件。其有很多方法通过加载并解析资源文件,返回不同类型的IO流对象。
SqlSessionFactoryBuilder类:
SqlSessionFactory的创建,需要使用SqlSessionFactoryBuilder对象的build()方法。由于SqlSessionFactoryBuilder对象在创建完工厂对象后,就完成了其历史使用,即可被销毁。所以,一般会将该SqlSessionFactoryBuilder对象创建为一个方法内的局部对象,方法结束,对象销毁。其被重载的build()方法较多:
SqlSessionFactory接口:
SqlSessionfactory接口对象是一个重量级对象(系统开销大的对象),是线程安全的,所以一个应用只需要一个该对象即可。创建SqlSession需要使用SqlSessionFactory接口的openSession()方法。
(1)openSession(true):创建一个有自动提交功能的SqlSession
(2)openSession(false):创建一个非自动提交功能的SqlSession,需要手动提交
(3)openSession():同openSession(false)
SqlSession接口:
SqlSession接口对象用于执行持久化操作。一个SqlSession对应着一次数据库回话,一次回话以SqlSession对象的创建开始,以SqlSession对象的关闭结束。
SqlSession接口对象是线程不安全的,所以每次数据库回话结束前,需要马上调用其close()方法,将其关闭。再次需要回话,再次创建。而在关闭时会判断当前的SqlSession是否被提交:若没有被提交,则会执行回滚后关闭;若已提交,则直接将SqlSession关闭。所以,SqlSession无需手工回滚。
上面工具类里边提到了IO流关闭了吗?
我们来看SqlSessionFactoryBuilder对象的build()方法会自动将输入流关闭。
public class Test{
public SqlSession session;
public UserInfoDao dao;
@Before
public void setProa() {
session = SqlSessionUtil.getSqlSession();
dao = session.getMapper(UserInfoDao.class);
}
@After
public void close(){
if (session != null) {
session.close();
session = null;
}
}
@Test
public void test02() {
List list = dao.selectUserInfo();
System.out.println(list.size());
}
}