MyBatis的注解,主要是用于替换映射文件。而映射文件中无非存放着增删改查的sql映射标签。所以,MyBatis注解,就是替换映射文件中的sql标签。
注解 | 说明 |
---|---|
@Insert | 实现新增 |
@Update | 实现更新 |
@Delete | 实现删除 |
@Select | 实现查询 |
@Result | 实现结果集封装 |
@Results | 可以与@Result 一起使用,封装多个结果集 |
@ResultMap | 实现引用@Results 定义的封装 |
@One | 实现一对一结果集封装 |
@Many | 实现一对多结果集封装 |
@SelectProvider | 实现动态 SQL 映射 |
@CacheNamespace | 实现注解二级缓存的使用 |
其value属性用于指定要执行的insert语句。
用于替换xml中的 <selectKey/>
标签,用于返回新插入数据的id值。
@SelectKey(statement="select @@identity",resultType=int.class,keyProperty="id",before=false 复制代码
其value属性用于指定要执行的delete语句。
其value属性用于指定要执行的update语句。
其value属性用于指定要执行的select语句。
程序举例:
SqlMapConfig.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 引入外部配置文件--> <properties resource="jdbcConfig.properties"></properties> <!--配置别名--> <typeAliases> <package name="com.hcx.domain"></package> </typeAliases> <!-- 配置环境--> <environments default="mysql"> <environment id="mysql"> <transactionManager type="JDBC"></transactionManager> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"></property> <property name="url" value="${jdbc.url}"></property> <property name="username" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </dataSource> </environment> </environments> <!-- 指定带有注解的dao接口所在位置 --> <mappers> <mapper class="com.hcx.dao.StudentDao"></mapper> </mappers> </configuration> 复制代码
1.修改dao接口:
public interface IStudentDao { @Insert(value={"insert into student(name,age,score) values(#{name},#{age},#{score})"}) void insertStudent(Student student); @Insert("insert into student(name,age,score) values(#{name},#{age},#{score})") @SelectKey(statement="select @@identity",resultType=int.class,keyProperty="id",before=false) void insertStudentCacheId(Student student); @Delete(value="delete from student where id=#{id}") void deleteStudentById(int id); @Update("update student set name=#{name},age=#{age},score=#{score} where id=#{id}") void updateStudent(Student student); @Select("select * from student") List<Student> selectAllStudents(); @Select("select * from student where id=#{id}") Student selectStudentById(int id); @Select("select * from student where name like '%' #{name} '%'") List<Student> selectStudentsByName(String name); } 复制代码
2.删除映射文件
3.修改主配置文件
由于没有了映射文件,所以主配置文件中不能使用 <mapper/>
注册mapper的位置了。需要使用 <package/>
标签
<!-- 注册映射文件 --> <mappers> <package name="com.hcx.dao"/> </mappers> 复制代码
注意:使用了注解之后,不管主配置文件(SqlMapConfig.xml)有没有引用映射文件,都不能存在映射文件。可以删除或者放在其他目录下。
1.@Result当实体属性和数据库字段名称不一致时,使用 @Result
注解声明映射关系
@Results(id = "studentMap",value={ @Result(id=true,column = "id",property = "studentId"), @Result(column = "name",property = "studentName"), @Result(column = "age",property = "studentAge"), @Result(column = "score",property = "studentScore"), }) 复制代码
id
:唯一标识这段映射,之后可以直接引用,无需重复编写 id=true
:标识为主键字段 column
:数据库字段名 property
:实体属性名
2.@ResultMap引用定义好的ResultMap
Student:
@Data @ToString public class Student implements Serializable{ private Integer studentId; private String studentName; private int studentAge; private double studentScore; } 复制代码
StudentDao:
public interface StudentDao { @Select("select * from student") @Results(id = "studentMap",value={ @Result(id=true,column = "id",property = "studentId"), @Result(column = "name",property = "studentName"), @Result(column = "age",property = "studentAge"), @Result(column = "score",property = "studentScore"), }) List<Student> findAll(); @Select("select * from student where id=#{id}") @ResultMap(value = {"studentMap"}) Student findById(Integer id); @Select("select * from student where name like #{name}") @ResultMap(value = {"studentMap"}) List<Student> findStudentByName(String name); } 复制代码
AnnotationCrudTest:
public class AnnotationCrudTest { private InputStream in; private SqlSessionFactory factory; private SqlSession session; private StudentDao studentDao; @Before public void init()throws Exception{ in = Resources.getResourceAsStream("SqlMapConfig.xml"); factory = new SqlSessionFactoryBuilder().build(in); session = factory.openSession(); studentDao = session.getMapper(StudentDao.class); } @After public void destroy()throws Exception{ session.commit(); session.close(); in.close(); } @Test public void testFindAll(){ List<Student> students = studentDao.findAll(); for(Student student : students){ System.out.println(student); } } @Test public void testFindById(){ Student student = studentDao.findById(1); System.out.println(student); } @Test public void testFindByName(){ List<Student> students = studentDao.findStudentByName("%小红%"); for(Student student : students){ System.out.println(student); } } } 复制代码
Account:
@Data @ToString public class Account { private Integer id; private Integer studentId; private Double money; //多对一:一个账户只能属于一个学生 private Student student; } 复制代码
AccountDao:
public interface AccountDao { /** * 查询所有账户并获取每个账户所属用户信息 * @return */ @Select("select * from account") @Results(id = "accountMap",value = { @Result(id = true,column = "id",property = "id"), @Result(column = "studentId",property = "studentId"), @Result(column = "money",property = "money"), @Result(property = "student",column = "studentId",one = @One(select = "com.hcx.dao.StudentDao.findById", fetchType = FetchType.EAGER)) }) List<Account> findAll(); } 复制代码
StudentDao:
public interface StudentDao { @Select("select * from student") @Results(id = "studentMap",value={ @Result(id=true,column = "id",property = "studentId"), @Result(column = "name",property = "studentName"), @Result(column = "age",property = "studentAge"), @Result(column = "score",property = "studentScore"), }) List<Student> findAll(); @Select("select * from student where id=#{id}") @ResultMap(value = {"studentMap"}) Student findById(Integer id); @Select("select * from student where name like #{name}") @ResultMap(value = {"studentMap"}) List<Student> findStudentByName(String name); } 复制代码
AccountTest:
@Test public void testFindAll(){ List<Account> accounts = accountDao.findAll(); for(Account account : accounts){ System.out.println(account); // System.out.println(account.getStudent()); } } 复制代码
注意:通常对一选择立即加载,对多选择延迟加载
Student:
@Data @ToString public class Student implements Serializable{ private Integer studentId; private String studentName; private int studentAge; private double studentScore; //一对多,一个用户对应多个账户 private List<Account> accounts; } 复制代码
StudentDao:
public interface StudentDao { @Select("select * from student") @Results(id = "studentMap",value={ @Result(id=true,column = "id",property = "studentId"), @Result(column = "name",property = "studentName"), @Result(column = "age",property = "studentAge"), @Result(column = "score",property = "studentScore"), @Result(property = "accounts",column = "id", many = @Many(select = "com.hcx.dao.AccountDao.findAccountByStudentId",fetchType = FetchType.LAZY)) }) List<Student> findAll(); @Select("select * from student where id=#{id}") @ResultMap(value = {"studentMap"}) Student findById(Integer id); @Select("select * from student where name like #{name}") @ResultMap(value = {"studentMap"}) List<Student> findStudentByName(String name); } 复制代码
AccountDao:
public interface AccountDao { /** * 查询所有账户并获取每个账户所属用户信息 * @return */ @Select("select * from account") @Results(id = "accountMap",value = { @Result(id = true,column = "id",property = "id"), @Result(column = "studentId",property = "studentId"), @Result(column = "money",property = "money"), @Result(property = "student",column = "studentId",one = @One(select = "com.hcx.dao.StudentDao.findById", fetchType = FetchType.EAGER)) }) List<Account> findAll(); /** * 根据学生id查询学生信息 * @param studentId * @return */ @Select("select * from account where studentId=#{studentId}") List<Account> findAccountByStudentId(Integer studentId); } 复制代码
Test:
@Test public void testFindAll(){ List<Student> students = studentDao.findAll(); for(Student student : students){ System.out.println(student); } } 复制代码
一级缓存:默认就开启:
@Test public void testFindById(){ Student student = studentDao.findById(1); System.out.println(student); Student student1 = studentDao.findById(1); System.out.println(student1); //true System.out.println(student==student1); } 复制代码
在主配置文件中开启二级缓存(默认开启,不配置也可以) sqlMapConfig.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 引入外部配置文件--> <properties resource="jdbcConfig.properties"></properties> <!--设置开启二级缓存--> <settings> <setting name="cacheEnabled" value="true"/> </settings> <!--配置别名--> <typeAliases> <package name="com.hcx.domain"></package> </typeAliases> <!-- 配置环境--> <environments default="mysql"> <environment id="mysql"> <transactionManager type="JDBC"></transactionManager> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"></property> <property name="url" value="${jdbc.url}"></property> <property name="username" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </dataSource> </environment> </environments> <!-- 指定带有注解的dao接口所在位置 --> <mappers> <!--<mapper class="com.hcx.dao.StudentDao"></mapper>--> <package name="com.hcx.dao"></package> </mappers> </configuration> 复制代码
在mapper中使用注解 @CacheNamespace(blocking=true)
@CacheNamespace(blocking = true) public interface StudentDao { @Select("select * from student") @Results(id = "studentMap",value={ @Result(id=true,column = "id",property = "studentId"), @Result(column = "name",property = "studentName"), @Result(column = "age",property = "studentAge"), @Result(column = "score",property = "studentScore"), @Result(property = "accounts",column = "id", many = @Many(select = "com.hcx.dao.AccountDao.findAccountByStudentId",fetchType = FetchType.LAZY)) }) List<Student> findAll(); @Select("select * from student where id=#{id}") @ResultMap(value = {"studentMap"}) Student findById(Integer id); @Select("select * from student where name like #{name}") @ResultMap(value = {"studentMap"}) List<Student> findStudentByName(String name); } 复制代码
Test:
@Test public void testFindOne(){ SqlSession sqlSession = factory.openSession(); StudentDao studentDao = sqlSession.getMapper(StudentDao.class); Student student = studentDao.findById(1); System.out.println(student); sqlSession.close(); SqlSession sqlSession1 = factory.openSession(); StudentDao studentDao1 = sqlSession1.getMapper(StudentDao.class); Student student1 = studentDao1.findById(1); System.out.println(student1); sqlSession1.close(); //false System.out.println(student==student1); } 复制代码