1. mybatis的几个重要的对象
1.1 SqlSessionFactoryBuilder
SqlSessionFactoryBuilder用于创建SqlSessionFactory,SqlSessionFactory一旦创建完成就不需要SqlSessionFactoryBuilder了,因为SqlSession是通过SqlSessionFactory创建的,所以可以将SqlSessionFactoryBuilder当做一个工具类来使用,最佳使用范围是方法范围,即方法体内局部变量
1.2 SqlSessionFactory
SqlSessionFactory是一个接口,接口中定义了oppenSession的不同重载方法,SqlSessionFactory是最佳使用范围是整个应用运行期间,一旦创建后可以重复使用,通常以单例模式管理SqlSessionFactory
SqlSessionFactory通过SqlSessionFactoryBuilder创建
1.3 SqlSession
SqlSession是一个面向用户的接口,SqlSession中定义了数据库的操作方法,如:查询、插入、更新、删除等。
SqlSession通过SqlSessionFactory创建
每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能共享使用,它也是线程不安全的。因此最佳的范围是请求或者方法范围。绝对不能将SqlSession实例的引用放在一个类的静态字段或实例字段中。
所以,根据这些特性,可以设计如下工具类
package com.bjc.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;
}
}
2. 传统dao开发方式
所谓传统开发就是有接口,有实现类
例如:
接口:
package com.bjc.mybatis.dao;
import java.util.List;
import com.bjc.mybatis.pojo.User;
public interface UserDao {
User getUser(Integer id);
List<User> getUserByName(String username);
void insertUser(User user);
}
实现类:
package com.bjc.mybatis.dao;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import com.bjc.mybatis.pojo.User;
import com.bjc.mybatis.utils.SqlSessionFactoryUtils;
public class UserDaoImpl implements UserDao {
@Override
public User getUser(Integer id) {
SqlSession openSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
User u = openSession.selectOne("getUserById", id);
openSession.close();
return u;
}
@Override
public List<User> getUserByName(String username) {
SqlSession openSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
List<User> users = openSession.selectList("getUserByName", username);
openSession.close();
return users;
}
@Override
public void insertUser(User user) {
SqlSession openSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
openSession.insert("saveUser", user);
openSession.commit();
openSession.close();
}
}
配置:
<?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">
<mapper namespace="user">
<!-- id:sql id,sql语句的唯一标识
parameterType:入参数据类型
resultType:返回结果的数据类型
#{}:点位符,相当于jdbc的 ?
-->
<select id="getUserById" parameterType="int" resultType="com.bjc.mybatis.pojo.User">
SELECT id,
username,
birthday,
sex,
address
FROM user
where id = #{id}
</select>
<select id="getUserByName" parameterType="string" resultType="com.bjc.mybatis.pojo.User">
SELECT id,
`username`,
birthday,
sex,
address
FROM user
where `username` like '%${value}%'
</select>
<insert id="saveUser" parameterType="com.bjc.mybatis.pojo.User" useGeneratedKeys="true" keyProperty="id">
<!-- 配置主键返回 -->
<selectKey keyProperty="id" resultType="int" order="AFTER">
select last_insert_id()
</selectKey>
INSERT INTO mybatis.user (
username,
birthday,
sex,
address,
uuid2
)
VALUES(
#{username},
#{birthday},
#{sex},
#{address},
#{uuid2}
);
</insert>
<insert id="saveUser1" parameterType="com.bjc.mybatis.pojo.User" useGeneratedKeys="true" keyProperty="id">
<!-- 配置主键返回 -->
<selectKey keyProperty="uuid2" resultType="string" order="BEFORE">
select UUID()
</selectKey>
INSERT INTO mybatis.user
(
username,
birthday,
sex,
address,
uuid2
)
VALUES
(
#{username},
#{birthday},
#{sex},
#{address},
#{uuid2}
);
</insert>
<update id="updateUser" parameterType="com.bjc.mybatis.pojo.User">
update user
set
username=#{username},
address=#{address}
where id=#{id}
</update>
<delete id="delUser" parameterType="int">
delete from user where id=#{id}
</delete>
</mapper>
测试类:
package com.bjc.mybatis.test;
import static org.junit.Assert.*;
import java.util.List;
import org.junit.Test;
import com.bjc.mybatis.dao.UserDao;
import com.bjc.mybatis.dao.UserDaoImpl;
import com.bjc.mybatis.pojo.User;
public class UserDaoImpTest {
@Test
public void testGetUser() {
UserDao userDao = new UserDaoImpl();
User user = userDao.getUser(22);
System.out.println(user);
}
@Test
public void testGetUserByName() {
UserDao userDao = new UserDaoImpl();
List<User> userByName = userDao.getUserByName("张");
System.out.println(userByName.toString());
}
@Test
public void testInsertUser() {
UserDao userDao = new UserDaoImpl();
User u = new User();
u.setAddress("xxx");
u.setUsername("Jack");
userDao.insertUser(u);
}
}
3. 动态代理开发方式
动态代理开发模式只有接口没有实现类
3.1 动态代理的4个开发规则
1. namespace必须是接口的全路径名
2. 接口的方法名必须与sql的id属性值一致
3. 接口的入参必须与parameterType的的类型一致
4. 接口的返回值必须与resultType类型一致
3.2 动态代理开发
只需要两步:
1. 新建接口
2. 新建对应的配置文件
例如:
接口
public interface UserMapper {
User getUserByID(Integer id);
List<User> getUserByName(String username);
void insertUser(User user);
}
配置文件:
<?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">
<mapper namespace="com.bjc.mybatis.mapper.UserMapper">
<select id="getUserByID" parameterType="int" resultType="com.bjc.mybatis.pojo.User">
SELECT id,
username,
birthday,
sex,
address
FROM user
where id = #{id}
</select>
<select id="getUserByName" parameterType="string" resultType="com.bjc.mybatis.pojo.User">
SELECT id,
`username`,
birthday,
sex,
address
FROM user
where `username` like '%${value}%'
</select>
<insert id="insertUser" parameterType="com.bjc.mybatis.pojo.User" useGeneratedKeys="true" keyProperty="id">
<!-- 配置主键返回 -->
<selectKey keyProperty="id" resultType="int" order="AFTER">
select last_insert_id()
</selectKey>
INSERT INTO mybatis.user (
username,
birthday,
sex,
address,
uuid2
)
VALUES(
#{username},
#{birthday},
#{sex},
#{address},
#{uuid2}
);
</insert>
<delete id="delUser" parameterType="int">
delete from user where id=#{id}
</delete>
</mapper>
应用配置文件:在核心配置文件SqlMapper.xml中配置
<mapper resource="mybatis/userMapper.xml"></mapper>
测试方法:
public void testGetUser() {
SqlSession openSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
// 获取接口的代理人的实现类
UserMapper mapper = openSession.getMapper(UserMapper.class);
User u = mapper.getUserByID(22);
System.out.println(u);
}
注意:动态代理方式开发只需要接口不需要实现类,并不是表示没有实现类,实现类有mybatis来实现的,我们只需要调用其接口openSession.getMapper(UserMapper.class);来获取对应的实现类即可。