MyBatis--註解式開發

MyBatis--註解式開發

MyBatis的註解,主要是用於替換映射文件。而映射文件中無非存放着增刪改查的sql映射標籤。因此,MyBatis註解,就是替換映射文件中的sql標籤。java

經常使用註解說明:mysql

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

1、基本的CRUD

1.@Insertsql

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

2.@SelectKey緩存

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

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

3.@Deletemarkdown

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

4.@Updatemybatis

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

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,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)有沒有引用映射文件,都不能存在映射文件。能夠刪除或者放在其餘目錄下。

2、實現複雜關係映射

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);
        }
    }
}
複製代碼

3、實現多表複雜查詢

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,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());
        }
    }
複製代碼

注意:一般對一選擇當即加載,對多選擇延遲加載

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",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);
        }
    }

複製代碼

4、實現二級緩存

一級緩存:默認就開啓:

@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);
    }
複製代碼
相關文章
相關標籤/搜索