MyBatis 是一个 XML 驱动的框架。配置信息是基于 XML 的,到了MyBatis 3 有了基于注解配置,Java 注解的的表达力和灵活性十分有限,项目中有看到使用注解,简单记录下
参考文档:https://mybatis.org/mybatis-3/zh/java-api.html#
注解可以简化Mapper映射文件,但是动态Sql依然使用mapper文件。注意:
1)使用注解时,mybatis-config.xml中
2)Mapper映射文件和注解是可以共同存在的。但是对于接口中的一个方法,注解和xml只能选择使用一个
MyBatis入门CRUD和全局配置文件 之前的这篇文章基础上改用注解
1、UserMapper接口:
import cn.jq.jqmybatis.model.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface UserMapper {
@Select("select id, username, reg_date from t_user where id = #{id}")
@Results(id = "userResultMap", value = {
@Result(column = "id", property = "id"),
@Result(column = "username", property = "username"),
@Result(column = "reg_date", property = "regDate"),
})
User getUser(Long id);
@Select("select * from t_user")
List listAll();
@Select("select * from t_user where id >= #{id} order by ${orderby}")
List listByParam(@Param("id") Long id, @Param("orderby") String orderby);
@Insert("insert into t_user(username, pazzword, salary, reg_date) value (#{username}, #{pazzword}, #{salary}, #{regDate})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insert(User user);
@Update("update t_user set username = #{username}, reg_date = #{regDate} where id = #{id}")
int update(User user);
@Delete("delete from t_user where id = #{id}")
int delete(@Param("id") Long id);
}
UserMapper.xml 删除接口中方法对应的 id 操作
2、测试类:OK
public class App {
@Test
public void testGet() throws Exception {
SqlSession session = MyBatisUtil.getSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = userMapper.getUser(3L);
System.out.println(user);
session.close();
}
@Test
public void testListAll() throws Exception {
SqlSession session = MyBatisUtil.getSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
List list = userMapper.listAll();
list.forEach(user -> {
System.out.println(user);
});
session.close();
}
@Test
public void testListByParam() throws Exception {
SqlSession session = MyBatisUtil.getSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
List list = userMapper.listByParam(1L, "id desc");
list.forEach(user -> {
System.out.println(user);
});
session.close();
}
@Test
public void testInsert() throws Exception {
SqlSession session = MyBatisUtil.getSession();
User user = new User();
user.setUsername("asda");
user.setPazzword("123456");
user.setSalary(new BigDecimal(99.99));
user.setRegDate(new Date());
UserMapper userMapper = session.getMapper(UserMapper.class);
userMapper.insert(user);
// 提交事务
session.commit();
System.out.println(user.getId()); // 7
session.close();
}
@Test
public void testUpdate() throws Exception {
SqlSession session = MyBatisUtil.getSession();
User user = new User();
user.setId(6L);
user.setUsername("asda@");
user.setRegDate(new Date());
UserMapper userMapper = session.getMapper(UserMapper.class);
userMapper.update(user);
// 提交事务
session.commit();
session.close();
}
@Test
public void testDelete() throws Exception {
SqlSession session = MyBatisUtil.getSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
userMapper.delete(7L);
// 提交事务
session.commit();
session.close();
}
}
用自定义的XxxProvider类构造SQL语句,该类无需继承实现其他类
Provider注解中提供了两个必填属性 type和method.
type 属性用于指定构建SQL语句的类
method 属性用于指定类中要执行构建SQL语句的方法,方法返回值(执行的SQL语句)必须是String类型。
1、BaseDao接口:通用的,其他XxxMapper接口可继承它
import cn.jq.jqmybatis.model.User;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
public interface BaseDao {
@SelectProvider(type = BaseDaoSqlProvider.class, method = "get")
User get(Class clazz, @Param("id") Long id);
@SelectProvider(type = BaseDaoSqlProvider.class, method = "listAll")
List listAll(Class clazz);
// 传参的话必须使用 Map类型
@SelectProvider(type = BaseDaoSqlProvider.class, method = "listByParam")
List listByParam(Class clazz, Map paramCon);
@InsertProvider(type = BaseDaoSqlProvider.class, method = "insert")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insert(T entity);
@UpdateProvider(type = BaseDaoSqlProvider.class, method = "update")
int update(T entity);
@DeleteProvider(type = BaseDaoSqlProvider.class, method = "delete")
int delete(Class clazz, @Param("id") Long id);
}
2、UserMapper接口继承BaseDao接口,可以写自己的复杂方法
public interface UserMapper extends BaseDao{
}
3、自定义的XxxProvider类:BaseDaoSqlProvider类
import org.apache.ibatis.jdbc.SQL;
import java.lang.reflect.Field;
import java.util.Map;
/**
* 只管构建动态SQL语句(占位符?),可以使用反射来实现,达到BaseDao通用的简单CRUD
* MyBatis中底层通过 OGNL表达式实现参数与占位符?的完成
*/
public class BaseDaoSqlProvider {
/**
* 有特殊需求的可以使用自定义注解完成,比如:@Tabel @Id @GenerationType @Column @Transient等
* 这里 简单处理下
*
* @param bean
* @return 构建动态SQL语句
*/
public String insert(Object bean) {
Class> clazz = bean.getClass();
System.out.println("insert=" + clazz); // insert=class cn.jq.jqmybatis.model.User
String tablename = "t_" + clazz.getSimpleName();
SQL sql = new SQL();
sql.INSERT_INTO(tablename);
for (Field field : clazz.getDeclaredFields()) {
field.setAccessible(true);
String propertyName = field.getName();
String columnName = field.getName();
if ("regDate".equals(propertyName)) {
columnName = "reg_date";
}
try {
// 属性都没有值时会报错:SQL语法错误
if (field.get(bean) != null && !"".equals(field.get(bean))) {
sql.VALUES(columnName, "#{" + propertyName + "}");
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return sql.toString();
}
public String update(Object bean) {
Class> clazz = bean.getClass();
System.out.println("update=" + clazz); //
String tablename = "t_" + clazz.getSimpleName();
SQL sql = new SQL();
sql.UPDATE(tablename);
for (Field field : clazz.getDeclaredFields()) {
field.setAccessible(true);
String propertyName = field.getName();
String columnName = field.getName();
if ("regDate".equals(propertyName)) {
columnName = "reg_date";
}
if ("id".equals(propertyName)) {
sql.WHERE(columnName + " = #{" + propertyName + "}");
} else {
// 修改所有属性值
sql.SET(columnName + " = #{" + propertyName + "}");
}
}
return sql.toString();
}
public String delete(Class> clazz) {
String tablename = "t_" + clazz.getSimpleName();
SQL sql = new SQL();
sql.DELETE_FROM(tablename);
for (Field field : clazz.getDeclaredFields()) {
field.setAccessible(true);
String propertyName = field.getName();
String columnName = field.getName();
if ("id".equals(propertyName)) {
sql.WHERE(columnName + " = #{" + propertyName + "}");
}
}
return sql.toString();
}
public String get(Class> clazz) {
String tablename = "t_" + clazz.getSimpleName();
SQL sql = new SQL();
// 简单处理,用 * 代替列名
sql.SELECT("*").FROM(tablename);
for (Field field : clazz.getDeclaredFields()) {
field.setAccessible(true);
String propertyName = field.getName();
String columnName = field.getName();
if ("id".equals(propertyName)) {
sql.WHERE(columnName + " = #{" + propertyName + "}");
}
}
return sql.toString();
}
public String listAll(Class> clazz) {
String tablename = "t_" + clazz.getSimpleName();
SQL sql = new SQL();
// 简单处理,用 * 代替列名
sql.SELECT("*").FROM(tablename);
return sql.toString();
}
public String listByParam(Class> clazz, Map paramCon) {
String tablename = "t_" + clazz.getSimpleName();
SQL sql = new SQL();
// 简单处理,用 * 代替列名
sql.SELECT("*").FROM(tablename);
// 这里对Map 简单处理,Map的key规定:条件_属性名
paramCon.forEach((key, value) -> {
String param = this.paramCon(key, value);
if (param != null) {
sql.WHERE(param);
}
});
return sql.toString();
}
// 处理Map集合条件sql
public String paramCon(String key, String value) {
String[] s = key.split("_");
if ("LIKES".equals(s[0])) {
return s[1] + " like '%" + value + "%' ";
}
if ("EQS".equals(s[0])) {
return s[1] + " = '" + value + "' ";
}
if ("EQL".equals(s[0])) {
return s[1] + " = " + value + " ";
}
if ("LTL".equals(s[0])) {
return s[1] + " <= " + value + " ";
}
if ("GTL".equals(s[0])) {
return s[1] + " >= " + value + " ";
}
return null;
}
}
4、测试类:OK
public class App {
@Test
public void testGet() throws Exception {
SqlSession session = MyBatisUtil.getSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = userMapper.get(User.class, 3L);
System.out.println(user);
session.close();
}
@Test
public void testListAll() throws Exception {
SqlSession session = MyBatisUtil.getSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
List list = userMapper.listAll(User.class);
list.forEach(user -> {
System.out.println(user);
});
session.close();
}
@Test
public void testListByParam() throws Exception {
SqlSession session = MyBatisUtil.getSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
Map map = new HashMap<>();
map.put("GTL_id","3");
map.put("LIKES_username","@");
List list = userMapper.listByParam(User.class, map);
list.forEach(user -> {
System.out.println(user);
});
session.close();
}
@Test
public void testInsert() throws Exception {
SqlSession session = MyBatisUtil.getSession();
User user = new User();
user.setUsername("asda");
user.setPazzword("123456");
user.setSalary(new BigDecimal(99.99));
user.setRegDate(new Date());
UserMapper userMapper = session.getMapper(UserMapper.class);
userMapper.insert(user);
// 提交事务
session.commit();
System.out.println(user.getId()); // 12
session.close();
}
@Test
public void testUpdate() throws Exception {
SqlSession session = MyBatisUtil.getSession();
User user = new User();
user.setId(11L);
user.setUsername("asda@121");
user.setSalary(new BigDecimal("98.99"));
UserMapper userMapper = session.getMapper(UserMapper.class);
userMapper.update(user);
// 提交事务
session.commit();
session.close();
}
@Test
public void testDelete() throws Exception {
SqlSession session = MyBatisUtil.getSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
userMapper.delete(User.class, 12L);
// 提交事务
session.commit();
session.close();
}
}
站在前辈的肩膀上,每天进步一点点
ends ~