一,介绍
今天来介绍一个和hibernate很像,但是又有不同的框架,他的名字叫做mybatis,
他的前身是ibatis,是阿帕奇的一个开源项目,这个项目后面转到谷歌,正式
改名叫做myIbatis,同时在功能上,比ibatis又有所加强
二,hibernate和ibatis的区别
首先,这两个框架都是对数据库访问的封装,都是持久层框架,但是两者有很大的不同
1.mybatis是持久层框架,而hibernate是属于对象关系映射
(ORM)框架,即mybatis需要程序员自己写sql,而hibernate不需要,不过mybatis可以使用逆向 工程
来自动生成sql
2.学习门槛:mybatis比hibernate低。
hibernate是一个比较重的框架相比于mybatis,但是相对应的功能比mybatis也要更加强大,
相应的学习成本就会很高,而mybatis只是对jdbc进行些 封 装,所以学习成本低了很多
3.应用的领域:
对于中小型项目,且需求固定,关系模型相对固定建议使用hibernate。适用传统项目,比如ERP。
对于需求不固定的项目,比如:互联网项目,建议使用mybatis,可以灵活去编写sql语句。
三,建立第一个Mybatis程序
学习一个框架,首先要知道这个框架是做什么的,其次要知道框架是怎么使用的,好的,我们已经知道了mybatis是一个持久层框架,现在我们来看看,
这个框架是如何使用的,让我们来写一个demo来看看
(一).准备 jar包,如下图
这是编写mybatis所需的jar包,注意mybatis-3.4.4这个核心包,mysql-connector-java,这个jdbc驱动包,用来连接数据库的。我使用是3.4.4版本
点击上面的地址即可
(二),配置内容
配置文件目录如下图
1.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
2.sqlMapConfig.xml
mybatis的全局配置文件,里面配置了mybatis运行所需要的所有配置属性,和hibernate的hibernate.cfg.xml是一样,因为在和spring整合时
我们会把他写到spring的配置文件中,所以此处的配置文件,仅仅是写demo所用,以后全部可以写到spring中,内容如下
<?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>
<!-- 和spring整合environment配置将废除 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 配置Mapping映射文件 -->
<mappers>
<mapper resource="sqlMap/User.xml"/>
</mappers>
</configuration>
感觉是不是和hibernate的配置文件一样,对就是一样的结构,上面的jdbc配置,以后可以写到配置文件中,便于维护,映射文件可以使用包扫描器,就不需要再配置了,以后再说,先就这样配置
3.配置PO类
建议po类名和表名一致,属性名和表字段名一致。
public class User {
private int id;
private String username;
private String sex;
private Date birthday;
private String address;
private String detail;
private Float score;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
public Float getScore() {
return score;
}
public void setScore(Float score) {
this.score = score;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", sex=" + sex
+ ", birthday=" + birthday + ", address=" + address
+ ", detail=" + detail + ", score=" + score + "]";
}
}
这只是一个demo,请根据你的项目的功能,来编写po类
4.配置mapper.xml映射文件(和PO类对应,和hibernate的XXX.hbm.xml一样)
就是上图中user.xml在sqlmap中的,内容如下
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace命令空间特殊作用,如果使用mapper动态代理方法,这里就需要配置mapper接口地址 -->
<mapper namespace="test">
<!--根据用户id查宿一条记录(返回单条记录)-->
<!--
select标签表示sql查询,内容会封装到Mapped Statement中。
可以将这个select标签称为一个Statement
id:Statement的id,用于标识select中定义的sql,id是同一个命名空间中不允许重复
#{}:表示一个占位符,避免sql注入
parameterType:表示输入参数的类型
resultType:表示输出 结果集单条记录映射的java对象类型,select查询得到字段名和resultType中属性名一致,才能映射成功
-->
<select id="findUserById" parameterType="int" resultType="com.itheima.mybatis.po.User">
SELECT * FROM USER WHERE id=#{id}
</select>
<!-- 查询用户列表(返回List集合)-->
<!--
不管结果查询一条还是多条,resultType指定结果集单条记录映射的java对象类型
${}:表示sql拼接,相当于sql字符串拼接,无法避免sql注入
${value}:value表示parameter输入参数的变量,如果输入参数是简单类型,使用${}拼接符,变量名必须使用value
${value}直接将value获取到拼接在sql中,value值不加任何修饰
-->
<select id="findUserList" parameterType="java.lang.String" resultType="com.itheima.mybatis.po.User">
SELECT * FROM USER WHERE username LIKE '%${value}%';
</select>
<!-- 添加用户
parameterType:如果paramterType指定是POJO,在#{}中指定pojo的属性名获取该pojo属性值
-->
<insert id="insertUser" parameterType="com.itheima.mybatis.po.User">
<!--
keyProperty:将主键设置到pojo中那个属性中
order:selectKey中sql执行的时机
resultType:selectKey中sql的执行的结果类型
LAST_INSERT_ID:是insert后获取自增主键值
-->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
select LAST_INSERT_ID();
</selectKey>
insert into user(username,birthday,sex,address,detail,score)
values(#{username},#{birthday},#{sex},#{address},#{detail},#{score})
</insert>
<!-- 根据主键删除用户 -->
<delete id="deleteUser" parameterType="int">
delete from user where id=#{id}
</delete>
<!-- 根据主键用户更新
更新传入输入参数内容,id和更新的信息
-->
<update id="updateUser" parameterType="com.itheima.mybatis.po.User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
</update>
</mapper>
里面配置了一些数据库查询的方法,上面做了些说明,你可以把他看成dao中的findUserById(int id),这样的对数据库访问的方法
(三).测试Demo
好了,现在配置基本完成,现在来测试这个mybatis的作用了,下面列个demo测试
public class User_insert {
public static void main(String[] args) throws IOException {
//加载配置文件
String resource = "sqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//根据mybatis的配置创建sqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//根据SqlSessionFactory创建SqlSession
SqlSession session = sqlSessionFactory.openSession();
//创建对象,并给对象赋值
User user = new User();
user.setScore(78.5f);
user.setAddress("中国上海");
user.setBirthday(new Date());
user.setSex("女");
user.setUsername("吴舒婷");
//持久化对象
session.insert("test.insertUser",user);
session.commit();
session.close();
//打印主键
System.out.println("id="+user.getId());
}
}
它和hibernate一样,通过配置文件,生成一session工厂,透过工厂生成SqlSession,而session中对应一些方法,通过传入user.xml中定义的“方法”名,和参数
就能实现增删改的的操作,其他操作,你可以自己测试,这里就不演示了
(四),问题总结
好了,到目前为止,算是说完了mybatis的基本使用,现在我们来看看一些问题的处理
1.主键返回的问题
1.mysql自增主键的获取
2.uuid主键的获取
Uuid主键在insert语句执行前生成 的
如果使用uuid获取主键,定义selectkey
3.Oracle主键的返回
四,mybatis解决jdbc编程的问题(重要)
1、 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
解决:在SqlMapConfig.xml中配置数据链接池,使用连接池管理数据库链接。
2、 Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。
3、 向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。
解决:Mybatis自动将java对象映射至sql语句,通过statement中的parameterType定义输入参数的类型。
4、 对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。
解决:Mybatis自动将sql执行结果映射至java对象,通过statement中的resultType定义输出结果的类型。
五.mapper动态代理
处理上面的方式使用mybatis,框架还提供了一种更加灵活的方式使用框架,那就是动态代理
1.简述
Mapper动态代理方法:程序员只需要写dao接口(Mapper),而不需要写dao实现类,由mybatis根据dao接口
和映射文件中statement的定义生成接口实现代理对象。可以调用代理对象方法。
Mybatis官方建议:将dao接口叫做mapper。
目标:通过一些规则让mybatis根据dao接口和映射文件中statement的定义生成接口实现代理对象
mybatis将以下代码自动在代理对象实现:
User user =sqlSession.selectOne("test.findUserById", id);
2.使用
1.开发 mapper.xml文件
2.开发mapper.java接口
4.mapper开发的规则
六.总结
好了,这就是mybatis的使用方法,他和hibernate很像,在配置和结构上,但是他更加的灵活,适合使用变化度行强的项目中,比如电商这种
经常需要更改sql的项目,而hibernate是否那种一旦开发,就不会怎么变化的系统,比如仓库管理系统这种的