MyBatis基础之执行SQL

MyBatis基础之执行SQL_第1张图片

文章目录

  • 执行 SQL 语句
    • 1. 增删改操作
      • insert 元素
      • insert 过程中的主键回填
      • delete 元素 和 update 元素
    • 2. getMapper 方法
    • 3. 查操作
      • select 元素
      • select 与 聚合函数
    • 4. 传递多个参数
      • 使用 Map 传递多参数
      • 使用 JavaBean 传递多参
      • 使用注解方式传递多参数

执行 SQL 语句

Mapper 是 MyBatis 最强大的工具与功能,它用于执行 SQL 语句。


DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="...">
  <insert id="..."> ... insert>
  <delete id="..."> ... delete>
  <update id="..."> ... update>
  <select id="..."> ... select>
mapper>
元素 描述 备注
select 查询语句,常用又复杂 可以自定义参数,返回结果集等
insert 插入语句 执行后返回一个整数,代表插入的条数
update 更新语句 执行后返回一个整数,代表更新的条数
delete 删除语句 执行后返回一个整数,代表删除的条数
resultMap 定义查询结果映射关系,常用又复杂 它将提供映射规则

1. 增删改操作

insert 元素

insert 元素的必要属性有 :

元素名 说明
id 和 Mapper 的 namespace 组合起来是唯一的,提供给 MyBatis 调用。
parameterType 类的完全限定名,或内置/自定义的类的别名(Alias)。
可以向 SQL 传递 JavaBean 和 Map 等复杂参数类型,但 Map 参数不建议使用

MyBatis 在执行插入之后会返回一个 整数,以表示插入的记录数。

<insert id="insertDepartment" parameterType="com.xja.hemiao.bean.Department">
  INSERT INTO dept(dname, loc) VALUES(#{dname}, #{loc});
insert>

在传递参数时,MyBatis 中可用的占位符有两种:#{}${}

  • #{}:MyBatis 使用的是 JDBC 中的 PreparedStatement
  • ${}:MyBatis 使用的是 JDBC 中的 Statement
--   #{}是占位符,会进行预编译,传参 'admin' or '1'='1', 0
-- ${}是直接替换,可能会改变你的sql语法(sql注入)传参  
select * from users where username=#{} and password = #{}
                    username = '' admin' or '1'='1'' and password = '0'

select * from users where username=${} and password =${}
                       username = 'admin' or '1'='1' and password = '0'

--  从消耗来说,二者单次的消耗是相同的,批处理时预编译则更友好,缓存重复利用,
-- 当然 就算是#{}也不是完全保证sql的安全,之后可以增加逻辑判断,密码加密等手段
// 这是一个相较于 classpath 的文件路径名。而且,不需要使用 / 。
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
SqlSession session = factory.openSession();

Department dept = new Department("Test", "BeiJing");
int n = session.insert("xxx.yyy.zzz.insertDepartment", dept);

System.out.println(n);      // 输出打印 1

session.commit();
session.close();

insert 过程中的主键回填

大多数情况下,插入信息的主键是由数据库底层生成的,在插入数据后,我们往往需要这个主键,以便于未来的操作。为此,MyBatis 提供了主键回填功能。这个功能需要数据库和数据库驱动支持,MyBatis 才能正常使用它。

开启主键回填功能的 insert 必要属性:

属性 说明
useGeneratedKeys 启用主键回填功能的开关属性。"true"
keyProperty 指定需要回填的 Bean 属性(对应数据库主键列的那个属性)

如果你有大量的 insert 都要用到主键回填功能,而你又觉得要在所有的这些 中每一个都去写 userGeneratedKeys="true" 很麻烦,MyBatis 的核心配置文件中的 中有一个全局设置,可以帮你批量开启所有的 的主键回填功能:

<settings>
  ...
  
  <setting name="useGeneratedKeys" value="true" />
  ...
settings>

[!attention] 注意
留意 的位置。MyBatis 对配置文件的内容的先后顺序有要求。

delete 元素 和 update 元素

和 insert 元素一样,MyBatis 执行完 update 元素 和 delete 元素后会返回一个整数,标示执行后影响的记录条数。

<update id="updateDepartment" parameterType="dept">
  UPDATE dept SET dname = #{dname}, loc = #{loc} WHERE deptno = #{deptno}
update>

<delete id="deleteDepartment" parameterType="int">
  DELETE FROM dept WHERE deptno = #{deptno}
delete>
....
session.insert("xxx.yyy.zzz.insertDepartment", dept);
....
session.update("xxx.yyy.zzz.updateDepartment", dept);
....
session.delete("xxx.yyy.zzz.deleteDepartment", 41);
....

2. getMapper 方法

通过 SqlSession 的 insert、upate、delete 和 selectOne、selectList 方法可以去调用 Mapper.xml 中定义的配置文件,进而操作数据库。不过,MyBatis 提供了更『高端』的操作,『帮』程序员去实现 DAO 层代码。

如果将 Mapper.xml 配置文件的 namespace 故意写的和一个 DAO 接口的完全路径名一样,并且该接口中的方法名有“碰巧”和 Mapp.xml 配置文件中的各个 SQL 语句的 id 值一样,那么 MyBatis 就会去为该接口动态生成一个实现类。

通过 SqlSession 的 getMapper 方法传入接口的类对象,就可以获得这个由 MyBatis 动态生成的 DAO 接口的实现类。

3 个“保持一致”:

  • Mapper.xmlnamespace 与接口的完全限定名保持一致。

  • SQL 语句的 id 属性值与接口中的方法名保持一致。

  • SQL 语句的 parameterType 属性值与接口的方法的参数类型保持一致。

package xxx.yyy.zzz.dao;

public interface DepartmentDao {
    public List<Department> listDepartments();
    ...
}
<mapper namespace="xxx.yyy.zzz.dao.DepartmentDao"> 
  <select id="listDepartments" resultType="dept">
    SELECT * FROM dept
  select>
  ...
mapper>
DepartmentDao dao = session.getMapper(DepartmentDao.class);

List<Department> list = dao.listDepartments();

3. 查操作

select 元素

通过 MyBatis 执行 SQL 后,MyBatis 通过其强大的映射规则,可以自动地将返回的结果集绑定到 JavaBean 中。

select 元素的必要属性有:

属性 说明
id 和 Mapper 的 namespace 组合起来必须唯一
parameterType 类的完全限定名,或内置/自定义的类的别名(Alias)
。可以向 SQL 传递 JavaBean 和 Map 等复杂参数类型。
resultType 类的完全限定名,查询结果将通过固定规范进行映射;
或者定义为 int、double、float 等参数。
resultMap resultType 的「高级版」,允许我们自定义映射规则。
不能与 resultType 同时使用

select 与 聚合函数

并不是所有的 select 语句都会返回一行,或多行记录。例如,在 select 中使用聚合函数。这种情况对于 MyBatis 而言最为简单,因为不需要将结果集映射成 JavaBean ,它只需要返回一行一列的单个数据。

<select id="getMaxSal" resultType="int">
  SELECT * FROM dept WHERE deptno = #{deptno}
select>


<select id="getEmployeeCount" resultType="string">
  SELECT count(empno) FROM emp;
select>
int n = session.selectOne("xxx.yyy.zzz.getMaxSal");
System.out.println(n);

String str = session.selectOne("xxx.yyy.zzz.getemployeeCount");
System.out.println(str);

MyBatis 可以很智能地将返回结果转换为你所指定的类型,如:int、String 等。

4. 传递多个参数

多参数的传递有三种方法:

传递方式 说明
使用 Map 传参 不建议使用(已被 JavaBean 传参替代)
使用 JavaBean 传参 大量多参 传递时使用
使用 注解 传参 少量多参 传递时使用

使用 Map 传递多参数

MyBatis 支持 Map 对象作为参数,此时,要求 select 元素的 parameterType 值为 map

List<Employee> selectBySal1(Map<String, Integer> salMap);
<select id="selectBySal1" parameterType="map" resultType="Employee">
  select * from emp where sal >= #{minSal} and sal < #{maxSal}
select>
Map<String, Integer> map = new HashMap<>();
map.put("minSal", 1000);
map.put("maxSal", 2000);

List<Employee> list = dao.selectBySal1(map);
for (Employee emp : list) {
    log.info("{}", emp);
}

使用 JavaBean 传递多参

由于 Map 的无语义性,因此官方 不建议使用 Map 传参!

此时,要求 select 元素的 parameterType 属性值为 JavaBean 的完全限定名(或别名)。

@Data
public class SallaryRegion {
    private Integer minSallary;
    private Integer maxSallary;
}
List selectBySal2(SallaryRegion region);
<select id="selectBySal2"
        parameterType="com.microboom.bean.po.SallaryRegion"
        resultType="Employee">
    select * 
    from emp 
    where sal >= #{minSallary} 
      and sal < #{maxSallary}
select>

使用注解方式传递多参数

如果所有的多参数传递都通过定义并使用 JavaBean 来进行,那么项目中会出现大量的参数 JavaBean 的定义,显然这也并不太合理。

为此,Mybatis 提供了参数注解,以减少参数 JavaBean 的定义。

List<Employee> selectBySal3(
    @Param("xxx") Integer minSallary,
    @Param("yyy") Integer MaxSallary);
<select id="selectBySal3" resultType="Employee">
  select * 
  from emp 
  where sal >= #{xxx} 
    and sal < #{yyy}
select>

补充MyBatis 框架的注解功能相对而言比较薄弱,官方推荐使用 XML 配置,而非注解,但是少量的多参数传递,是 必须使用注解 的场景。

你可能感兴趣的:(mybatis,mybatis,sql)