这是我们的UserMapper.xml文件
<?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接口名称--> <mapper namespace="cn.dai.mapper.UserMapper"> <!-- 我们的SQL语句使用这种标签来实现 --> <!-- id 是我们的Mapper接口中的 方法名称 --> <!-- resultType 表示查询的结果类型,因为是List 这里我们直接填写泛型的元素类型就好了 --> <select id="getUserList" resultType="cn.dai.pojo.User"> /* 这里填写我们的SQL语句 */ SELECT * FROM `user`; </select> </mapper>
mapper
映射配置文件的根标签,有且只能存在一个
namespace
是我们所绑定的Mapper接口类
select
表示SQL语句的标签,总共是CRUD4种SQL语句标签
即我们的:
SELECT
INSERT
UPDATE
DELETE
id
我们的对应的接口的方法名称
resultType
查询后的结果集类型,是List集合就是我们所泛型的类型
parameterType
参数类型,填写注入SQL的类型即可
DAO的编写流程 ×
Mapper的编写流程 √
1、编写接口
2、编写抽象SQL方法
3、编写接口映射配置文件
4、编写SQL标签
5、回到核心配置注册映射文件
补全我们的DAO接口,口胡是Mapper
public interface UserMapper { List<User> getUserList(); User getUserById(int id); int addUser(User user); int updateUserById(User user); int deleteUserById(int id); }
补全映射配置
<?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接口名称--> <mapper namespace="cn.dai.mapper.UserMapper"> <!-- 我们的SQL语句使用这种标签来实现 --> <!-- id 是我们的Mapper接口中的 方法名称 --> <!-- resultType 表示查询的结果类型,因为是List 这里我们直接填写泛型的元素类型就好了 --> <select id="getUserList" resultType="cn.dai.pojo.User"> /* 这里填写我们的SQL语句 */ SELECT * FROM `user`; </select> <!-- parameterType="int" 表示参数类型,也就是说我们只能配置1个参数--> <select id="getUserById" resultType="cn.dai.pojo.User" parameterType="int"> /* #{user_id} 表示预编译SQL注入,普通SQL注入是 ${} 这个里面的user_id是实体类的,不是数据表的 */ SELECT * FROM `user` WHERE `user_id` = #{user_id}; </select> <!-- 增删改都不需要填写结果类型,因为只返回操作的结果记录数 --> <insert id="addUser" parameterType="cn.dai.pojo.User" > /* 这里我们设置的自增,所以主键可以不需要设置,注入实例时主键为null即可 */ INSERT INTO `user`(user_name,user_password) VALUES(#{user_name},#{user_password}); </insert> <!-- 修改语句--> <update id="updateUserById" parameterType="cn.dai.pojo.User" > UPDATE `user` SET user_name = #{user_name}, user_password = #{user_password}) WHERE user_id = #{user_id}; </update> <!-- 删除语句--> <delete id="deleteUserById" parameterType="int"> DELETE FROM `user` WHERE user_id = #{user_id}; </delete> </mapper>
开始测试【核心配置已经注册了】
发现异常问题
我在这里找了很久才发现,Mybatis会将注释中的注入表达式也会读取
我们将 $ 符号和{}区分开来再进行测试
结果还是报错
因为前面的注释的预编译SQL注入也会读取
这个东西也要区分开来
再次测试,访问成功
实际上是这样映射的
我们可以把映射配置的user_id改成id试试
这样还是能被读取到,也就是说基本类型,只要类型一致,
Mybatis如果匹配不了标识符,就会根据类型匹配
只要符合类型,依然能够查询出来,不过最好还是规范书写
剩余的增删改测试
增加 INSERT
如果实体类对应主键类型是基本类型,在注入实体类对象时,这个主键不可为null,必须赋值,
在我们的数据表的主键约束中设置了自增约束,这个情况就很尴尬了
所以为什么要设置实体类的主键类型为包装类了
可以看到我们的操作结果返回了1,说明操作是成功的
但是,查看数据库之后,并没有这个记录,
这是因为Mybatis的事务管理是默认开启的!!!
执行提交
sqlSession.commit();
再次查看结果,成功
如果要关闭事物可以在获取会话对象时,注入参数为true
修改
写错一个字符都有可能不通过
@Test public void queryOne3(){ // 获取会话对象 SqlSession sqlSession = MybatisUtil.getSqlSession(); // 获得映射实现实例 UserMapper mapper = sqlSession.getMapper(UserMapper.class); // 调用接口方法 int r = mapper.updateUserById(new User(17,"阿花","332211")); System.out.println(r); // 成功再提交,否则无意义 if ( r > 1) sqlSession.commit(); // 释放资源 sqlSession.close(); }
测试成功
删除
@Test public void queryOne4(){ // 获取会话对象 SqlSession sqlSession = MybatisUtil.getSqlSession(); // 获得映射实现实例 UserMapper mapper = sqlSession.getMapper(UserMapper.class); // 调用接口方法 int i = mapper.deleteUserById(17); System.out.println(i); if ( i > 1) sqlSession.commit(); // 释放资源 sqlSession.close(); }
测试成功
出现的错误总结:
1、SQL语句注释中的注入表达式也会被Mybatis读取,
所以要小心表达式字符
2、参数的标识设置尽可能的规范
演示的这段虽然没有出错,
是因为基本类型Mybatis可以识别匹配,但是要注意!!!
3、Mybatis的事务管理的默认开启的
除了查询,增删改在执行成功的情况下需要提交
4、SQL语句不要写错.
我也是没看仔细
5、注意主键映射的Java数据类型
如果没有在数据表设置自增约束,
Java的映射数据类型,可以基本int也可以包装类
如果是自增列,Java对象注入SQL时可以写null,
int类型也不是不能写,就是主键的编号会打乱【不推荐】