MyBatis概念
Mybatis是一个支撑框架,它以映射sql语句orm方式来数据库持久化操作
框架的概念
解决一个开放性问题而设计的具有一定约束性的支撑结构,所谓的框架就是提供的一些基础支撑结构,通过这些结构可以解决现实生活中具体点的问题,而在这个过程中必须遵循一定规范.
数据库持久化
数据库持久化:把内存中数据保存到数据库中.
mybatis相较于jdbc的优点
MyBatis入门
准备相关的表,创建相关的实体类
准备相关的dao层,提供CRUD方法
实现步骤
获取SqlSessionFactory
我们需要准备一个核心的Mybatis-config.xml文件
拿到SqlSessionFactory之前需要读取核心的xml配置文件
需要构造者(SqlSessionFactoryBuilder)来创建它
映射文件准备
通过SqlSessionFactory获取SqlSession执行映射SQL
编写配置文件 mybatis-config.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>
<!--(1)引入jdbc.propeties文件-->
<properties resource="jdbc.properties" />
<!-- 环境们 (很多环境的意思)
default:默认使用哪一个环境(必需对应一个环境的id)
-->
<typeAliases>
<typeAlias alias="Product" type="com.xmh.domain.Product"/>
<!--如果配置包,包下面所有类都会定义别名,使用规则一般是就是类名或者类名首字母小写-->
<package name="com.xmh.domain"/>
<package name="com.xmh.dao"/>
<package name="com.xmh.query"/>
</typeAliases>
<environments default="development">
<!--
一个环境 id:为这个环境取唯一一个id名称
-->
<environment id="development">
<!--
事务管理 type:JDBC(支持事务)/MANAGED(什么都不做-就不用事务)
数据库引擎设置innodb
-->
<transactionManager type="JDBC" />
<!--
数据源, 连接池 type(POOLED):MyBatis自带的连接池
https://blog.csdn.net/crankz/article/details/82874158
-->
<dataSource type="POOLED">
<!-- 连接数据库的参数 -->
<property name="driver" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<!-- 这个mappers代表的是相应的ORM映射文件 -->
<mappers>
<mapper resource="com/xmh/dao/impl/ProductMapper.xml" />
</mappers>
</configuration>
配置连接数据库四大配置 jdbc.properties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///2019_10_28_mybatis
jdbc.username=root
jdbc.password=123456
配置ProductMapper.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的主要功能就是写sql
mapper:根
namespace:命令空间 (用来确定唯一) 以前这个是可以不加的,现在必需加
namespace的值,规则的:映射文件XxxMapper.xml所在的包+domain类名+Mapper
-->
<mapper namespace="com.xmh.dao.impl.ProductDaoImpl">
<!--
select : 这里面写查询语句
id:用来确定这条sql语句的唯一
以后我们确定唯一,也就是找sql语句 : namespace +.+ id
例: cn.itsource.mybatis.day1._1_hello.ProductMapper.get
parameterType : 传入的参数类型 long:大Long _long:小long (具体的对应请参见文档)
resultType : 结果类型(第一条数据返回的对象类型) 自己的对象一定是全限定类名
-->
<!--<select id="get" parameterType="long" resultType="cn.itsource.domain.Product">
select * from product where id = #{id}
</select>-->
<insert id="insert" parameterType="com.xmh.domain.Product" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
insert into product
(productName,brand,supplier,salePrice,costPrice)
values(#{productName},#{brand},#{supplier},#{salePrice},#{costPrice})
</insert>
<update id="update" parameterType="Product">
update product set
productName = #{productName},brand = #{brand},supplier = #{supplier},salePrice = #{salePrice},costPrice = #{costPrice}
where id = #{id}
</update>
<!--mybatis内置类型long 相当于java.lang.Long的别名-->
<delete id="delete" parameterType="long">
delete from product where id = #{id}
</delete>
<select id="selectOne" parameterType="long" resultType="Product">
select * from product where id = #{id}
</select>
<select id="selectAll" resultType="Product">
select * from product
</select>
<delete id="deleteCustomer" parameterType="arraylist">
delete from product where id in
<foreach collection="list" item="id" index="index"
open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<insert id="insertCustomer" parameterType="arraylist" >
insert into product
(productName,brand,supplier,salePrice,costPrice)
values
<foreach collection="list" item="product" separator=",">
(#{product.productName},#{product.brand},#{product.supplier},#{product.salePrice},#{product.costPrice})
</foreach>
</insert>
<!-- <select id="loadAll" parameterType="productQuery" resultType="product">
select * from product
<where>
<if test="productName != null">
and productName like #{productName}
</if>
<if test="brand != null">
and brand like #{brand}
</if>
</where>
</select>-->
<!--查询的字段可以抽取出来-->
<!-- 高级查询方法-->
<select id="loadAll" parameterType="productQuery" resultType="product">
select * from product
<where>
<include refid="whereSql"></include>
</where>
</select>
<!-- 抽取出来-->
<sql id="whereSql">
<if test="productName != null">
and productName like #{productName}
</if>
<if test="brand != null">
and brand like #{brand}
</if>
</sql>
</mapper>
daoimpl方法实现
package com.xmh.dao.impl;
import com.xmh.dao.IProductDao;
import com.xmh.domain.Product;
import com.xmh.query.ProductQuery;
import com.xmh.utils.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import java.io.IOException;
import java.util.List;
public class ProductDaoImpl implements IProductDao{
@Override
public void save(Product product) throws IOException {
/*InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
SqlSession session = factory.openSession();*/
SqlSession session = MybatisUtil.INSTANCE.openSession();
session.insert("com.xmh.dao.impl.ProductDaoImpl.insert",product);
session.commit();
}
@Override
public void update(Product product) throws IOException {
/*InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
SqlSession session = factory.openSession();*/
SqlSession session = MybatisUtil.INSTANCE.openSession();
session.update("com.xmh.dao.impl.ProductDaoImpl.update",product);
session.commit();
}
@Override
public void delete(Long id) throws IOException {
/*InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
SqlSession session = factory.openSession();*/
SqlSession session = MybatisUtil.INSTANCE.openSession();
session.delete("com.xmh.dao.impl.ProductDaoImpl.delete",id);
session.commit();
}
@Override
public Product findOne(Long id) throws IOException {
/*InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
SqlSession session = factory.openSession();*/
SqlSession session = MybatisUtil.INSTANCE.openSession();
return (Product)session.selectOne("com.xmh.dao.impl.ProductDaoImpl.selectOne", id);
}
@Override
public List<Product> findAll() throws IOException {
/*InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
SqlSession session = factory.openSession();*/
SqlSession session = MybatisUtil.INSTANCE.openSession();
List<Product> list = session.selectList("com.xmh.dao.impl.ProductDaoImpl.selectAll");
return list;
}
@Override
public void deleteCustomer(List list) throws IOException {
SqlSession session = MybatisUtil.INSTANCE.openSession();
session.delete("com.xmh.dao.impl.ProductDaoImpl.deleteCustomer",list);
session.commit();
}
@Override
public void insertCustomer(List list) throws IOException {
SqlSession session = MybatisUtil.INSTANCE.openSession();
session.insert("com.xmh.dao.impl.ProductDaoImpl.insertCustomer",list);
session.commit();
}
@Override
public List<Product> loadAll(ProductQuery query) {
//读取配置文件 --获取对象
SqlSession sqlSession = MybatisUtil.INSTANCE.openSession();
//通过对象操作方法--保存数据到数据库
List<Product> products = sqlSession.selectList("com.xmh.dao.impl.ProductDaoImpl.loadAll", query);
return products;
}
}
测试方法中完成CRUD
package com.xmh.dao.impl;
import com.xmh.domain.Product;
import com.xmh.query.ProductQuery;
import org.junit.Test;
import javax.management.Query;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
public class ProductDaoImplTest {
@Test
public void test() throws Exception {
Product product = new Product();
product.setProductName("勇勇");
product.setBrand("老勇");
product.setCostPrice(new BigDecimal(20));
product.setSalePrice(new BigDecimal(150));
try {
new ProductDaoImpl().save(product);
//product通过配置生成主键会自动增加id属性
System.out.println(product);
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void test1() throws Exception {
Product product = new Product();
product.setId(21L);
product.setProductName("勇勇");
product.setBrand("巨勇");
product.setCostPrice(new BigDecimal(20));
product.setSalePrice(new BigDecimal(150));
try {
new ProductDaoImpl().update(product);
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void test2() throws Exception {
try {
new ProductDaoImpl().delete(21L);
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void test3() throws Exception {
try {
System.out.println(new ProductDaoImpl().findOne(20L));
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void test4() throws Exception {
try {
new ProductDaoImpl().findAll().forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void deleteCustomer() throws Exception {
List<Integer> list = Arrays.asList(19, 20);
new ProductDaoImpl().deleteCustomer(list);
}
@Test
public void insertCustomer() throws Exception {
Product p1 = new Product();
Product p2 = new Product();
p1.setProductName("香蕉");
p1.setBrand("中国");
p2.setProductName("苹果");
p2.setBrand("日本");
List<Product> list = Arrays.asList(p1, p2);
new ProductDaoImpl().insertCustomer(list);
}
@Test
public void testLoadAll() throws Exception {
ProductQuery query = new ProductQuery();
query.setProductName("罗技M%");
query.setBrand("%罗%");
new ProductDaoImpl().loadAll(query).forEach(e->
{
System.out.println(e);
});
}
}
重复SqlSessionFactory创建抽取为工具类
- sqlSession 类似EntityManager对象 可以频繁创建
- 单例模式
*/
public enum MybatisUtil {
INSTANCE;
private static SqlSessionFactory sqlSessionFactory;
static {
InputStream in = null;
try {
in = Resources.getResourceAsStream("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
e.printStackTrace();
}
}
public SqlSession openSession(){
return sqlSessionFactory.openSession();
}
}
细节
添加成功返回主键
适用于角色,权限
<insert id="insert" parameterType="com.xmh.domain.Product" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
insert into product
(productName,brand,supplier,salePrice,costPrice)
values(#{productName},#{brand},#{supplier},#{salePrice},#{costPrice})
</insert>
添加日志
log4j
导包
2.配置log4j.properties
#Global logging configuration
log4j.rootLogger=ERROR, stdout
MyBatis logging configuration...
log4j.logger.com.xmh=TRACE
#Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
Mybatis内置别名
https://mybatis.org/mybatis-3/zh/configuration.html#typeAliases