Mybatis 学习笔记(一)自定义持久层框架
原始jdbc 存在的问题:
问题 | 解决方案 |
---|---|
数据库连接创建、释放频繁,浪费资源 | 连接池 |
sql硬编码,不易维护 | 配置文件 |
sql 参数硬编码 | 配置文件 |
返回结果集,封装麻烦 | 反射、内省 |
什么是内省?
参考:https://blog.csdn.net/z714405489/article/details/84650307
反射
是在运行状态把Java类中的各种成分映射成相应的Java类,可以动态的获取所有的属性以及动态调用任意一个方法,强调的是运行状态。
内省(IntroSpector)
是Java 语言针对 Bean 类属性、事件的一种缺省处理方法。 JavaBean是一种特殊的类,主要用于传递数据信息,这种类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。如果在两个模块之间传递信息,可以将信息封装进JavaBean中,这种对象称为“值对象”(Value Object),或“VO”。方法比较少。这些信息储存在类的私有变量中,通过set()、get()获得。内省机制是通过反射来实现的,BeanInfo用来暴露一个bean的属性、方法和事件,以后我们就可以操纵该JavaBean的属性。
package com.example.mybatis;
import com.alibaba.fastjson.JSON;
import com.example.mybatis.bean.User;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
public class JDBC {
/**
* jdbc 关键信息
* connection 数据库连接
* PreparedStatement 预处理statement
* resultSet 返回结果集
* @param args
*/
public static void main(String[] args) {
Connection connection=null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2 创建连接
//Properties properties=new Properties();
//properties.put("username","root");
// properties.put("password","123456");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8", "root","123456");
// sql ?
String sql = "select * from user ";
// statement
preparedStatement = connection.prepareStatement(sql);
// preparedStatement.setString(1,"tom");
resultSet = preparedStatement.executeQuery();
List<User> users=new ArrayList<>();
while (resultSet.next()) {
int id = resultSet.getInt("id");
String name = resultSet.getString("name"); // User
//getDate只能获取年月日 是不是很神奇
Date createDate = resultSet.getDate("create_date");
Time create_date = resultSet.getTime("create_date");
//20:00:00
System.out.println(create_date);
Timestamp create_date1 = resultSet.getTimestamp("create_date");
//2020-07-09 20:00:00.0 todo 为什么会加0? 与版本的字段类型有关 mysql 中的字段类型是dateTime
System.out.println(create_date1);
//好久没写jdbc 都快忘记了。。。。
int age = resultSet.getInt("age");
User user = new User();
user.setId(id);
user.setName(name);
user.setAge(age);
user.setCreateDate(create_date1);
users.add(user);
}
System.out.println(users.size());
/**
* date
* User{id=1, name='你好', age=11, createDate=2020-07-09}
* json转
* {"age":11,"createDate":1594296000000,"id":1,"name":"你好"} timestamp
* tostring
* User{id=1, name='你好', age=11, createDate=2020-07-09 20:00:00.0}
*/
users.forEach(x->System.out.println(x));
}catch (Exception e){
e.printStackTrace();
}finally {
//
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (preparedStatement != null) {
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
} }
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
自定义持久化框架思路
1.配置文件
sqlMapperConfig.xml 存放数据库配置信息和mapper.xml的全路径
<configuration>
<!--数据库配置信息-->
<dataSource>
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql:///zdy_mybatis"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</dataSource>
<!--存放mapper.xml的全路径-->
<mapper resource="UserMapper.xml"></mapper>
</configuration>
mapper.xml 存放sql映射
<!--
namespace dao映射的全路径
paramterType 参数类型(实体类全路径)类中的属性必须与数据库中的字段保持一致
resultType 返回值类型 (实体类全路径)类中的属性必须与数据库中的字段保持一致
-->
<mapper namespace="com.example.mybatis.dao.IUserDao">
<select id="selectOne" paramterType="com.example.mybatis.bean.User"
resultType="com.example.mybatis.bean.User">
select * from user where id = #{id} and name =#{name}
</select>
<select id="selectList" resultType="com.example.mybatis.bean.User">
select * from user
</select>
</mapper>
2.持久层框架的执行流程