程序员SQL极简教程 · MySQL · MyBatis · JPA 技术笔记 教程 总结

Mybatis入门程序数据操作(3)

2018-08-30  本文已影响1人  LeaveStyle

内容接着上一篇文章,Mybatis搭建环境(2)

先把dao层的接口给出来,和UserMapper.xml中的mapper标签的namespace属性对接。

package cn.com.mybatis.dao;
import cn.com.mybatis.po.User;

public interface UserDao {
    User findUserById(int id);
    User findUserByUsername(String username);
    int insertUser(User user);
    int deleteUser(int id);
    User updateUserName(String username);
}

1. 模糊查询样例

要对数据库中User表的数据进行模糊查询,需要通过匹配名字的某个字来查询该用户,首先在UserMapper.xml文件中配置SQL映射:

<!--根据用户姓名进行模糊查询-->
<select id="findUserByUsername" parameterType="java.lang.String" resultType="cn.com.mybatis.po.User">
    SELECT * FROM USER WHERE username LIKE '%${value}'
</select>

这里“${}”符号表示拼接SQL串,将收到的参数内容不加任何修饰地拼接在SQL中,在“${}”中只能使用value代表其中的参数。然而在Web项目中,如果没有防范SQL注入的机制,要谨慎使用“${}”符号拼接SQL语句串,因为这可能会引起SQL注入的风险。
然后在MyBatisTest测试类中写一个新的测试方法TestFuzzySearch,来查询所有名称中含有“丽”字的用户信息。

@Test
    public void TestFuzzySearch() throws IOException{
        SqlSession sqlSession = dataConn.getSqlSession();
        List<User> userList = sqlSession.selectList("cn.com.mybatis.dao.UserDao.findUserByUsername","丽");
        for(User user : userList){
            System.out.println("姓名:"+user.getUsername());
            System.out.println("性别:"+user.getGender());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            System.out.println("生日:"+sdf.format(user.getBirthday()));
            System.out.println("所在地:"+user.getProvince()+user.getCity());
        }
        sqlSession.close();;
    }
模糊查询结果.png

2. 新增样例

要对数据库中User表进行新增数据,在UserMapper.xml文件中配置SQL映射:

<!--在表中新增数据信息-->
<insert id="insertUser" parameterType="cn.com.mybatis.po.User">
    INSERT INTO USER(username, password, gender, birthday, email, province, city)
      VALUE (#{username}, #{password}, #{gender}, #{birthday,jdbcType=DATE}, #{email}, #{province}, #{city})
</insert>

在测试类MyBatisTest中添加名为TestInsert方法,向User表新插入一条用户数据。

@Test
public void TestInsert() throws Exception{
    SqlSession sqlSession = dataConn.getSqlSession();
    User user = new User();
    user.setUsername("孙佳佳");
    user.setGender("男");
    user.setPassword("5555");
    user.setEmail("5555@126.com");
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    user.setBirthday(sdf.parse("1991-02-16"));
    user.setProvince("湖北省");
    user.setCity("武汉市");
    sqlSession.insert("cn.com.mybatis.dao.UserDao.insertUser",user);
    sqlSession.commit();
    sqlSession.close();
}
插入数据成功页面.png
更新后的表单信息.png

如果想在插入之后不执行查询语句而立即获取id信息,有两种方法,这里针对Mysql为例:

<!--在表中新增数据信息-->
<insert id="insertUser" parameterType="cn.com.mybatis.po.User">
    <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
        SELECT LAST_INSERT_ID()
    </selectKey>
    INSERT INTO USER(username, password, gender, birthday, email, province, city)
      VALUE (#{username}, #{password}, #{gender}, #{birthday,jdbcType=DATE}, #{email}, #{province}, #{city})
</insert>
<!--在表中新增数据信息-->
<insert id="insertUser" parameterType="cn.com.mybatis.po.User"
    useGeneratedKeys="true" keyProperty="id">
    INSERT INTO USER(username, password, gender, birthday, email, province, city)
      VALUE (#{username}, #{password}, #{gender}, #{birthday,jdbcType=DATE}, #{email}, #{province}, #{city})
</insert>

进行完上面的配置后,MyBatis执行完insert语句后,会自动将自增长id值赋给对象User的属性id,然后在逻辑处理层就可以通过User的get方法获得该id。

3. 删除与修改样例

对于删除和修改,同样需要在UserMapper.xml配置文件中编写相关的SQL配置:

<!--删除用户-->
<delete id="deleteUser" parameterType="java.lang.Integer">
    DELETE FROM USER WHERE id=#{id}
</delete>
<!--修改用户-->
<update id="updateUserName" parameterType="cn.com.mybatis.po.User">
    UPDATE USER SET username=#{username} where id=#{id}
</update>

在MyBatisTest测试类中添加TestDelete和TestUpdate测试方法:

@Test
public void TestDelete() throws Exception{
    SqlSession sqlSession = dataConn.getSqlSession();
    sqlSession.delete("cn.com.mybatis.dao.UserDao.deleteUser",5);
    sqlSession.commit();
    sqlSession.close(); 
}
@Test
public void TestUpdate() throws Exception{
    SqlSession sqlSession = dataConn.getSqlSession();
    User user = new User();
    user.setId(4);
    user.setUsername("孙丽");
    sqlSession.update("cn.com.mybatis.dao.UserDao.updateUserName", user);
    sqlSession.commit();
    sqlSession.close();
}
删除样例成功.png
修改样例成功.png

到此Mybatis的基本入门操作就完成了,下面补充一下注意的事项:

注意 ${} 和 #{} 的区别:

动态 sql 是 mybatis 的主要特性之一,在 mapper 中定义的参数传到 xml 中之后,在查询之前 mybatis 会对其进行动态解析。mybatis 为我们提供了两种支持动态 sql 的语法:#{} 以及 ${}。

  • ${}哪边都能使用,只是存在sql注入风险,相当于直接拼接字符串,不对参数做任何处理。
  • #{}会进行预编译,对参数进行处理,防止注入。
<!--在下面的语句中,如果 username 的值为 zhangsan,则两种方式无任何区别:-->
select * from user where name = #{name};
select * from user where name = ${name};
<!--解析出来的结果都是如下:-->
select * from user where name = 'zhangsan';
  • 但是 #{} 和 ${} 在预编译中的处理是不一样的。#{} 在预处理时,会把参数部分用一个占位符 ? 代替,变成如下的 sql 语句:
elect * from user where name = ?;
  • 而 ${} 则只是简单的字符串替换,在动态解析阶段,该 sql 语句会被解析成:
select * from user where name = 'zhangsan';
  • 以上,#{} 的参数替换是发生在 DBMS 中,而 ${} 则发生在动态解析过程中。
    那么,在使用过程中我们应该使用哪种方式呢?
    答案是,优先使用 #{}。因为 ${} 会导致 sql 注入的问题。看下面的例子:
select * from ${tableName} where name = #{name}
<!--若表名为user; delete user; 则动态解析之后 sql 如下:-- -->
select * from user; delete user; -- where name = ?;

之后的语句被注释掉,而原本查询用户的语句变成了查询所有用户信息+删除用户表的语句,会对数据库造成重大损伤,极大可能导致服务器宕机

  • 既然这样那为什么还要用${}呢。
    因为使用#{}存在一个不足,当参数为字符串时会加上'',这就导致某些情况下sql失效。
    SELECT * FROM #{tableName},当使用#{}传入参数user,sql就会变成
    SELECT * FROM 'user'. 这样就会报错查询不到数据

参考文章: Mabatis中#{}和${}的区别mybatis #{}与${}使用场景

上一篇下一篇

猜你喜欢

热点阅读