1、一个简单的MyBatis案例。
(1)新建一个java项目。导入jar包。jar包从官网下载MyBatis的源码,源码里面有主jar包以及lib里面的依赖jar包,都拷贝过来。其次,我们还用到数据库,这里用的是mysql的,所以再把数据库驱动的jar包也导进来。
(2)下面是结构目录。
文件打包下载地址:MyBatis简单入门程序
(3)说说思路。
——首先是主配置文件,这个名字好像约定俗成了,大家都这么叫,放在src下面,叫sqlMapConfig.xml
,里面核心的就是说明有哪些“映射文件”,也就是mapper文件。
<?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整合后 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="root" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="sqlMap/User.xml"/>
</mappers>
</configuration>
——自然的下面就是那些mapper文件了,其实就是我们跟数据库中每一张表打交道的东西。这里用了select标签,还要delete等其他标签,这里需要定义命名空间和标签的id,这两个加起来相当于唯一的,也就是说我们在具体调用的时候可能是用user.findUserById
作为唯一标识,这样才能锁定到这个语句来。当然还有参数是传入数据的类型,以及结果类型,这里的resultType
是自动化的结果类型,我们直接传入pojo类,如果我们的pojo类的属性和table里面的字段名称不一致的话就不能用这个,需要用手动的resultMap
。里面就是sql语句,这也是和hibernate不一样的地方,这边相当于直接写完整的sql语句了,注意的是这里的占位符的格式,里面的v可以随便取其他名称。
<?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:命名空间,用于隔离sql -->
<mapper namespace="user">
<select id="findUserById" parameterType="Integer" resultType="com.itheima.mybatis.pojo.User">
select * from user where id = #{v}
</select>
</mapper>
——下面就是具体用了。用的时候也是先加载资源,然后利用这个资源,我们建个工厂,然后利用这个工厂生成一个SqlSession,利用这个SqlSession去操作数据。这些类都在MyBatis包里面,可以自己查看。
public class MyBatisTest {
@Test
public void test01() throws IOException{
String resource = "sqlMapConfig.xml";
InputStream in = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession = sqlSessionFactory.openSession();
User u =(User)sqlSession.selectOne("user.findUserById", 10);
System.out.println(u);
}
}
——查询成功,结果就是:
User [id=10,username=张三,sex=1,birthday=Thu Jul 10 00:00:00 CST 2014,address=北京市
2、扩展-模糊查询多个。
——模糊查询多个的时候,在User.xml
里下面两种方式都行,但是第一种不能防止注入,而且第一种相当于字符串拼接,第二种才是占位符的写法,而且第一种里面只能用value
不能写其他的。注意的是,这里的resultType并不是一个List,而依然是我们最终的pojo类。
<select id="findUserByUsername" parameterType="String" resultType="com.itheima.mybatis.pojo.User">
<!-- select * from user where username like '%${value}%' -->
select * from user where username like "%"#{v}"%"
</select>
——我们用的时候自然也要改变,结果是一个List。
List<User> us = sqlSession.selectList("user.findUserByUsername", "五");
for(User u1 : us){
System.out.println(u1);
}
3、扩展-插入数据。
——插入数据的类型是pojo类。里面sql语句值得注意。只需要一一对应用占位符即可,不需要写成user.username
这种形式。
<insert id="insertUser" parameterType="com.itheima.mybatis.pojo.User">
insert into user(username,sex,birthday,address) values(#{username},#{sex},#{birthday},#{address})
</insert>
——使用的时候直接用:
User u2 = new User();
u2.setUsername("测试");
u2.setSex("男");
u2.setBirthday(new Date());
u2.setAddress("在哪里");
int i = sqlSession.insert("user.insertUser", u2);
sqlSession.commit();
4、插入数据并返回主键。就是在选择的时候增加选择主键的函数。
<insert id="insertUser" parameterType="com.itheima.mybatis.pojo.User">
<selectKey keyProperty="id" order="AFTER" resultType="Integer">
select LAST_INSERT_ID()
</selectKey>
insert into user(username,sex,birthday,address) values(#{username},#{sex},#{birthday},#{address})
</insert>
User u3 = new User();
u3.setUsername("测试11");
u3.setSex("女");
u3.setBirthday(new Date());
u3.setAddress("where are u");
sqlSession.insert("user.insertUser", u3);
sqlSession.commit();
System.out.println(u3.getId());
5、更新。
<update id="updateUserById" parameterType="com.itheima.mybatis.pojo.User">
update user set username=#{username},sex=#{sex},address=#{address},birthday=#{birthday} where id=#{id}
</update>
User u = new User();
u.setId(33);
u.setUsername("hahha");
u.setSex("男");
u.setBirthday(new Date());
u.setAddress("家居假按揭啊");
sqlSession.update("user.updateUserById", u);
//发现用insert也是可以的
//sqlSession.insert("user.updateUserById", u);
sqlSession.commit();
6、删除。
sqlSession.delete("user.deleteUserById", 33);
sqlSession.commit();
<delete id="deleteUserById" parameterType="Integer">
delete from user where id=#{id}
</delete>
7、MyBatis与Hibernate的区别。
——MyBatis是需要手写sql语句的,所以不能算是一个完整的ORM框架。
——因为需要手写sql语句,所以如果是不一样的数据库,那么sql语句也会不同。也就是说如果更换数据库了,那么需要我们重写所有的sql语句,这也是MyBatis不是完整ORM框架的缺点。这也是为什么大部分公司选用Hibernate的原因,因为数据库迁移是有可能的。
8、Mapper动态代理,实际开发时的操作。
——我们一般需要写一个Dao文件。
package com.itheima.mybatis.dao;
import com.itheima.mybatis.pojo.User;
public interface UserDao {
public User findUserById(Integer id);
}
这是一个接口,接口里的函数不是胡乱写的,需要满足几个条件。
1. 函数名字要和User.xml文件中的id要一致。
2. 函数返回值和参数也要和User.xml中的一致。
3. 这个接口类要和User.xml联系起来,在User.xml中用命名空间联系起来。
<mapper namespace="com.itheima.mybatis.dao.UserDao">
<select id="findUserById" parameterType="Integer" resultType="com.itheima.mybatis.pojo.User">
select * from user where id = #{id}
</select>
</mapper>
——在使用的时候也有所需要,我们需要用getMapper方法动态生成。
public class MyBatisTest {
@Test
public void test01() throws IOException{
String resource = "sqlMapConfig.xml";
InputStream in = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
User u = userDao.findUserById(16);
System.out.println(u);
}
}
9、实际开发的时候,可以在sqlMapConfig.xml中进行特定的配置,比如多利用package包的设置方法等。