Mybatis(一)入门程序
来源:互联网 发布:数据量化方法 编辑:程序博客网 时间:2024/06/06 05:45
对原生态JDBC问题总结
原生JDBC代码
- package com.utils;
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- /**
- * @ClassName: JdbcTest
- * @Description: TODO(原始的JDBC操作数据库)
- * @author warcaft
- * @date 2015-6-27 下午3:31:22
- *
- */
- public class JdbcTest {
- public static void main(String[] args) {
- // 数据库连接
- Connection connection = null;
- // 预编译的Statement,使用预编译的Statement提高数据库性能
- PreparedStatement preparedStatement = null;
- // 结果 集
- ResultSet resultSet = null;
- try {
- // 加载数据库驱动
- Class.forName("com.mysql.jdbc.Driver");
- // 通过驱动管理类获取数据库链接
- connection = DriverManager
- .getConnection(
- "jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8",
- "root", "root");
- // 定义sql语句 ?表示占位符
- String sql = "select * from t_user where username = ?";
- // 获取预处理statement
- preparedStatement = connection.prepareStatement(sql);
- // 设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
- preparedStatement.setString(1, "王五");
- // 向数据库发出sql执行查询,查询出结果集
- resultSet = preparedStatement.executeQuery();
- // 遍历查询结果集
- while (resultSet.next()) {
- System.out.println(resultSet.getString("id") + " "
- + resultSet.getString("username"));
- }
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- // 释放资源
- if (resultSet != null) {
- try {
- resultSet.close();
- } catch (SQLException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- if (preparedStatement != null) {
- try {
- preparedStatement.close();
- } catch (SQLException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- if (connection != null) {
- try {
- connection.close();
- } catch (SQLException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
- }
问题总结
1、数据库连接,使用时就创建,不使用立即释放,对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响数据库性能。
解决方案:使用数据库连接池管理数据库连接。
2、将sql语句硬编码到java代码中,如果sql 语句修改,需要重新编译java代码,不利于系统维护。
解决方案:将sql语句配置在xml配置文件中,即使sql变化,不需要对java代码进行重新编译。
3、向preparedStatement中设置参数,对占位符号位置和设置参数值,硬编码在java代码中,不利于系统维护。
解决方案:将sql语句及占位符号和参数全部配置在xml中。
4、从resutSet中遍历结果集数据时,存在硬编码,将获取表的字段进行硬编码,,不利于系统维护。
解决方案:将查询的结果集,自动映射成java对象。
MyBatis框架原理
MyBatis是什么?
(下载地址:https://github.com/mybatis/mybatis-3/releases)
MyBatis 本是apache的一个开源项ibatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis,实质上Mybatis对ibatis进行一些改进。
MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
原理如图
1、mybatis配置
SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。
mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。
2、通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
3、由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
4、mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。
5、Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。
6、Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
7、Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。
入门程序
需求
对订单商品案例中的用户表进行增删改查操作
- 根据用户ID查询用户信息
- 根据用户名称模糊查询用户列表
- 添加用户
- 删除用户(练习)
- 修改用户(练习)
环境转呗
Jdk:1.8
Ide:idea
Mybatis:3.2.7
数据库:MySQL 5.7
数据库脚本初始化
先执行sql_table.sql再执行sql_data.sql
Sql_table
- /*
- SQLyog v10.2
- MySQL - 5.1.72-community : Database - mybatis
- *********************************************************************
- */
- /*!40101 SET NAMES utf8 */;
- /*!40101 SET SQL_MODE=''*/;
- /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
- /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
- /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
- /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
- /*Table structure for table `items` */
- CREATE TABLE `items` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `name` varchar(32) NOT NULL COMMENT '商品名称',
- `price` float(10,1) NOT NULL COMMENT '商品定价',
- `detail` text COMMENT '商品描述',
- `pic` varchar(64) DEFAULT NULL COMMENT '商品图片',
- `createtime` datetime NOT NULL COMMENT '生产日期',
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
- /*Table structure for table `orderdetail` */
- CREATE TABLE `orderdetail` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `orders_id` int(11) NOT NULL COMMENT '订单id',
- `items_id` int(11) NOT NULL COMMENT '商品id',
- `items_num` int(11) DEFAULT NULL COMMENT '商品购买数量',
- PRIMARY KEY (`id`),
- KEY `FK_orderdetail_1` (`orders_id`),
- KEY `FK_orderdetail_2` (`items_id`),
- CONSTRAINT `FK_orderdetail_1` FOREIGN KEY (`orders_id`) REFERENCES `orders` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
- CONSTRAINT `FK_orderdetail_2` FOREIGN KEY (`items_id`) REFERENCES `items` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
- ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
- /* constraint 中文为约束的意思,constraint 约束名 foreign key(列名) references (主表列名)*/
- /*Table structure for table `orders` */
- CREATE TABLE `orders` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `user_id` int(11) NOT NULL COMMENT '下单用户id',
- `number` varchar(32) NOT NULL COMMENT '订单号',
- `createtime` datetime NOT NULL COMMENT '创建订单时间',
- `note` varchar(100) DEFAULT NULL COMMENT '备注',
- PRIMARY KEY (`id`),
- KEY `FK_orders_1` (`user_id`),
- CONSTRAINT `FK_orders_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
- ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
- /*Table structure for table `user` */
- CREATE TABLE `user` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `username` varchar(32) NOT NULL COMMENT '用户名称',
- `birthday` date DEFAULT NULL COMMENT '生日',
- `sex` char(1) DEFAULT NULL COMMENT '性别',
- `address` varchar(256) DEFAULT NULL COMMENT '地址',
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
- /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
- /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
- /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
- /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
Sql_data
- /*
- SQLyog v10.2
- MySQL - 5.1.72-community : Database - mybatis
- *********************************************************************
- */
- /*!40101 SET NAMES utf8 */;
- /*!40101 SET SQL_MODE=''*/;
- /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
- /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
- /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
- /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
- /*Data for the table `items` */
- insert into `items`(`id`,`name`,`price`,`detail`,`pic`,`createtime`) values (1,'台式机',3000.0,'该电脑质量非常好!!!!',NULL,'2015-02-03 13:22:53'),(2,'笔记本',6000.0,'笔记本性能好,质量好!!!!!',NULL,'2015-02-09 13:22:57'),(3,'背包',200.0,'名牌背包,容量大质量好!!!!',NULL,'2015-02-06 13:23:02');
- /*Data for the table `orderdetail` */
- insert into `orderdetail`(`id`,`orders_id`,`items_id`,`items_num`) values (1,3,1,1),(2,3,2,3),(3,4,3,4),(4,4,2,3);
- /*Data for the table `orders` */
- insert into `orders`(`id`,`user_id`,`number`,`createtime`,`note`) values (3,1,'1000010','2015-02-04 13:22:35',NULL),(4,1,'1000011','2015-02-03 13:22:41',NULL),(5,10,'1000012','2015-02-12 16:13:23',NULL);
- /*Data for the table `user` */
- insert into `user`(`id`,`username`,`birthday`,`sex`,`address`) values (1,'王五',NULL,'2',NULL),(10,'张三','2014-07-10','1','北京市'),(16,'张小明',NULL,'1','河南郑州'),(22,'陈小明',NULL,'1','河南郑州'),(24,'张三丰',NULL,'1','河南郑州'),(25,'陈小明',NULL,'1','河南郑州'),(26,'王五',NULL,NULL,NULL);
- /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
- /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
- /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
- /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
搭建工程
- Mybatis的核心包和依赖包
- MySQl的驱动包
- Junit(非必须)
代码创建
代码在Mybatis01中
db.properties和log4j.properties
创建po类
以及相应的getter和setter
创建全局配置文件
在config目录下,创建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>
- <!-- 加载java的配置文件或者声明属性信息 -->
- <properties resource="db.properties">
- </properties>
- <!-- 配置mybatis的环境信息,与spring整合,该信息由spring来管理 -->
- <environments default="development">
- <environment id="development">
- <!-- 配置JDBC事务控制,由mybatis进行管理 -->
- <transactionManager type="JDBC"></transactionManager>
- <!-- 配置数据源,采用mybatis连接池 -->
- <dataSource type="POOLED">
- <property name="driver" value="${db.driver}" />
- <property name="url" value="${db.url}" />
- <property name="username" value="${db.username}" />
- <property name="password" value="${db.password}" />
- </dataSource>
- </environment>
- </environments>
- <!-- 加载映射文件 -->
- <mappers>
- <mapper resource="User.xml"></mapper>
- </mappers>
- </configuration>
需求加法
根据用户ID查询用户信息
映射文件
在config目录下创建user.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:命名空间,对statement的信息进行分类管理 -->
- <!-- 注意:在mapper代理时,它具有特殊及重要的作用 -->
- <mapper namespace="test">
- <!-- 根据用户ID查询用户信息 -->
- <!-- select:表示一个MappedStatement对象 -->
- <!-- id:statement的唯一标示 -->
- <!-- #{}:表示一个占位符? -->
- <!-- #{id}:里面的id表示输入参数的参数名称,如果该参数是简单类型,那么#{}里面的参数名称可以任意 -->
- <!-- parameterType:输入参数的java类型 -->
- <!-- resultType:输出结果的所映射的java类型(单条结果所对应的java类型) -->
- <select id="findUserById" parameterType="int" resultType="com.lichao.po.User">
- SELECT * FROM USER WHERE id=#{id};
- </select>
- </mapper>
全局配置文件中加载映射文件
前面全局配置文件时候已经加上了
测试代码
在test文件夹下创建包first,新建UserTest类
根据用户名模糊查询用户列表
映射文件
测试代码
小结
- #{}和${}
#{}表示占位符?,#{}接收简单类型的参数时,里面的名称可以任意
${}表示拼接符,${}接收简单类型的参数时,里面的名称必须是value
${}里面的值会原样输出,不加解析(如果该参数值是字符串,有不会添加引号)
${}存在sql注入的风险,但是有些场景下必须使用,比如排序后面会动态传入排序的列名
- parameterType和resultType
parameterType指定输入参数的java类型,parameterType只有一个,也就是说入参只有一个。
resultType指定输出结果的java类型(是单条记录的java类型)
- selectOne和selectList
selectOne查询单个对象
selectList查询集合对象
- Mybatis(一)入门程序
- Mybatis入门程序一
- Mybatis总结(一)--初始Mybatis及入门程序
- [MyBatis]MyBatis入门(一)
- MyBatis入门(一)
- Mybatis入门(一)
- Mybatis入门(一)
- MyBatis入门(一)
- MyBatis入门(一)
- mybatis入门(一)
- mybatis学习笔记(3)-入门程序一
- Mybatis学习笔记(三)【入门程序一】
- mybatis(1)mybatis入门程序
- MyBatis(4)MyBatis入门程序
- Mybatis总结(3)---Mybatis入门程序
- 深入浅出Mybatis系列(一)---Mybatis入门
- 深入浅出Mybatis系列(一)---Mybatis入门
- 深入浅出Mybatis系列(一)---Mybatis入门
- 猜数字游戏
- 【PHP】XAMPP不下载自带MYSQL,配置为原已安装MYSQL方法
- RTMP、RTSP、HTTP协议
- Constructing Roads POJ
- uvm学习总结(1)--激励
- Mybatis(一)入门程序
- Android 插件化和热修复知识梳理
- Neo4j图形数据库环境安装(一)
- 171126 Misc-湖湘杯部分
- 二叉树遍历的应用(递归!递归!递归!)
- dns正反向解析
- 判断一个数是否为质数/素数——从普通判断算法到高效判断算法思路
- 6603网狐棋牌搭建视频教程
- Reusing Code in C++: inheriting and template