1. 程式人生 > 程式設計 >MyBatis--註解式開發

MyBatis--註解式開發

MyBatis--註解式開發

MyBatis的註解,主要是用於替換對映檔案。而對映檔案中無非存放著增刪改查的sql對映標籤。所以,MyBatis註解,就是替換對映檔案中的sql標籤。

常用註解說明:

註解 說明
@Insert 實現新增
@Update 實現更新
@Delete 實現刪除
@Select 實現查詢
@Result 實現結果集封裝
@Results 可以與@Result 一起使用,封裝多個結果集
@ResultMap 實現引用@Results 定義的封裝
@One 實現一對一結果集封裝
@Many 實現一對多結果集封裝
@SelectProvider 實現動態 SQL 對映
@CacheNamespace 實現註解二級快取的使用

一、基本的CRUD

1.@Insert

其value屬性用於指定要執行的insert語句。

2.@SelectKey

用於替換xml中的<selectKey/>標籤,用於返回新插入資料的id值。

@SelectKey(statement="select @@identity",resultType=int.class,keyProperty="id",before=false
複製程式碼
  • statement:獲取新插入記錄主鍵值得sql語句
  • keyProperty:獲取的該主鍵值返回後初始化物件的那個屬性
  • resultType:返回值型別
  • before:指定主鍵的生成相對於insert語句的執行先後順序,該屬性不能省略

3.@Delete

其value屬性用於指定要執行的delete語句。

4.@Update

其value屬性用於指定要執行的update語句。

5.@Select

其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,#{score})")
	@SelectKey(statement="select @@identity",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,@Result(column = "name",@Result(column = "age",@Result(column = "score",})
    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);
        }
    }
}
複製程式碼

三、實現多表複雜查詢

1.一對一

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,property = "id"),@Result(column = "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",})
    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());
        }
    }
複製程式碼

注意:通常對一選擇立即載入,對多選擇延遲載入

2.一對多

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",@Result(property = "accounts",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",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",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);
    }
複製程式碼