原生态 JDBC 程序问题总结:
1, 数据库连接, 使用时就创建, 不使用立即释放. 该操作是对数据库进行频繁连接开启和关闭, 造成数据库资源浪费, 影响数据库性能.
解决: 使用数据库连接池管理数据库连接.
2, 将 sql 语句硬编码到 java 代码中, 若 sql 语句修改, 需要重新编译 java 代码, 不利于维护.
解决: 将 sql 语句配置在 xml 配置文件中, 即使 sql 变化, 也不需要对 java 代码进行重新编译.
3, 在向 PreparedStatement 中设置参数时, 对占位符位置和设置参数值, 硬编码在 Java 代码中, 不利于维护.
解决: 将 sql 语句及占位符和参数全部配置在 xml 配置文件中.
4, 从 ResutSet 中遍历结果集数据时, 存在硬编码, 将获取表的字段进行硬编码, 不利于维护.
解决: 将查询的结果集, 自动映射成 Java 对象.
Mybatis 简述:
mybatis 是一个持久层框架, 是 Apache 下的顶级项目. mybatis 的前身是 ibatis.mybatis 开始是托管到 goolecode 下, 再后来托管到 GitHub 下(https://github.com/mybatis/mybatis-3/releases)
mybatis 让程序将主要精力放在 sql 上, 通过 mybatis 提供的映射方式, 自由灵活生成 (半自动) 满足需要 sql 语句.
mybatis 可以将向 PreparedStatement 中的输入参数自动进行输入映射, 将查询结果集灵活映射成 Java 对象(输出映射)
Mybatis 框架原理:
SqlMapConfig.xml:mybatis 的全局配置文件, 名称不固定; 配置了数据源, 事务等 mybatis 运行环境. mybatis 还需要配置 mapper.xml,mapper.xml 等, mapper.xml 就是映射文件(配置 sql 语句).
SqlSessionFactory: 会话工厂. 根据配置文件创建工厂. 作用就是创建 SqlSession.
SqlSession: 会话. 是一个接口, 面向用户的接口. 作用, 进行 crud 数据库操作.
Executor: 执行器. 是一个接口, 存在俩个实现: 基本执行器, 缓存执行器. 作用, SqlSession 内部通过执行器进行 crud 数据库操作.
mapped statement: 底层封装对象. 作用, 对 crud 数据库操作存储封装, 包含 sql 语句, 输入参数, 输出结果类型.
Mybatis 入门程序:
映射文件:
1, 映射文件命名: User.xml(原始 ibatis 命名.),mapper 代理开发映射文件名称为: XXXMapper. 如: 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">
- <!-- namespace 命名空间, 作用就是对 sql 进行分类化管理, 理解 sql 隔离
- 注意: 使用 mapper 代理方法开发, namespace 有特殊重要的作用 -->
- <mapper namespace="test">
- <!-- 再映射文件中配置很多的 sql 语句:
- select 标签执行数据库查询
- id: 标识映射文件中的 sql, 将 sql 语句封装到 mappedStatement 对象中, 所以将 id 称为 statement 的 id
- parameterType: 指定输入参数的类型.
- resultType: 输出类型. 指定 sql 输出结果的所映射的 java 对象类型, select 指定 resultType 表示将单条记录映射成的 Java 对象.
- #{}: 表示一个占位符号
- #{id}: 其中的 id 表示接入输入的参数, 参数名称就是 id, 如果输入参数是简单类型,#{}中的参数名可以任意; 可以是 value 或其他名称.
- -->
- <select id="findUserById" parameterType="参数的类型. 如: int" resultType="">
- select * from t_User where id=#{id}
- </select>
- <!-- 无论 sql 语句返回的是单条记录或多条记录都是所映射的 Java 对象类型
- ${}: 表示拼接 sql 串, 将接收到参数的内容不加任何修饰拼接在 sql 中. 使用 ${}拼接 sql, 会引起 sql 注入.
- ${value}: 接收输入参数的内容, 若传入类型是简单类型,${}中只能使用 value -->
- <select id="findUserByName" parameterType="String" resultType="cn.ccir.mybatis.entity.User">
- select * from t_User where username like '%${value}%'
- </select>
- <!-- 添加配置
- parameterType: 指定输入参数类型是 pojo(普通的 java 对象)
- #{}中指定 pojo 的属性名, 接收到 pojo 对象的属性值, mybatis 通过 OGNL 获取对象的属性值 -->
- <insert id="insertUser" parameterType="cn.ccir.mybatis.entity.User">
- <!-- 将插入数据的自增主键值返回, 返回到 user 对象中
- select LAST_INSERT_ID(): 得到刚 insert 的记录主键值, 只适用于自增主键
- keyProperty: 将查询到主键值设置到 parameterType 指定对象的那个属性
- order:select LAST_INSERT_ID()的执行顺序, 相对于 insert 语句来说它的指定顺序
- resultType: 指定 select LAST_INSERT_ID()的结果类型 -->>
- <selectKey keyProperty="id" order="AFTER" resultType="java.long.Integer">
- select LAST_INSERT_ID()
- </selectKey>
- <!-- 或 -->
- <!-- 将插入数据的非自增主键值返回, uuid()得到主键, 在 insert 语句之前执行.
- 通过 uuid()得到主键, 将主键设置到 user 对象的 id 属性中. 其次在 insert 执行时, 从 user 对象中去除 id 属性值 -->
- <selectKey keyProperty="id" order="BEFORE" resultType="java.long.String">
select uuid()(MySQL)/select 序列名. nextval()(oracle)
- </selectKey>
- insert into user(id,username,birthday,sex,address)value(#{id},#{username},#{birthday},#{sex},#{address})
- </insert>
- <!-- 删除配置 -->>
- <delete id="deleteUserById" parameterType="java.lang.Integer">
- delete from t_User where id=#{id}
- </delete>
- <!-- 修改配置
- parameterType: 指定 user 对象, 包括 id 和更新信息. 注: id 必须在 User 对象中存在
- #{}: 从输入 User 对象中获取 id 属性值 -->>
- <update id="updateUserById" parameterType="cn.ccir.mybatis.entity.User">
- update t_User set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
- </update>
- </mapper>
UserMapper.xml
2, 在 SqlMapConfig.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>
- <!-- 和 spring 整合后 environments 配置将废除 -->
- <environments default="development">
- <environment id="development">
- <!-- 使用 jdbc 事务管理, 事务控制由 mybatis -->
- <transactionManager type="JDBC"></transactionManager>
- <!-- 数据库连接池, 有 mybatis 管理 -->
- <dataSource type="POOLED">
- <property name="driver" value=""/>
- <property name="url" value=""/>
- <property name="username" value=""/>
- <property name="password" value=""/>
- </dataSource>
- </environment>
- </environments>
- <!-- 加载映射文件 -->
- <mappers>
- <mapper resource="UserMapper.xml"/>
- </mappers>
- </configuration>
SqlMapConfig.xml
- public void findUserById() throws IOException{
- // 加载配置文件得到流对象
- String resource="SqlMapConfig.xml";
- InputStream inputStream=Resources.getResourceAsString(resource);
- // 创建会话工厂
- SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
- // 通过工厂得到 SqlSession
- SqlSession sqlSession=sqlSessionFactory.openSession();
- // 通过 SqlSession 来 curd 数据库
- // 第一个参数: 映射文件中是 statement 的 id, 等于 namespace+"."+statement 的 id
- // 第二个参数: 指定和樱色和文件中所匹配的 parameterType 类型的参数.
- //sqlSession.selectOne 结果是与映射文件中所匹配的 resultType 类型的对象. 查询出的是一条记录.
- //sqlSession.selectList 查询出的是多条记录.
- User user = sqlSession.selectOne("test.findUserById",parameter,1);
- // 方法名: findUserByName
- List<User> list = sqlSession.selectList("test.findUserByName","条件值");
- // 添加 方法名: insertUser
- User user=new User();
- user.setUsername("");
- user.setBirthday(new Date());
- user.setSex("");
- user.setAddress("");
- ......
- sqlSession.insert("test.insertUser",user);
- sqlSession.commit();// 提交事务
- // 删除 方法名: deleteUserById
- sqlSession.delete("test.deleteUserById",1);
- sqlSession.commit();// 提交事务
- user.getId();// 获取主键 id 值.
- // 修改 方法名: updateUserById
- User user=new User();
- user.setId("");
- user.setUsername("");
- user.setBirthday(new Date());
- user.setSex("");
- user.setAddress("");
- ......
- sqlSession.insert("test.updateUserById",user);
- sqlSession.commit();// 提交事务
- // 释放资源
- sqlSession.close();
- }
Crud 实例
- #{} 与 ${}:
- #{}: 表示一个占位符, 接收输入参数, 类型可以时简单类型, pojo(简单 java 对象),hashmap.
若 #{}接收简单类型,#{}中可以写成 value 或其他名称.
若 #{}接收 pojo 对象值, 通过 OGNL 读取对象中的属性值, 通过属性. 属性. 属性... 的方式获取对象属性.
${}: 表示一个拼接符号, 会引用 sql 注入, 所以不建议使用 ${}. 接收输入参数, 类型可以时简单类型, pojo,hashmap.
若 ${}接收简单类型,${}中只能写成 value.
若 ${}接收 pojo 对象值, 通过 OGNL 读取对象中的属性值, 通过属性. 属性. 属性... 的方式获取对象属性.
Mybatis 和 Hibernate 本质区别及应用场景:
Hibernate: 是一个标准的 ORM 框架(对象关系映射). 入门门槛较高, 不需要书写 sql 语句, hibernate 会自动生成. 对 sql 进行优化, 修改比较困难.
Mybatis: 专注是 sql 本身, 需要书写 sql 语句, sql 的优化, 修改比较方便. Mybatis 不是一个完全的 ORM 框架, 虽然可以实现映射(输入, 输出框架), 但还需要书写 sql.
.Net 转 Java 自学之路 - Mybatis 框架篇一(入门)
来源: http://www.bubuko.com/infodetail-2990222.html