先使用,后原理。
一、工具准备
本文运行环境:
JDK 1.8.0
Eclipse Oxygen.3a Release (4.7.3a)
MySQL 8.0.12-standard
二、Mybatis简介
官网定义: MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手工设置参数以及抽取结果集。MyBatis 使用简单的 XML 或注解来配置和映射基本体,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
使用上来说,就是帮我们省去了手动写代码来和数据库建立连接以及从数据库中抽取数据这些麻烦事,让程序员可以专注于SQL核心代码。
三、准备源数据
在mySQL服务器上建立myjava数据库,在数据库中建立table product_(id, name, price)。
使用终端/可视化界面均可。
MySQL Server常用命令戳:这里,博主总结得非常详细。
建表代码:
/* 设置id自增,使用MyISAM引擎避免插入记录时自增id不连续 */
CREATE TABLE product_ (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(32) DEFAULT NULL,
price float(32,8) NOT NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
然后插入一些数据:
insert into product_ (name, price) values ('apple',12),('book',35.5),('pen',2.0);
这张product_表的初始内容:
四、实现通过Mybatis操纵数据库
1)新建Java Project,此例命名为mybatis。
2)导入需要的jar包。
- mybatis-3.4.2.jar
- mysql-connector-java-5.0.8-bin.jar
3)项目文件目录如下:
4)各文件内容。
- mybatis-config.xml:配置连接的数据库信息和mapper位置。
<?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>
<!-- 加上typeAliases配置可以直接使用pojo package中类的名字,不用全名 -->
<typeAliases>
<package name="pojo"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!-- 配置要连接的数据库信息 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/myjava?characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="yourpassword"/>
</dataSource>
</environment>
</environments>
<!-- SQL语句写在这个文件里 -->
<mappers>
<mapper resource="pojo/Query.xml"/>
</mappers>
</configuration>
- Query.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="pojo">
<!-- 定义对product_表的增、删、改操作 -->
<insert id="addProduct" parameterType="Product">
insert into product_ (name, price) values (#{name}, #{price})
</insert>
<delete id="deleteProduct" parameterType="Product">
delete from product_ where id=#{id}
</delete>
<update id="updateProduct" parameterType="Product">
update product_ set name=#{name}, price=#{price} where id=#{id}
</update>
<!-- 按id返回产品信息 -->
<select id="getProductById" parameterType="_int" resultType="Product">
select * from product_ where id=#{id}
</select>
<!-- 获取全部产品信息 -->
<select id="listProduct" resultType="Product">
select * from product_
</select>
<!-- ====================================
多条件查询:
查询 id大于指定序号,且名称以#{name}开头的产品
======================================= -->
<select id="listProductByIdAndName" parameterType="map" resultType="Product">
select * from product_ where id>#{id} and name like concat(#{name},'%')
</select>
</mapper>
- Product.java:product实体类
package pojo;
public class Product {
private int id;
private String name;
private float price;
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 float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public String toString() {
return id+"\t"+name +"\t"+price;
}
}
- ProductManager.java:实现对数据库进行操作的接口函数,供主程序调用
package manager;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.session.SqlSession;
import pojo.Product;
public class ProductManager {
/* 添加记录 */
public void addProduct(SqlSession session, String name, float price) {
Product p = new Product();
p.setName(name);
p.setPrice(price);
session.insert("addProduct", p);
System.out.println("插入记录" + p.getName());
}
/* 删除指定id的记录
* 如果该记录不存在
* 打印提示信息,不做删除*/
public void deleteProduct(SqlSession session, int id) {
System.out.println("尝试删除id为"+id+"的记录");
Product p = getProductById(session, id);
if(p == null) return;
session.delete("deleteProduct",id);
System.out.println("成功删除第"+id+"条记录");
}
/* 查找指定id的记录
* 如果该记录不存在
* 打印提示信息 */
public Product getProductById(SqlSession session, int id) {
Product p = session.selectOne("getProductById",id);
if(p == null) {
System.out.println("记录不存在!");
}
return p;
}
/* 修改指定id的记录
* 如果该记录不存在
* 打印提示信息,不做修改*/
public void updateProduct(SqlSession session, int id, String name, float price) {
System.out.println("尝试修改id为"+id+"的记录");
Product p = getProductById(session, id);
if(p == null) return;
p.setName(name);
p.setPrice(price);
session.update("updateProduct", p);
System.out.println("成功修改第"+id+"条记录");
}
/* product_: 多条件查询
* 输出序列号大于id,且名称以name开头的产品信息
* 返回符合条件的记录条数
*
* 因为selectList只接受一个参数对象
* 故将多个参数装进map里传入 */
public int listProductByIdAndName(SqlSession session, int id, String name) {
Map<String, Object> params = new HashMap<>();
params.put("id",id);
params.put("name", name);
List<Product> multiSelectResult = session.selectList("listProductByIdAndName", params);
for(Product p: multiSelectResult) {
System.out.println(p);
}
return multiSelectResult.size();
}
/* 打印当前所有产品信息 */
public void listAllProduct(SqlSession session) {
List<Product> pl=session.selectList("listProduct");
System.out.println("当前产品如下:");
/*for(int i=0; i < pl.size(); i++) {
System.out.println((i+1)+"\t"+pl.get(i));
}*/
for(Product p: pl) {
System.out.println(p);
}
System.out.println();
}
}
- TestMybatis.java:测试类,先与数据库建立会话(session),然后通过此session对象对数据库进行操作。
package test;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import manager.*;
public class TestMybatis {
public static void main(String[] args) throws IOException {
//根据配置文件mybatis-config.xml得到sqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//建立会话
SqlSession session=sqlSessionFactory.openSession();
ProductManager m1 = new ProductManager();
{数据库操作测试代码:详见步骤5}
/*使用commit方法将更改提交到数据库*/
session.commit();
session.close();
}
}
5)运行结果。
- 打印当前产品信息
m1.listAllProduct(session);
- 插入记录测试
/* porduct_:插入记录测试 */
m1.addProduct(session, "beef", 60);
m1.listAllProduct(session);
- 删除记录测试
/* product_: 删除记录测试 */
m1.deleteProduct(session, 5);
m1.listAllProduct(session);
- 修改记录测试
/* product_: 修改记录测试 */
m1.updateProduct(session, 1, "pineapple", 100);
m1.listAllProduct(session);
- 多条件查询测试
/* product_: 多条件查询测试*/
System.out.println("满足条件的记录为:");
m1.listProductByIdAndName(session, 0, "b");
6)执行操作后数据库中数据也发生改变。
五、问题及解决
问题描述:运行TestMybatis时与数据库建立连接失败,出现MySQLNonTransientConnectionException: Client does not support authentication protocol requested by server; consider upgrading MySQL client
错误。
问题原因: 4.1版本后的MySQL身份验证协议使用密码hash算法,与本文使用的客户端算法不兼容。官网原文如下:https://dev.mysql.com/doc/refman/5.5/en/old-client.html
The current implementation of the authentication protocol uses a password hashing algorithm that is incompatible with that used by older (pre-4.1) clients.
解决方式:在MySQL中修改密码为旧密码验证方式。
SET PASSWORD FOR 'some_user'@'some_host' = OLD_PASSWORD('new_password');
文章内容参考自:http://how2j.cn/k/mybatis/mybatis-tutorial/1087.html?p=52209
为记录学习过程所需,侵删。