框架增删改查"/>
02 MyBatis框架增删改查
目录
一、UserMapper.xml映射文件
二、优化测试方法
三、MyBatis新增
四、MyBatis修改
五、MyBatis删除
六、MyBatis根据Id查询
七、MyBatis模糊查询(三种方式)
八、MyBatis分页查询(4种方法)
1.分页查询方法1(顺序传参):
2.分页查询方法2(@Param()传参):
3.分页查询方法3(POJO传参):
4.分页查询方法4(Map传参):
5.知识点整理:
九、MyBatis聚合查询
十、MyBatis主键回填
十一、映射文件中parameterType=“”参数传入规则
一、UserMapper.xml映射文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapperPUBLIC "-//mybatis//DTD Mapper 3.0//EN"".dtd"><!--映射文件要和持久层接口名称相同;如:UserMapper对应UserMapper.xml--> <!--映射文件要和持久层接口的目录结构相同:如com.itbaizhan.mapper.Usermapper.xml--> <!--映射文件中namespace属性要写持久层接口的全名(包名+接口名)如:com.itbaizhan.mapper.UserMapper--> <!--映射文件中标签的id属性是持久层接口方法中要具体实现的那一个方法名;如findAll--> <!--映射文件中标签的resultType属性(结果类型)是接口方法的返回值类型,如果是集合+泛型的,返回值类型是泛型的全类名,如List<User>,返回类型是User类的全类名(包名+类名)--> <!--映射文件中标签的parameterType属性是接口方法中参数的类型,不是方法名的返回类型--> <!--映射文件中resultType、parameterType属性要写全类名,如果是集合类型,则写其泛型的全类名--><mapper namespace="com.itbaizhan.mapper.UserMapper"></mapper>
二、优化测试方法
前言:
通过Junit前置后置方法@Before、@After,将创建对象放入前置方法,关闭对象放在后置方法,test测试方法只写关键语句。
public class TestUserMapper2 {InputStream is = null;SqlSession session = null;UserMapper userMapper = null;@Beforepublic void before() throws IOException {// (1)读取核心配置文件is = Resources.getResourceAsStream("SqlMapConfig.xml"); // (2) 创建SqlSessionFactoryBuild对象SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); // (3)SqlSessionFactoryBuilder对象获取SqlSessionFactory对象SqlSessionFactory factory = builder.build(is); // (4)SqlSessionFactory对象获取SqlSession对象session = factory.openSession(); // (5)SqlSession对象获取代理对象userMapper = session.getMapper(UserMapper.class);}@Afterpublic void after() throws IOException { // 释放资源session.close();is.close();}
三、MyBatis新增
1.持久层接口添加新增方法
// 新增方法void add(User user);
2.映射文件添加标签
<!--注意事项:--> <!--1.如果方法没有返回类型(即void),则不用resultType。--> <!--2.parameterType是方法中参数的返回类型,如void add(User user),应填入User类的全类名--> <!--3.当接口方法的参数类型为POJO类型时,SQL语句中绑定参数时使用#{POJO的属性名}即可--> <!--插入数据--><insert id="add" parameterType="com.itbaizhan.pojo.User">insert into user(username,sex,address) values(#{username},#{sex},#{address})</insert>
3.编写测试方法
@Test //测试向数据库添加元素public void testAdd() throws IOException { // 代理对象执行方法User user = new User("程序员","男","上海");userMapper.add(user); // 注意:事务提交。增删改操作都需要提交事务。 // Mybatis事务默认手动提交,所以在执行完增删改查方法后,需要手动调用session对象 // 的事务提交方法,否则数据库将不发生改变。 // 可以将factory.openSession()设置为true,关闭手动提交。sessionmit();}
4.注意:
- 当接口方法的参数类型为POJO类型时,SQL语句中绑定参数时使用#{POJO的属性名}即可。
- MyBatis事务默认手动提交,所以子执行完增删改方法之后后,需要手动调用SqlSession对象的事务提交方法,否则数据库将不发生改变。
5.知识点整理:
5.1.接口方法的数据类型为POJO类型,SQL语句中绑定参数时使用“#{POJO属性名}”
5.2.在MyBatis中,执行“查询”操作后不需要手动提交事务,执行“增删改”操作后需要手动提交事务。
四、MyBatis修改
1.持久层接口添加修改方法
// 更新方法void update(User user);
2.映射文件添加标签
<!--更新数据--><update id="update" parameterType="com.itbaizhan.pojo.User">update user set username=#{username},sex=#{sex},address=#{address} where id=#{id}</update>
3.编写测试方法
@Testpublic void testUpdate(){User user = new User(14,"程序员2","女","深圳");userMapper.update(user);sessionmit();}
4.知识点整理:
4.1.MyBatis修改方法映射文件的标签是“<update>”
4.2.Junit前置方法的注解为@Before
五、MyBatis删除
1.持久层接口添加删除方法
// 删除方法void delete(int userId);
2.映射文件添加标签
<!--注意事项:--> <!--当方法的参数类型为POJO类型时,传入的格式为#{POJO的属性名}--> <!--当方法的参数类型为简单数据类型时(基本数据类型、字符串等),传入的格式为#{任意名称},如下:--> <!--删除数据--><delete id="delete" parameterType="int">delete from user where id = #{userId}</delete>
注意:
(1)当方法的参数类型是简单数据类型时,#{}中可以写任意名称
(2)简单数据类型:基本数据类型、字符串
3.编写测试方法
@Testpublic void testDelete(){userMapper.delete(15);sessionmit();}
六、MyBatis根据Id查询
1.持久层接口添加(根据Id查询)方法
// 通过id查找数据方法User findById(int userId);
2.映射文件添加标签
<!--通过id查询数据--><select id="findById" parameterType="int" resultType="com.itbaizhan.pojo.User">select * from user where id = #{userId}</select>
3.编写测试方法
@Testpublic void testFindById(){User user = userMapper.findById(6);System.out.println(user);}
4.知识点整理:
4.1.MyBatis删除方法映射文件的标签是“<delete>”
4.2.当方法的参数类型是简单数据类型时,SQL语句应表示为“#{任意名称}”
七、MyBatis模糊查询(三种方式)
1.持久层接口添加模糊查询方法
// 模糊查询方法List<User> findByLike(String username);
2.映射文件添加标签
<!--通过字符串模糊查询--><!--模糊查询方式1:用#{}预编译处理--><select id="findByLike" parameterType="string" resultType="com.itbaizhan.pojo.User">select * from user where username like #{username}</select><!--模糊查询方式2:用${}字符串代替,注意,${}里面必须是value,其他变量名不符合--><select id="findByLike" parameterType="string" resultType="com.itbaizhan.pojo.User">select * from user where username like '%${value}%'</select><!--模糊查询方式3:用<bind>,这样就可以又用#{},又可以查询时不写%%--><select id="findByLike" parameterType="string" resultType="com.itbaizhan.pojo.User"><bind name="likename" value="'%'+username+'%'"/>select * from user where username like #{likename}</select>
3.编写测试方法
@Testpublic void testFindByLike(){ // <!--模糊查询方式1:用#{}预编译处理--> // List<User> user = userMapper.findByLike("%尚学堂%"); // <!--模糊查询方式2:用${}字符串代替,注意,${}里面必须是value,其他变量名不符合-->List<User> users = userMapper.findByLike("尚学堂"); // user.forEach(System.out::println);users.forEach(System.out::println);}
4.#{}和${}的区别 :
1.#{}是预编译处理,相当于?,表示sql模板的占位符;${}是字符串替换,表示将字符串拼接到sql模板中;如下:
<!--模糊查询方式2:用${}字符串代替,注意,${}里面必须是value,其他变量名不符合--><select id="findByLike" parameterType="string" resultType="com.itbaizhan.pojo.User">select * from user where username like '%${value}%'</select>
2..#可以防止sql注入,提高系统的安全性,一般能用#就不用$。
3.${}内部的参数名必须写value。
5.知识点整理:
5.1.在MyBatis中,String数据类型的别名为“string”
5.2.在MyBatis映射文件中,关于参数类型的写法:可以写全类名,也可以写别名
5.3.在MyBatis中,${}中的参数必须写value;#{}表示SQL模板占位符,可以防止SQL注入。
5.4.在MyBatis中,使用“<bind>”标签可以定义外部变量,绑定到SQL语句中;如:
<!--模糊查询方式3:用<bind>,这样就可以又用#{},又可以查询时不写%%--><select id="findByLike" parameterType="string" resultType="com.itbaizhan.pojo.User"><bind name="likename" value="'%'+username+'%'"/>select * from user where username like #{likename}</select>
八、MyBatis分页查询(4种方法)
前言:
分页查询时,Sql语句使用limit关键字,需要传入开始索引和每页条数两个参数。
1.分页查询方法1(顺序传参):
前言:
SQL中的参数使用arg0、arg1...或param1、param2...表示参数的顺序。这种方法可读性较低,在开发中不建议使用。
(1)持久层接口添加分页查询方法1
/**** @param startIndex 分页查询开始位置* @param pageSize 分页查询每页展示多少条数据* @return*/ // 分页查询方法1List<User> findPage1(int startIndex,int pageSize);
(2)映射文件添加标签
<!--分页查询1.1(顺序传参):通过limit语句进行分页查询1(不建议使用)--><!--注意:1.为什么不用paramType=""的形式进行传参,因为有两个或两个以上的变量时,不好区分传入的是哪个变量2.arg从0开始:arg1、arg1、、、param从1开始:param1、param2、、、--><select id="findPage1" resultType="com.itbaizhan.pojo.User">select * from User limit #{arg0},#{arg1}</select><!--分页查询1.2(顺序传参):通过limit语句进行分页查询2(不建议使用)--><select id="findPage1" resultType="com.itbaizhan.pojo.User">select * from user limit #{param1},#{param2}</select>
(3)编写测试方法
@Testpublic void testFindPage1(){List<User> user = userMapper.findPage1(2,4);user.forEach(System.out::println);}
2.分页查询方法2(@Param()传参):
前言:
在接口方法的参数列表中通过@Param定义参数名称,在SQL语句中通过注解中所定义的参数名称指定参数位置。注意@Param()填入的是字符串,要带双引号“”。此方式参数比较直观,经常使用。
(1)持久层接口添加分页查询方法2
// 分页查询方法2 // 注意:@param(),括号里面填字符串类型,要加双引号List<User> findPage2(@Param("startIndex") int startIndex,@Param("pageSize") int pageSize);
(2)映射文件添加标签
<!--分页查询2(@Param传参):通过@Param()注解的方式进行分页查询(建议使用)--><!--注意:#{}里面的变量名要和方法中@Param()括号里面的变量名一致--><select id="findPage2" resultType="com.itbaizhan.pojo.User">select * from user limit #{startIndex},#{pageSize}</select>
(3)编写测试方法
@Testpublic void testFindPage2(){List<User> user = userMapper.findPage2(2,4);user.forEach(System.out::println);}
3.分页查询方法3(POJO传参):
前言:
自定义POJO类,该类的属性就是要传递的参数,在SQL语句中绑定参数时使用POJO的属性名作为参数名即可。这种方法较为常见,可以使用!
(1)自定义POJO
public class PageQuery {private int startIndex;private int pageSize; // 有参/无参构造器、setter/getter方法、toString方法省略 }
(2)持久层接口添加分页查询方法3
//分页查询方法3:如果觉得参数较多,可以使用POJO类型传参List<User> findPage3(PageQuery pageQuery);
(3)映射文件添加标签
<!--分页查询3(POJO传参):(就是创建一个实体类,类似于User类进行传参)--><!--注意:参数类型是PageQuery,返回结果类型还是User实体类--><select id="findPage3" parameterType="com.itbaizhan.pojo.PageQuery" resultType="com.itbaizhan.pojo.User">select * from user limit #{startIndex},#{pageSize}</select>
(4)编写测试方法
@Testpublic void testFindPage3(){PageQuery pageQuery = new PageQuery(2,4);List<User> user = userMapper.findPage3(pageQuery);user.forEach(System.out::println);}
4.分页查询方法4(Map传参):
前言:
如果不想自定义POJO,可以使用Map作为传递参数的载体,在SQL语句中绑定参数时使用Map的key作为参数名即可。这种方法较为常见,可以使用!
(1)持久层接口添加分页查询方法
// 分页查询方法4:通过Map集合传入key-value进行传参List<User> findPage4(Map<String,Object> params);
(2)映射文件添加标签
<!--分页查询4(Map传参):(通过key-value键值对进行传参)--><!--注意:1.参数类型是map,map是Map的别名,要小写2.#{}里的变量名可以任意写,但后面传入参数值的时候名字要与这里的变量名一致--><select id="findPage4" parameterType="map" resultType="com.itbaizhan.pojo.User">select * from user limit #{startIndex},#{pageSize}</select>
(3)编写测试方法
@Testpublic void testFindPage4(){ // 创建MapMap<String,Object> params = new HashMap<>(); // 注意:#{}里的变量名可以任意写,但后面传入参数值的时候名字要与#{}里面的变量名一致params.put("startIndex",2);params.put("pageSize",4);List<User> user = userMapper.findPage4(params);user.forEach(System.out::println);}
5.知识点整理:
- 在MyBatis中,集合类型中能作为参数载体的是“Map”
- 在MyBatis中使用Map传参,Map键的类型为String
- MyBatis映射文件的Sql语句中,表示接口方法的第一个参数可以写成:arg0或param1
九、MyBatis聚合查询
1.持久层接口添加聚合查询方法
// 聚合查询count函数int findCount();
2.映射文件添加标签
<!--聚合查询count函数--><select id="findCount" resultType="int">select count(id) from user</select>
3.编写测试方法
@Testpublic void testFindCount(){System.out.println(userMapper.findCount());}
十、MyBatis主键回填
前言:
主键回填功能是为了获取主键自增后的id主键值。有时我们需要获取新插入数据的主键值,如果数据库中主键是自增的,插入数据后并不会得到id主键值,要主键回填后才能得到主键id值,这时我们就需要使用MyBatis的主键回填功能。
1.持久层接口添加主键回填方法
// 主键回填功能void add2(User user);
2.映射文件添加标签
<!-- 主键回填--><!--keyProperty:主键属性 keyColumn:主键列名 resultType:主键返回值类型 order:执行时机(AFTER:插入完成后再获取主键)--><insert id="add2" parameterType="com.itbaizhan.pojo.User"><selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">SELECT LAST_INSERT_ID();</selectKey>insert into user(username,sex,address) values (#{username},#{sex},#{address})</insert>
SELECT LAST_INSERT_ID():
查询刚刚插入的记录的主键值,只适用于自增主键,且必须和insert语句一起执行。
3.编写测试方法
@Testpublic void testAdd2(){User user = new User("程序员2","女","深圳");System.out.println(user);userMapper.add2(user);sessionmit();System.out.println(user);}
十一、映射文件中parameterType=“”参数传入规则
在映射文件中,parameterType的值为string而没有写java.lang.String,这是为什么呢?
原因:参数/返回值类型为基本数据类型/包装类/String等类型时,我们可以写全类名,也可以写别名。
更多推荐
02 MyBatis框架增删改查
发布评论