Mybatis在项目中主要使用的地方就是开发dao(数据访问层),所以下面讲解一下mybatis开发dao的方法。有两种方式:原始dao开发方式、mapper代理开发方式(推荐)。
1、根据用户ID来查询用户信息;
2、根据用户名称来模糊查询用户信息列表;
3、添加用户;
程序员需要写dao接口和dao实现类。
1、根据需求创建po类
2、编写全局配置文件
3、根据需求编写映射文件
4、加载映射文件
5、编写dao接口
6、编写dao实现类
7、编写测试代码
publicinterface UserDao {
//根据用户ID来查询用户信息
public User findUserById(int id);
//根据用户名称来模糊查询用户信息列表
public List
//添加用户
publicvoid insertUser(User user);
}
l SqlSessionFactoryBuilder,它的作用只是通过配置文件创建SqlSessionFactory,所以只要创建出SqlSessionFactory,它就可以销毁了。所以说,它的生命周期是在方法之内。
l SqlSessionFactory,它的作用是创建SqlSession的工厂,工厂一旦创建,除非应用停掉,不要销毁。所以说它的生命周期是在应用范围内。这里可以通过单例模式来管理它。在mybatis整合spring之后,最好的处理方式是把SqlSessionFactory交由spring来做单例管理。
l SqlSession是一个面向用户(程序员)的接口,它的默认实现是DefaultSqlSession。Mybatis是通过SqlSession来操作数据库的。SqlSession中不仅包含要处理的SQL信息,还包括一些数据信息,所以说它是线程不安全的,因此它最佳的生命周期范围是在方法体之内。
publicclass UserDaoImpl implements UserDao {
//注入SqlSessionFactory
private SqlSessionFactory sqlSessionFactory;
//使用构造方法来初始化SqlSessionFactory
public UserDaoImpl(SqlSessionFactorysqlSessionFactory){
this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public User findUserById(int id) {
//通过工厂,在方法内部获取SqlSession,这样就可以避免线程不安全
SqlSessionsqlSession = sqlSessionFactory.openSession();
//返回结果集
returnsqlSession.selectOne("test.findUserById", id);
}
@Override
public List
//通过工厂,在方法内部获取SqlSession,这样就可以避免线程不安全
SqlSessionsqlSession = sqlSessionFactory.openSession();
return sqlSession.selectList("test.findUsersByName", username);
}
@Override
publicvoid insertUser(User user) {
//通过工厂,在方法内部获取SqlSession,这样就可以避免线程不安全
SqlSessionsqlSession = sqlSessionFactory.openSession();
sqlSession.insert("test.insertUser", user);
}
}
publicclass UserDaoTest {
//声明全局的SqlSessionFactory
private SqlSessionFactory sqlSessionFactory;
@Before
publicvoid setUp() throws Exception {
// 1、读取配置文件
Stringresource = "SqlMapConfig.xml";
InputStreaminputStream = Resources.getResourceAsStream(resource);
// 2、根据配置文件创建SqlSessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
publicvoid testFindUserById() {
//构造UserDao对象
UserDaouserDao = new UserDaoImpl(sqlSessionFactory);
//调用UserDao对象的方法
Useruser = userDao.findUserById(1);
System.out.println(user);
}
@Test
publicvoid testFindUsersByName() {
//构造UserDao对象
UserDaouserDao = new UserDaoImpl(sqlSessionFactory);
//调用UserDao对象的方法
List
System.out.println(list);
}
@Test
publicvoid testInsertUser() {
//构造UserDao对象
UserDaouserDao = new UserDaoImpl(sqlSessionFactory);
//构造User对象
Useruser = new User();
user.setUsername("东哥3");
user.setAddress("清河宝盛西里3");
//调用UserDao对象的方法
userDao.insertUser(user);
System.out.println(user.getId());
}
}
原始dao开发存在一些问题:
Ø 存在一定量的模板代码。比如:通过SqlSessionFactory创建SqlSession;调用SqlSession的方法操作数据库;关闭Sqlsession。
Ø 存在一些硬编码。调用SqlSession的方法操作数据库时,需要指定statement的id,这里存在了硬编码。
1、mapper接口的全限定名要和mapper映射文件的namespace的值相同。
2、mapper接口的方法名称要和mapper映射文件中的statement的id相同;
3、mapper接口的方法参数只能有一个,且类型要和mapper映射文件中statement的parameterType的值保持一致。
4、mapper接口的返回值类型要和mapper映射文件中statement的resultType值或resultMap中的type值保持一致;
通过规范式的开发mapper接口,可以解决原始dao开发当中存在的问题:
1、模板代码已经去掉;
2、剩下去不掉的操作数据库的代码,其实就是一行代码。这行代码中硬编码的部分,通过第一和第二个规范就可以解决。
1、根据需求创建po类
2、编写全局配置文件
3、根据需求编写映射文件
4、加载映射文件
5、编写mapper接口
6、编写测试代码
重新定义mapper映射文件UserMapper.xml(内容同Users.xml,除了namespace的值),放到新创建的目录mapper下。
xml version="1.0" encoding="UTF-8"?>
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTDMapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.itcast.mybatis.mapper.UserMapper">
<select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User">
SELECT* FROM USER WHERE id = #{id}
select>
<select id="findUsersByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User">
SELECT* FROM USER WHERE username LIKE '%${value}%'
select>
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
<selectKey keyProperty="id" resultType="int"order="AFTER">
SELECT LAST_INSERT_ID()
selectKey>
INSERTINTO USER(username,sex,birthday,address) VALUES (#{username},#{sex},#{birthday},#{address})
insert>
mapper>
<mappers>
<mapper resource="sqlmap/User.xml"/>
<mapper resource="mapper/UserMapper.xml"/>
mappers>
内容同UserDao接口一样:
publicinterface UserMapper {
//根据用户ID来查询用户信息
public User findUserById(int id);
//根据用户名称来模糊查询用户信息列表
public List
//添加用户
publicvoid insertUser(User user);
}
publicclass UserMapperTest {
// 声明全局的SqlSessionFactory
private SqlSessionFactory sqlSessionFactory;
@Before
publicvoid setUp() throws Exception {
// 1、读取配置文件
Stringresource = "SqlMapConfig.xml";
InputStreaminputStream = Resources.getResourceAsStream(resource);
// 2、根据配置文件创建SqlSessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
publicvoid testFindUserById() {
// 创建SqlSession
SqlSessionsqlSession = sqlSessionFactory.openSession();
// 通过SqlSession,获取mapper接口的动态代理对象
UserMapperuserMapper = sqlSession.getMapper(UserMapper.class);
// 调用mapper对象的方法
Useruser = userMapper.findUserById(1);
System.out.println(user);
// 关闭SqlSession
sqlSession.close();
}
@Test
publicvoid testFindUsersByName() {
// 创建SqlSession
SqlSessionsqlSession = sqlSessionFactory.openSession();
// 通过SqlSession,获取mapper接口的动态代理对象
UserMapperuserMapper = sqlSession.getMapper(UserMapper.class);
// 调用mapper对象的方法
List
System.out.println(list);
// 关闭SqlSession
sqlSession.close();
}
@Test
publicvoid testInsertUser() {
// 创建SqlSession
SqlSessionsqlSession = sqlSessionFactory.openSession();
// 通过SqlSession,获取mapper接口的动态代理对象
UserMapperuserMapper = sqlSession.getMapper(UserMapper.class);
//构造User对象
Useruser = new User();
user.setUsername("东哥4");
user.setAddress("清河宝盛西里4");
// 调用mapper对象的方法
userMapper.insertUser(user);
System.out.println(user.getId());
//执行SqlSession的commit操作
sqlSession.commit();
// 关闭SqlSession
sqlSession.close();
}
}