MyBatis Fundamentals
- Database and Dependency Setup
Create a database table:
CREATE TABLE tb_user ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(20), password VARCHAR(20), gender CHAR(1), addr VARCHAR(30) );
INSERT INTO tb_user VALUES (1, 'zhangsan', '123', '男', '北京'); INSERT INTO tb_user VALUES (2, '李四', '234', '女', '天津'); INSERT INTO tb_user VALUES (3, '王五', '11', '男', '西安');
Maven dependencies:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.11</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
- MyBatis Core Configuration
User POJO:
public class User {
private Integer id;
private String username;
private String password;
private String gender;
private String addr;
// Getters and setters
}
Mapper XML:
<?xml version="1.0" encoding="UTF-8" ?>
<mapper namespace="userMapper">
<select id="selectAll" resultType="com.example.pojo.User">
SELECT * FROM tb_user
</select>
</mapper>
MyBatis configuration:
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///pikachu?useSSL=false"/>
<property name="username" value="kudo"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="UserMapper.xml"/>
</mappers>
</configuration>
- Testing MyBatis
public class MyBatisTest {
public static void main(String[] args) throws Exception {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
List<User> users = sqlSession.selectList("userMapper.selectAll");
System.out.println(users);
sqlSession.close();
}
}
Mapper Proxy Development
Enterface definition:
public interface UserMapper {
List<User> selectAll();
}
Using mapper proxy:
public class MyBatisTest {
public static void main(String[] args) throws Exception {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> users = userMapper.selectAll();
System.out.println(users);
sqlSession.close();
}
}
Advanced Mappper Configuration
Package scanning in MyBatis config:
<mappers>
<package name="com.example.mapper"/>
</mappers>
Properties loading:
<properties resource="jdbc.properties"/>
Type aliases:
<typeAliases>
<package name="com.example.pojo"/>
</typeAliases>
Multiple environments configuration:
<environments default="development">
<environment id="development">
<!-- Development config -->
</environment>
<environment id="test">
<!-- Test config -->
</environment>
</environments>
Spring Integration with MyBatis
Annotated DAO interface:
package com.example.dao;
import com.example.pojo.User;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface UserDao {
@Select("SELECT * FROM tb_user")
List<User> selectAll();
}
Spring configuration for MyBatis:
@Configuration
public class MyBatisConfig {
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) {
SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
ssfb.setTypeAliasesPackage("com.example.dao");
ssfb.setDataSource(dataSource);
return ssfb;
}
@Bean
public MapperScannerConfigurer mapperScannerConfigurer() {
MapperScannerConfigurer msc = new MapperScannerConfigurer();
msc.setBasePackage("com.example.dao");
return msc;
}
}
Service implementation:
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
public List<User> selectAll(){
return userDao.selectAll();
}
}
JUnit Integration with Spring
Dependencies:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
Test class:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
public void testSelectAll(){
System.out.println(userService.selectAll());
}
}
Aspect-Oriented Programming (AOP)
Basic aspect definition:
@Component
@Aspect
public class MyAspect {
@Pointcut("execution(void com.example.service.UserService.update())")
private void pc(){}
@Before("pc()")
public void logTimestamp() {
System.out.println(System.currentTimeMillis());
}
}
AOP configuration:
@Configuration
@ComponentScan("com.example")
@EnableAspectJAutoProxy
public class SpringConfig {
}
Password trimmnig aspect:
@Component
@Aspect
public class PasswordTrimmer {
@Pointcut("execution(boolean com.example.service.ResourcesService.yesorno(*,*))")
public void pt(){}
@Around("pt()")
public Object trimStrings(ProceedingJoinPoint pjp) throws Throwable {
Object[] args = pjp.getArgs();
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof String) {
args[i] = ((String) args[i]).trim();
}
}
return pjp.proceed(args);
}
}