一、在前一篇中,存在一些问题:
1. 没有使用接口编程,Java是面向接口编程语言。应该对数据库操作定义一些接口,调用dao接口完成数据库操作。
public interface UserDao { //根据Id查询用户信息 public User findUserById(int userId) throws Exception; //添加用户 public void insertUser(User user) throws Exception; //修改用户 public void updateUser(User user) throws Exception; //删除用户 public void deleteUser(int userId) throws Exception; } public class UserDaoImpl implements UserDao { private SqlSessionFactory sqlSessionFactory; //通过spring将 SqlSessionFactory 注入,这里没有spring,暂时使用构造方法代替 public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) { this.sqlSessionFactory = sqlSessionFactory; } public UserDaoImpl(SqlSessionFactory sqlSessionFactory) { this.setSqlSessionFactory(sqlSessionFactory); } @Override public User findUserById(int userId) throws Exception { SqlSession sqlSession = null; User user = null; try { //通过SqlSessionFactory获取SqlSession sqlSession = sqlSessionFactory.openSession(); //使用session操作数据库 //selectOne第一个参数:指定sql的id(statement id),注意带上namespace;第二个参数:向sql中传的参数值 user = sqlSession.selectOne("test.findUserById", userId); System.out.println(user); } catch (Exception e) { // TODO: handle exception } finally { if (sqlSession != null) { sqlSession.close(); } } return user; } @Override public void insertUser(User user) throws Exception { SqlSession sqlSession = null; try { //通过SqlSessionFactory获取SqlSession sqlSession = sqlSessionFactory.openSession(); //使用session操作数据库 sqlSession.insert("test.insertUser", user); //提交事务 sqlSession.commit(); } catch (Exception e) { // TODO: handle exception } finally { if (sqlSession != null) { sqlSession.close(); } } } }
2. 虽然上面改写成Dao接口实现类的方式,但访问sql映射文件中定义的sql时需要调用 SqlSession 的 selectOne() 方法, 并将 sql 的位置(命名空间 + id)和参数传递到 selectOne() 方法中,且第一个参数是长字符串,第二个参数是object 对象,编写代码时出现错误无法 在编译阶段发现。
优化:
第一步:定义UserMapper.xml, 还用原来的不用变
第二步:定义mapper接口
public interface UserMapper { //根据Id查询用户信息 public User findUserById(int userId) throws Exception; //添加用户 public void insertUser(User user) throws Exception; //修改用户 public void updateUserById(User user) throws Exception; //删除用户 public void deleteUserById(int userId) throws Exception; }
接口定义有以下特点:
a. Mapper 接口方法名和 UserMapper.xml 中定义的每个 sql 的 id 同名。
b. Mapper 接口方法的输入参数类型和 UserMapper.xml 中定义的 sql parameterType 类型相同。
c. Mapper 接口的输出参数类型和 UserMapper.xml 中 定义的 sql 的 resultType 类型相同。
第三步:修改 UserMapper.xml 的namespace
修改后的 namespace 即是 Mapper 接口的类路径。
<mapper namespace="mybatis.mapper.UserMapper">
第四步:通过 Mapper 接口调用statement 去操作数据库
public class UserMapperTest extends TestCase { private SqlSessionFactory sqlSessionFactory; String resource = "SqlMapConfig.xml"; //任何测试方法都要执行的方法 @Override protected void setUp() throws Exception { super.setUp(); //通过输入流读取配置文件 InputStream inputStream = Resources.getResourceAsStream(resource); //获取SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } public User testFindUserById() throws Exception { //获取SqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); //指定 mapper 接口的类型,MyBatis通过动态代理的方式实现mapper接口 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = userMapper.findUserById(100101); sqlSession.commit(); sqlSession.close(); //查询主键为100101的用户并输出 System.out.println("user---" + user); return user; } public void testInsertUser() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); //指定 mapper 接口的类型,MyBatis通过动态代理的方式实现mapper接口 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = new User(); user.setUsername("Dina"); user.setSex("0"); user.setBirthday(new Date()); user.setAddress("Redwood City"); user.setDetail("good person"); user.setScore(99.2f); userMapper.insertUser(user); sqlSession.commit(); sqlSession.close(); } public void testUpdateUserById() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); //指定 mapper 接口的类型,MyBatis通过动态代理的方式实现mapper接口 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = new User(); user.setUserId(100102); user.setUsername("Golden"); user.setSex("0"); user.setBirthday(new Date()); user.setAddress("Shen zhen"); user.setDetail("good person"); user.setScore(89.2f); userMapper.updateUserById(user); sqlSession.commit(); sqlSession.close(); } public void testDeleteUserById() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); userMapper.deleteUserById(100110); sqlSession.commit(); sqlSession.close(); } }
总结:
使用 Mapper 接口的方式,不用写接口实现类接口完成数据库操作,简单方便,此方法是官方推荐。
是MyBatis一种很重要的用法。
使用 Mapper 接口调用必须具备以下条件:
- Mapper 接口方法名 和 UserMapper.xml 中定义的每个 sql 的 id 同名。
- Mapper 接口方法的输入参数类型和 UserMapper.xml 中定义的 sql parameterType 类型相同。
- Mapper 接口的输出参数类型和 UserMapper.xml 中 定义的 sql 的 resultType 类型相同。
- UserMapper.xml 文件中的 namespace 即是 Mapper 接口的类路径。
时间: 2024-10-10 12:12:08