Mybatis使用注解开发以及拓展知识详解

注解开发

1、面向接口编程

根本原因:解耦,可拓展,提高复用

对于像 BlogMapper 这样的映射器类来说,还有另一种方法来完成语句映射。 它们映射的语句可以不用 XML 来配置,而可以使用 Java 注解来配置。比如,将xml可以被替换成如下的配置:

    package org.mybatis.example;
    public interface BlogMapper {
      @Select("SELECT * FROM blog WHERE id = #{id}")
      Blog selectBlog(int id);
    }

使用注解来映射简单语句会使代码显得更加简洁,但对于稍微复杂一点的语句,Java 注解不仅力不从心,还会让你本就复杂的 SQL 语句更加混乱不堪。 因此,如果你需要做一些很复杂的操作,最好用 XML 来映射语句。

选择何种方式来配置映射,以及认为是否应该要统一映射语句定义的形式,完全取决于你和你的团队。 换句话说,永远不要拘泥于一种方式,你可以很轻松的在基于注解和 XML 的语句映射方式间自由移植和切换。

2、使用注解开发

2.1、注解在接口上实现

//查询所有用户
@Select("select * from user")
List<User> getUserList();

2.2、需要在核心配置文件中绑定接口

<mappers>
    <mapper class="com.liu.dao.UserMapper"></mapper>
</mappers>

2.3、测试

  @Test
    public void getUserList(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = mapper.getUserList();
        for (User user : userList) {
            System.out.println(user);
        }
        sqlSession.close();
    }

3、CRUD(增删改查)

可以在工具类创建的时候实现自动提交事务

public static SqlSession getSqlSession(){
    return sqlSessionFactory.openSession(true);//默认为fales
}

编写接口,增加注解

//查询所有用户
    @Select("select * from user")
    List<User> getUserList();

    //通过id查询  当方法存在多个参数时,所有的参数前面必须加上@Param("")注解,sql语句中的条件跟@Param中的参数名字保持一致
    @Select("select * from user where id=#{id}")
    User getUserOne(@Param("id") int id);

    //增加用户
    @Insert("insert into user(id,name,pwd) values(#{id},#{name},#{password})")
    int insertUser(User user);

    //修改  先传的是id
    @Update("update user set name=#{name},pwd=#{password} where id=#{id}")
    int updateUserName(User user);

    //删除
    @Delete("delete from user where id=#{uid}")
    int deleteUser(@Param("uid") int id);

测试类

public class UserDaoTest {
    @Test
    public void getUserList(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        //查询所有用户
     	  List<User> userList = mapper.getUserList();
          for (User user : userList) {
        	   System.out.println(user);
	       }

        //通过id查询
        User userOne = mapper.getUserOne(3);

        //插入
        mapper.insertUser(new User(6,"客行","123456"));

        //修改数据
        mapper.updateUserName(new User(6,"haha","123456789"));

        //删除数据
        mapper.deleteUser(5);
        sqlSession.close();
    }

4、关于@Param()注解

  • 基本类型的参数或者String类型,需要加上
  • 引用类型不需要加
  • 如果只有一个基本类型得话,可以忽略,建议加上
  • 我们在SQL中引用的就是我们这里的@Param()中的属性

${} 和#{}的区别

1)#{}是预编译处理,$ {}是字符串替换。

2)MyBatis在处理#{}时,会将SQL中的#{}替换为?号,使用PreparedStatement的set方法来赋值;MyBatis在处理 { } 时,就是把 { } 替换成变量的值。

3)使用 #{} 可以有效的防止SQL注入,提高系统安全性。

5、@Option注解

5.1、插入数据之后,拿到数据库中的自增列的值(主键);

将此注解方法放在插入注解语句上面即可。
方法一:

    //keyProperty是实体类中的属性,和数据库中的主键对应。
    @0ptions(keyProperty = "eno " , useGeneratedKeys = true)

方法二:

    @SelectKey(keyProperty = "username",before = false,resultType = String.class,statement = "select last_insert_id()")

5.2、插入一个不重复的数
给指定的属性,插入一个不重复的数,通过数据库生成一个UUID,随时间变化生成

实际中可用于数据库的id,不需要在数据库中令id自动增长。

//在测试类中不需要再给username设置值了   
//插入一条记录
@SelectKey(keyProperty = "username",before =true,resultType = String.class,statement = "select UUID()")
@Insert("insert into accinfo2(username,realname,sex) values(#{username},#{realname},#{sex})")

6、注解映射问题

@Results(id="EmpMap " , value={
    @Result(id = true , property = "eno " ,column = "eno " )@Result(property = "ename " , column = "ename "),
    @Result(property = "sal " ,column = "sal")@Result(property = "deptNo " ,column = "did ")
    }
)
@Select("select * from emp")
List<Emp> queryEmpByAnno();

在其他方法上若是想要引用的话,用@ResultMap(id=“EmapMap”)

7、多对一关系

使用内嵌查询方式,在注解中进行引用IDeptMapper中的语句,并将参数传递过去。

public interface IEmpMapper {
    @Results({
            @Result(id = true,property = "empno",column = "empno"),
            @Result(property = "ename",column = "ename"),
            @Result(property = "salary",column = "salary"),
            @Result(property = "phone",column = "phone"),
            @Result(property = "dept",column = "deptno",one = @One(select = "com.liu.dao.IDeptMapper.selectById"))
    })
    @Select("select * from emp")
    List<Emp> queryEmpByAnno();
}
public interface IDeptMapper {
    @Select("select * from dept where deptno=#{deptno}")
    Dept1 selectById(Integer deptno);
}

8、一对多关系

@Results({
        @Result(id = true,property = "deptno",column = "deptno"),
        @Result(property = "dname",column = "dname"),
        @Result(property = "loc",column = "loc"),
        @Result(property = "emps",column = "empno",many = @Many(select = "com.liu.dao.IEmpMapper.queryByIDept"))
})
@Select("select * from dept where deptno = #{deptno}")
List<Dept1> queryById(Integer deptno);

9、注解的动态SQL

1、更新操作

@Update("<script>" +
        "    update emp\n" +
        "    <set>\n" +
        "        <if test=\"salary!=null\">\n" +
        "            salary=salary+10,\n" +
        "        </if>\n" +
        "        <if test=\"ename!=null\">\n" +
        "            ename=#{ename}\n" +
        "        </if>\n" +
        "    </set>\n" +
        "    where empno=#{empno}" +
        "</script>")
void update(Emp emp);

对更新的优化,
(1)将sql提出来在另外一个类中拼接出来,在接口方法上调用(@UpdateProvider)

EmpProvider类

public class EmpProvider {
    public String update(Emp emp){
        String sql = " update emp set ";
        if(emp.getEname()!=null){
            sql+="ename=#{ename},";
        }
        if(emp.getSalary()!=null){
            sql+="salary=#{salary},";
        }
        sql = sql.substring(0,sql.length()-1);
        return sql;
    }
}

调用

@UpdateProvider(type = EmpProvider.class,method = "update")
int update2(Emp emp);

(2)使用SQL类更新,类中用内部类声明。
注意emp必须声明为final

public String update3(final Emp emp){
return new SQL(){
    {
        UPDATE("emp");
        if(emp.getEname() != null){
            SET("ename=#{ename}");
        }
        if(emp.getSalary()!=null){
            SET("salary=#{salary}");
        }
        WHERE("empno=#{empno}");
    }
}.toString();
}

接口中进行调用

@UpdateProvider(type = EmpProvider.class,method = "update3")
int update3(Emp emp);

测试类

public class TestUpdatePro {
    private SqlSession sqlSession;
    @Before
    public void before(){
        sqlSession = MybatisUtils.getSqlSession();
    }
    @After
    public void after(){
        sqlSession.close();
    }
    @Test
    public void update(){
        IEmpMapper mapper = sqlSession.getMapper(IEmpMapper.class);
        Emp emp = new Emp();
        emp.setEname("客行");

        mapper.update2(emp);
    }

    @Test
    public void update2(){
        IEmpMapper mapper = sqlSession.getMapper(IEmpMapper.class);
        Emp emp = new Emp();
        emp.setEname("客行");
        emp.setSalary(1000f);
        emp.setEmpno(2);
        mapper.update3(emp);
    }
}

10、注解和XML混合使用

10.1、接口。

//直接通过id引用映射配置
@ResultMap("EmpMap")
@Select("select eno,ename,sal,did from emp")
List<Emp> query();

10.2、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 namespace="com.wdzl.dao.IEmpDao">

<resultMap id="EmpMap" type="Emp" autoMapping="true">
    <id column="eno" property="eno"></id>
    <result property="ename" column="ename"></result>
    <result property="deptNo" column="did"></result>
    <association property="dept" column="did" select="getDept"></association>
</resultMap>
  
<select id="getDept" resultType="dept">
    select did,dname from dept where did=#{did}
</select>

好了,Mybatis的使用注解开发以及拓展内容的分享到这里就结束了,希望可以对大家有帮助!

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值