mybatis 简单手写

一,定义实体

public class User {
    private int id;
    private String name;
    private int age;
    private String addr;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }


    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", addr='" + addr + '\'' +
                '}';
    }
}
二,定义xml

<?xml version="1.0" encoding="UTF-8" ?>
<mapper namespace="test.dao.UserDao">
    <select id="getUserInfo" resultType="test.entity.User">
        select * from tb_user
        where id = ?;
    </select>

    <update id="updateUserName">
        update tb_user set name = ?
        where id = ?
    </update>

    <insert id="insertUser">
        insert into tb_user
        values(?, ?, ?, ?);
    </insert>
</mapper>

三,数据配置

public class Config {
    public static final Config DEFAULT = new Config();
    private Config() {

    }
    private String url = "jdbc:mysql://139.199.195.54:3306/weistudy";
    private String user = "root";
    private String pwd = "kurozakisql";
    private String mapperPath = "mapper/";
    public String getUrl() {
        return url;
    }
    public String getUser() {
        return user;
    }
    public String getPwd() {
        return pwd;
    }
    public String getMapperPath() {
        return mapperPath;
    }
}

四,数据源连接

public class ConnectionManager {

    public static Connection get() throws SQLException {
        return DriverManager.getConnection(
                Config.DEFAULT.getUrl(),
                Config.DEFAULT.getUser(),
                Config.DEFAULT.getPwd()
        );
    }
}

五,XMl 映射到实体文件

public class MapperInfo {

    private QueryType queryType;
    private String interfaceName;
    private String methodName;
    private String sql;
    private String resultType;

    public QueryType getQueryType() {
        return queryType;
    }

    public void setQueryType(QueryType queryType) {
        this.queryType = queryType;
    }

    public String getSql() {
        return sql;
    }

    public void setSql(String sql) {
        this.sql = sql;
    }

    public String getResultType() {
        return resultType;
    }

    public void setResultType(String resultType) {
        this.resultType = resultType;
    }

    public String getInterfaceName() {
        return interfaceName;
    }

    public void setInterfaceName(String interfaceName) {
        this.interfaceName = interfaceName;
    }

    public String getMethodName() {
        return methodName;
    }

    public void setMethodName(String methodName) {
        this.methodName = methodName;
    }

    @Override
    public String toString() {
        return "MapperInfo{" +
                "queryType=" + queryType +
                ", interfaceName='" + interfaceName + '\'' +
                ", methodName='" + methodName + '\'' +
                ", sql='" + sql + '\'' +
                ", resultType='" + resultType + '\'' +
                '}';
    }
}

接口方法

public interface UserDao {

    User getUserInfo(int id);

    int updateUserName(String newName, int id);

    int insertUser(int id, String name, int age, String addr);
}
 

 

六,定义枚举查询

public enum QueryType {
    SELECT, UPDATE, INSERT, DELETE;

    public static QueryType value(String v) {
        return valueOf(v.toUpperCase());
    }
}

七,SQL映射文件处理器

public enum SqlMappersHolder {

    INSTANCE;

    private Map<String, MapperInfo> mi = null;

    SqlMappersHolder() {
        if (mi != null)
            return;
        mi = new HashMap<>();

        File dir = new File(SqlMappersHolder.class
                .getClassLoader()
                .getResource(Config.DEFAULT.getMapperPath())
                .getFile());


        SAXReader reader = new SAXReader();
        try {
            for (String file : dir.list()) {
                Document doc = reader.read(new File(dir, file));
                Element root = doc.getRootElement();
                String className = root.attributeValue("namespace");

                for (Object o : root.elements()) {
                    Element e = (Element) o;

                    MapperInfo info = new MapperInfo();
                    info.setQueryType(QueryType.value(e.getName()));
                    info.setInterfaceName(className);
                    info.setMethodName(e.attributeValue("id"));
                    info.setResultType(e.attributeValue("resultType"));
                    info.setSql(e.getText());

                    mi.put(idOf(className, e.attributeValue("id")), info);
                }
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

    public MapperInfo getMapperInfo(String className, String methodName) {
        return mi.get(idOf(className, methodName));
    }

    private String idOf(String className, String methodName) {
        return className + "." + methodName;
    }
}

八,SQL执行处理器

public class SqlExecuteHandler implements InvocationHandler {

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // get mapper info
        MapperInfo info = getMapperInfo(method);

        // execute sql
        return executeSql(info, args);
    }

    private MapperInfo getMapperInfo(Method method) throws Exception {
        MapperInfo info = SqlMappersHolder.INSTANCE.getMapperInfo(
                method.getDeclaringClass().getName(),
                method.getName());
        if (info == null) {
            throw new Exception("Mapper not found for method: " +
                    method.getDeclaringClass().getName() + "." + method.getName());
        }
        return info;
    }

    private Object executeSql(MapperInfo info, Object[] params)
            throws SQLException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Object result = null;
        PreparedStatement pstat = ConnectionManager.get().prepareStatement(info.getSql());
        for (int i = 0; i < params.length; i++) {
            pstat.setObject(i + 1, params[i]);
        }


        if (info.getQueryType() == QueryType.SELECT) {
            ResultSet rs = pstat.executeQuery();
            rs.first();
            // 将查询结果映射为Java类或基本数据类型)
            // 目前简化版仅支持String和int两种类型
            if (rs.getMetaData().getColumnCount() == 1) {
                switch (info.getResultType()) {
                    case "int":
                        result = rs.getInt(1);
                        break;
                    default:
                        result = rs.getString(1);
                }
            } else {
                Class<?> resTypeClass = Class.forName(info.getResultType());
                Object inst = resTypeClass.newInstance();
                for (Field field : resTypeClass.getDeclaredFields()) {
                    String setterName = "set" +
                            field.getName().substring(0, 1).toUpperCase() +
                            field.getName().substring(1);
                    Method md;

                    switch (field.getType().getSimpleName()) {
                        case "int":
                            md = resTypeClass.getMethod(setterName, new Class[]{int.class});
                            md.invoke(inst, rs.getInt(field.getName()));
                            break;

                        default:
                            md = resTypeClass.getMethod(setterName, new Class[]{String.class});
                            md.invoke(inst, rs.getString(field.getName()));
                    }
                }
                result = inst;
            }
        } else {
            result = pstat.executeUpdate();
        }
        return result;
    }

}
十,SqlSession

public class SqlSession {

    @SuppressWarnings("unchecked")
    public <T> T getMapper(Class<T> cls) {
        return (T) Proxy.newProxyInstance(cls.getClassLoader(),
                new Class[]{cls},
                new SqlExecuteHandler());
    }
}
十一,SqlSessionFactory.

public class SqlSessionFactory {

    static {
        SqlMappersHolder inst = SqlMappersHolder.INSTANCE;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public SqlSession openSession() {
        return new SqlSession();
    }
}

十二,测试

public class TestClient {

    public static void main(String[] args) {
    
        SqlSessionFactory factory = new SqlSessionFactory();
        SqlSession sqlSession = factory.openSession();

        UserDao userDao = sqlSession.getMapper(UserDao.class);

        System.out.println(userDao.getUserInfo(3));
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值