注解开发
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的使用注解开发以及拓展内容的分享到这里就结束了,希望可以对大家有帮助!