20

Interneto sistemų architektūraklevas.mif.vu.lt/~vaidasj/tp/skaidres/09-MyBatis.pdf · Maven MyBatis generator plugin Data Mapper - MyBatis 3 org.mybatis.generator

  • Upload
    others

  • View
    5

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Interneto sistemų architektūraklevas.mif.vu.lt/~vaidasj/tp/skaidres/09-MyBatis.pdf · Maven MyBatis generator plugin Data Mapper - MyBatis 3  org.mybatis.generator
Page 2: Interneto sistemų architektūraklevas.mif.vu.lt/~vaidasj/tp/skaidres/09-MyBatis.pdf · Maven MyBatis generator plugin Data Mapper - MyBatis 3  org.mybatis.generator

Data Mapper: Main idea

2Data Mapper - MyBatis

Page 3: Interneto sistemų architektūraklevas.mif.vu.lt/~vaidasj/tp/skaidres/09-MyBatis.pdf · Maven MyBatis generator plugin Data Mapper - MyBatis 3  org.mybatis.generator

Maven MyBatis generator plugin

Data Mapper - MyBatis 3

<plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.5</version><configuration>

<contexts>StudentsDB</contexts><verbose>true</verbose>

</configuration><dependencies>

JDBC driver dependencies...</dependencies>

</plugin>

Naudoja: src\main\resources\generatorConfig.xml

Page 4: Interneto sistemų architektūraklevas.mif.vu.lt/~vaidasj/tp/skaidres/09-MyBatis.pdf · Maven MyBatis generator plugin Data Mapper - MyBatis 3  org.mybatis.generator

src\main\resources\generatorConfig.xml

Data Mapper - MyBatis 4

<generatorConfiguration><context id="StudentsDB" targetRuntime="MyBatis3Simple">

<jdbcConnection driverClass="org.postgresql.Driver"connectionURL="jdbc:postgresql://localhost/studentsdb"userId="postgres"password="postgres">

</jdbcConnection><javaModelGenerator targetPackage="lt.vu.usecases.mybatis.model"

targetProject="MAVEN" /><!-- Anotacijų variantas - mažiau galimybių, bet paprastesnis --><!--<javaClientGenerator type="ANNOTATEDMAPPER"

targetPackage="lt.vu.usecases.mybatis.dao" targetProject="MAVEN" /> -->

<!-- XML variantas - daugiau galimybių --><sqlMapGenerator targetPackage="lt.vu.usecases.mybatis.xml"

targetProject="MAVEN" /><javaClientGenerator type="XMLMAPPER"

targetPackage="lt.vu.usecases.mybatis.dao" targetProject="MAVEN" />

Page 5: Interneto sistemų architektūraklevas.mif.vu.lt/~vaidasj/tp/skaidres/09-MyBatis.pdf · Maven MyBatis generator plugin Data Mapper - MyBatis 3  org.mybatis.generator

src\main\resources\generatorConfig.xml (2)

Data Mapper - MyBatis 5

<table schema="public" tableName="university"><generatedKey column="id" identity="true" sqlStatement="JDBC" /><ignoreColumn column="opt_lock_version" />

</table><table schema="public" tableName="student">

<generatedKey column="id" identity="true" sqlStatement="JDBC" /><ignoreColumn column="opt_lock_version" />

</table><table schema="public" tableName="course">

<generatedKey column="id" identity="true" sqlStatement="JDBC" /><ignoreColumn column="opt_lock_version" />

</table><table schema="public" tableName="student_course"></table>

</context></generatorConfiguration>

Page 6: Interneto sistemų architektūraklevas.mif.vu.lt/~vaidasj/tp/skaidres/09-MyBatis.pdf · Maven MyBatis generator plugin Data Mapper - MyBatis 3  org.mybatis.generator

Generavimo rezultatas

Data Mapper - MyBatis 6

Page 7: Interneto sistemų architektūraklevas.mif.vu.lt/~vaidasj/tp/skaidres/09-MyBatis.pdf · Maven MyBatis generator plugin Data Mapper - MyBatis 3  org.mybatis.generator

Maven MyBatis dependencies

Data Mapper - MyBatis 7

<dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.2</version>

</dependency><dependency>

<groupId>org.mybatis</groupId><artifactId>mybatis-cdi</artifactId><version>1.0.0-beta7</version>

</dependency>

Page 8: Interneto sistemų architektūraklevas.mif.vu.lt/~vaidasj/tp/skaidres/09-MyBatis.pdf · Maven MyBatis generator plugin Data Mapper - MyBatis 3  org.mybatis.generator

MyBatis: http://www.mybatis.org/mybatis-3 SqlSessionFactory

Once created, the SqlSessionFactory should exist for the duration of your application execution.

The simplest is to use a Singleton pattern or Static Singleton pattern.

SqlSession Each thread should have its own instance of SqlSession.

Instances of SqlSession are not to be shared and are not thread safe. Therefore the best scope is request or method scope.

Never keep references to a SqlSession instance in a static field or even an instance field of a class. Never keep references to a SqlSession in any sort of managed scope, such as HttpSessionof the Servlet framework.

Data Mapper - MyBatis 8

Page 9: Interneto sistemų architektūraklevas.mif.vu.lt/~vaidasj/tp/skaidres/09-MyBatis.pdf · Maven MyBatis generator plugin Data Mapper - MyBatis 3  org.mybatis.generator

MyBatisResources.java

Data Mapper - MyBatis 9

@Slf4j@ApplicationScopedpublic class MyBatisResources {

@Produces@ApplicationScoped@SessionFactoryProviderprivate SqlSessionFactory produceSqlSessionFactory() {

try {return new SqlSessionFactoryBuilder().build(

Resources.getResourceAsStream("MyBatisConfig.xml"));

} catch (IOException e) {log.error("produceSqlSessionFactory(): ", e);throw new RuntimeException(...);

}}

}

Page 10: Interneto sistemų architektūraklevas.mif.vu.lt/~vaidasj/tp/skaidres/09-MyBatis.pdf · Maven MyBatis generator plugin Data Mapper - MyBatis 3  org.mybatis.generator

Data Mapper - MyBatis 10

<configuration><typeAliases><typeAlias type="lt.vu.usecases.mybatis.model.Student"

alias="Student"/>...

</typeAliases><environments default="development"><environment id="development"><transactionManager type="MANAGED"/><dataSource type="JNDI">

<property name="data_source" value="openejb:Resource/StudentsDataSource"/>

</dataSource></environment>

</environments><mappers><mapper resource="mybatis/xml/StudentMapper.xml"/>...

</mappers></configuration>

src\main\resources\MyBatisConfig.xml

Page 11: Interneto sistemų architektūraklevas.mif.vu.lt/~vaidasj/tp/skaidres/09-MyBatis.pdf · Maven MyBatis generator plugin Data Mapper - MyBatis 3  org.mybatis.generator

MyBatis Student Model class

Data Mapper - MyBatis 11

@Getter@Setterpublic class Student {

private Integer id;private String firstName;private String lastName;private Integer universityId;private String registrationNo;

// Rankomis prirašyti:private University university;private List<Course> courses;

}

Page 12: Interneto sistemų architektūraklevas.mif.vu.lt/~vaidasj/tp/skaidres/09-MyBatis.pdf · Maven MyBatis generator plugin Data Mapper - MyBatis 3  org.mybatis.generator

Student Mapper XML file

Data Mapper - MyBatis 12

<mapper namespace="lt.vu.usecases.mybatis.dao.StudentMapper"><delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">

DELETE FROM public.studentWHERE id = #{id,jdbcType=INTEGER}

</delete>

<insert id="insert" keyColumn="id" keyProperty="id" parameterType="Student" useGeneratedKeys="true">

INSERT INTO public.student (first_name, last_name, registration_no, university_id)

VALUES (#{firstName,jdbcType=VARCHAR}, #{lastName,jdbcType=VARCHAR}, #{registrationNo,jdbcType=VARCHAR}, #{universityId,jdbcType=INTEGER})

</insert>

<update id="updateByPrimaryKey" parameterType="Student">UPDATE public.studentSET first_name = #{firstName,jdbcType=VARCHAR},last_name = #{lastName,jdbcType=VARCHAR},registration_no = #{registrationNo,jdbcType=VARCHAR},university_id = #{universityId,jdbcType=INTEGER}WHERE id = #{id,jdbcType=INTEGER}

</update>

Page 13: Interneto sistemų architektūraklevas.mif.vu.lt/~vaidasj/tp/skaidres/09-MyBatis.pdf · Maven MyBatis generator plugin Data Mapper - MyBatis 3  org.mybatis.generator

Student Mapper XML file

Data Mapper - MyBatis 13

<resultMap id="BaseResultMap" type="lt.vu.usecases.mybatis.model.Student"><id column="id" jdbcType="INTEGER" property="id"/><result column="first_name" jdbcType="VARCHAR" property="firstName"/><result column="last_name" jdbcType="VARCHAR" property="lastName"/><result column="registration_no" jdbcType="VARCHAR"

property="registrationNo"/><result column="university_id" jdbcType="INTEGER" property="universityId"/>...

</resultMap>

<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">

SELECT id, first_name, last_name, registration_no, university_idFROM public.studentWHERE id = #{id,jdbcType=INTEGER}

</select>

<select id="selectAll" resultMap="BaseResultMap">SELECT s.id, s.first_name, s.last_name, s.registration_no, s.university_id,

u.title as university_titleFROM public.student s

LEFT JOIN public.university u ON s.university_id = u.id</select>

Page 14: Interneto sistemų architektūraklevas.mif.vu.lt/~vaidasj/tp/skaidres/09-MyBatis.pdf · Maven MyBatis generator plugin Data Mapper - MyBatis 3  org.mybatis.generator

Ryšiai

Data Mapper - MyBatis 14

<resultMap id="BaseResultMap" type="lt.vu.usecases.mybatis.model.Student">...

<!-- Rankomis prirašytas ryšiui ManyToOne Student -> University --><!-- Nested result (nėra N+1 select problemos) --><association property="university" columnPrefix="university_"

resultMap="lt.vu.usecases.mybatis.dao.UniversityMapper.BaseResultMap"/>

<!-- Rankomis prirašytas ryšiui ManyToMany Student -> Course --><!-- Nested select (yra N+1 select problema) --><collection property="courses" javaType="ArrayList" ofType="Course"

column="id" select="selectCoursesForStudent"/></resultMap>

<!-- Rankomis prirašytas ryšiui ManyToMany Student -> Course --><select id="selectCoursesForStudent" resultType="Course">

SELECTc.id,c.name

FROM public.course cJOIN public.student_course sc on c.id = sc.course_id

WHERE sc.student_id = #{id,jdbcType=INTEGER}</select>

Page 15: Interneto sistemų architektūraklevas.mif.vu.lt/~vaidasj/tp/skaidres/09-MyBatis.pdf · Maven MyBatis generator plugin Data Mapper - MyBatis 3  org.mybatis.generator

UniversityMapper.xml

Data Mapper - MyBatis 15

<mapper namespace="lt.vu.usecases.mybatis.dao.UniversityMapper"><resultMap id="BaseResultMap" type="University">

<id column="id" jdbcType="INTEGER" property="id"/><result column="title" jdbcType="VARCHAR" property="title"/>

</resultMap>

Page 16: Interneto sistemų architektūraklevas.mif.vu.lt/~vaidasj/tp/skaidres/09-MyBatis.pdf · Maven MyBatis generator plugin Data Mapper - MyBatis 3  org.mybatis.generator

MyBatis DAO: StudentMapper

Data Mapper - MyBatis 16

@Mapper // rankomis prirašytas: MyBatis CDI integracijapublic interface StudentMapper {

int deleteByPrimaryKey(Integer id);

int insert(Student record);

Student selectByPrimaryKey(Integer id);

List<Student> selectAll();

int updateByPrimaryKey(Student record);}

Metodų pavadinimai atitinka XML faile atributų „id“ reikšmes

Page 17: Interneto sistemų architektūraklevas.mif.vu.lt/~vaidasj/tp/skaidres/09-MyBatis.pdf · Maven MyBatis generator plugin Data Mapper - MyBatis 3  org.mybatis.generator

Use case controller

Data Mapper - MyBatis 17

@Model // tas pats kaip: @Named ir @RequestScoped@Slf4jpublic class RequestUseCaseControllerMyBatis {

@Getter private Course course = new Course();@Getter private Student student = new Student();

@Inject private StudentMapper studentMapper;@Inject private CourseMapper courseMapper;@Inject private StudentCourseMapper studentCourseMapper;

public List<lt.vu.usecases.mybatis.model.Student> getAllStudents() {return studentMapper.selectAll();

}@Transactionalpublic void createCourseStudent() {

courseMapper.insert(course);studentMapper.insert(student);StudentCourse studentCourse = new StudentCourse();studentCourse.setCourseId(course.getId());studentCourse.setStudentId(student.getId());studentCourseMapper.insert(studentCourse);log.info("Maybe OK...");

}}

Page 18: Interneto sistemų architektūraklevas.mif.vu.lt/~vaidasj/tp/skaidres/09-MyBatis.pdf · Maven MyBatis generator plugin Data Mapper - MyBatis 3  org.mybatis.generator

simple-usecase-mybatis.xhtml

Data Mapper - MyBatis 18

<p:fieldset legend="All students" toggleable="true" style="width: 50%"><p:dataTable var="student"

value="#{requestUseCaseControllerMyBatis.getAllStudents()}">

<p:column headerText="Student"><h:outputText value="#{student.firstName} #{student.lastName}"/>

</p:column>

<p:column headerText="Courses"><ui:repeat var="course" value="#{student.courses}"><h:outputText value="#{course.name} " />

</ui:repeat></p:column>

<p:column headerText="University"><h:outputText value="#{student.university.title} " />

</p:column></p:dataTable>

</p:fieldset>

Page 19: Interneto sistemų architektūraklevas.mif.vu.lt/~vaidasj/tp/skaidres/09-MyBatis.pdf · Maven MyBatis generator plugin Data Mapper - MyBatis 3  org.mybatis.generator

ORM vs Data Mapper SQL sakiniai:

ORM: generuojami (ir prisitaiko prie skirtingų DBVS automatiškai)

Data Mapper: rašomi rankomis; skirtingoms DBVS reikės skirtingų SQL...

SQL sakinių našumas/greitaveika: ORM: praktiškai nekontroliuojama (yra galimybės nurodyti

„hint‘us“...)

Data Mapper: pilnai kontroliuojama SQL lygyje

N+1 select problema: ORM: valdoma dalinai (galime pasakyti norus)

Data Mapper: valdoma pilnai

Data Mapper - MyBatis 19

Page 20: Interneto sistemų architektūraklevas.mif.vu.lt/~vaidasj/tp/skaidres/09-MyBatis.pdf · Maven MyBatis generator plugin Data Mapper - MyBatis 3  org.mybatis.generator

MyBatis: Dynamic SQL

Data Mapper - MyBatis 20

<select id="findActiveBlogLike" resultType="Blog">SELECT * FROM BLOG <where><if test="state != null">

state = #{state} </if><if test="title != null">

AND title like #{title} </if><if test="author != null and author.name != null">

AND author_name like #{author.name} </if>

</where></select>

The where element knows to only insert "WHERE" if there is any content

returned by the containing tags.

Furthermore, if that content begins with "AND" or "OR", it knows to strip it off.