mybatis——持久层各种实现

一、JDBC

一个简单的JDBC连接

public class JDBCTest {

    public static void main(String[] args) throws Exception {
        //Class.forName("com.mysql.jdbc.Driver");1.5后SPI机制
        //打开连接
        Connection con = DriverManager.getConnection("jdbc:mysql://mcip:3306/study","root","123456");
        //创建语句
        Statement statement = con.createStatement();
        //指定sql并执行
        ResultSet resultSet = statement.executeQuery("select * from user");
        //循环遍历结果集
        while (resultSet.next()){
            //处理每条数据
            System.out.println(resultSet.getString("user_id")+"-"+
                    resultSet.getString("user_name"));
        }
        //关闭连接
        con.close();
    }
}

简单的JDBC存在诸多的缺点:

① 打开关闭连接

② 每次执行sql时,都要创建statement,然后执行

③ 结果集处理:循环遍历+处理每条数据

④ 没有事务的支持

二、JDBCTemplate

JDBCTemplate是spring-jdbc.jar中的核心类,借用下官网中的表格(第3节)

 可以看出:spring-jdbc只是一个部分解决方案,还算不上一个整体解决框架,主要解决了

① 自动打开释放连接

② 自动创建statement,开发仅需要指定sql语句,及参数

③ 事务的支持

④ 优化了结果集的遍历,但每条数据还是要开发人员处理

简单JDBCTemplate实现:

public class JdbcTemplateTests {

    private static JdbcTemplate jdbcTemplate = null;

    static {
        //创建数据源
        try (InputStream in = new FileInputStream("D:\\myGItHub\\spring-framework\\spring-study\\src\\test\\resources\\db.properties");){
            Properties properties = new Properties();
            properties.load(in);
            SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
            Class DriverClass = Class.forName(properties.getProperty("mysql.driver"));
            dataSource.setDriverClass((Class<? extends Driver>) DriverClass);
            dataSource.setUrl(properties.getProperty("mysql.url"));
            dataSource.setUsername(properties.getProperty("mysql.username"));
            dataSource.setPassword(properties.getProperty("mysql.password"));
            //创建jdbcTemplate
            jdbcTemplate = new JdbcTemplate(dataSource);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }

    @Test
    public void jdbcTemplateTest(){
        List<User> list = jdbcTemplate.query("select * from user", new RowMapper<User>() {
            @Override
            public User mapRow(ResultSet rs, int rowNum) throws SQLException {
                User user = new User();
                user.setId(rs.getLong("id"));
                user.setUserId(rs.getLong("user_id"));
                user.setUserName(rs.getString("user_name"));
                return user;
            }
        });
        if (list.isEmpty()){
            return;
        }
        User user = list.get(0);
        System.out.println(user);
        jdbcTemplate.update("update user set user_name = ? where id = ?","9527",user.getId());
        Map<String,Object> map = jdbcTemplate.queryForMap("select * from user where id = ?",user.getId());
        System.out.println(map);
    }
}

jdbcTemplate还遗留的问题:

① 结果集的每条数据,需要开发人员自己处理

② sql语句Java代码强耦合

三、mybatis与Hibernate

为解决上面所有问题而产生的整体性框架,例如mybatis、Hibernate。

① 结果集的每条数据自动映射成一个java对象

② sql在xml中配置与Java代码解耦(mybatis),直接去sql开发(hibernate)

1、常见的两个术语ORM与JPA

ORM:是Object Relational Mapping简称,中文名为对象关系映射。是通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中。本质就是实现程序对象到关系数据库数据的映射,程序对象操作会直接自动生成sql,然后操作数据库数据。不需要开发人员写sql语句。

JPA:是Java Persistence API简称,中文名为Java持久层API。由sun公司提供的POJO持久化标准规范,主要为了实现ORM。

JPA包括以下3方面技术:

ORM映射元数据:JPA支持xml或者注解两种元数据形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库中;

API:用来操作实体对象,执行CRUD操作,框架在后台代替我们完成所有的事情(包括自动生成sql),将开发人员从繁琐的JDBC和SQL代码中解脱出来

查询语言:通过面向对象而非面向数据库查询语言查询数据,避免程序的SQL语句紧密耦合。

2、mybatis与hibernate对比

hibernate:是一个全自动的ORM框架,开发人员仅需要操作映射对象,能自动生成sql语句,然后自动执行。有自己的HQL可提供更加灵活的查询能力。

mybatis:不是一个全自动的ORM框架,程序与数据库打交道还是通过开发人员写SQL语句来完成的,但保留了对象和表数据的映射关系,所以也称为半自动ORM框架(将SQL语句交由开发人员编写)。

3、mybatis简单实现

 mybatis原名是ibatis,3.0版本后改名为mybatis,框架改名意味着有重大升级

3.0之前即ibatis仅允许XML映射器,所有sql都在xml文件中配置,且这个xml文件需要配置到configuration下<mapper>中。使用时需要先引入SqlSession,然后执行

private SqlSession session;
public void setSqlSessino(SqlSession session){
    this.session = session;    
}
User s = session.selectOne("com.app.aop.transactional.mapper.UserMapper.selectByPrimaryKey", 1L);

3.0之后即mybatis开始支持接口映射器,其底层采用接口绑定技术。sql可以在接口方法上注解,也可以在xml文件中配置,提供一个接口解析器扫描某个package下所有的接口,不需要再配置<mapper>了

@Autowired
private UserMapper userMapper;//ali插件不建议这么注入了,建议采用构造方法注入
User s = userMapper.selectByPrimaryKey(1L);

简单实现:

public class MybatisTests {

    public static void main(String[] args) throws Exception {
        // 读取mybatis-config.xml文件
        InputStream inputStream = Resources.getResourceAsStream("mybatis-conf.xml");

        // 初始化mybatis,创建SqlSessionFactory类的实例
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        // 创建Session实例
        SqlSession session = sqlSessionFactory.openSession();

        // 操作数据库方法一(ibatis主要使用方式):获得xml映射文件中定义的操作语句
        User s = session.selectOne("com.app.aop.transactional.mapper.UserMapper.selectByPrimaryKey", 1L);
        // 打印Student对象
        System.out.println(s);

        // 操作数据库方法二(mybatis主要使用方式):获得mapper接口的代理对象
        UserMapper sm = session.getMapper(UserMapper.class);
        // 直接调用接口的方法,查询id为1的Student数据
        User s2 = sm.selectByPrimaryKey(1L);
        // 打印Peson对象
        System.out.println(s2);

        // 提交事务
        session.commit();
        // 关闭Session
        session.close();
    }
}

mybatis-conf.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- 配置文件的根元素 -->
<configuration>
    <!-- 属性:定义配置外在化 -->
    <properties resource="db.properties" />

    <!-- 环境:配置mybatis的环境 -->
    <environments default="dev">
        <!-- 环境变量:可以配置多个环境变量,比如使用多数据源时,就需要配置多个环境变量 -->
        <environment id="dev">
            <!-- 事务管理器 -->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 数据源 -->
            <dataSource type="POOLED">
                <property name="driver" value="${mysql.driver}"/>
                <property name="url" value="${mysql.url}"/>
                <property name="username" value="${mysql.username}"/>
                <property name="password" value="${mysql.password}"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 映射器:指定映射文件或者映射类 -->
    <mappers>
        <mapper resource="mapper/UserMapper.xml"/>
    </mappers>
</configuration>

db.propertis

mysql.driver=com.mysql.cj.jdbc.Driver
mysql.url=jdbc:mysql://mcip:3306/study
mysql.username=root
mysql.password=123456

UserMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.app.aop.transactional.mapper.UserMapper">
  <resultMap id="BaseResultMap" type="com.app.aop.transactional.model.User">
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="user_id" jdbcType="BIGINT" property="userId" />
    <result column="user_name" jdbcType="VARCHAR" property="userName" />
  </resultMap>
  <sql id="Base_Column_List">
    id, user_id, user_name
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from user
    where id = #{id,jdbcType=BIGINT}
  </select>
</mapper>

UserMapper.java

public interface UserMapper {

    User selectByPrimaryKey(Long id);

}

 

posted on 2020-03-06 22:04  FFStayF  阅读(710)  评论(0编辑  收藏  举报