mybatis是一款orm框架,主要用来操作数据库。
jdbc
最原生操作数据库,它特点:执行效率高,但是开发效率低。
jdbc自己手动写sq|语句,所以性能高。
jdbc自己手动写sq|语句,所以性能高。
jpa
jpa:它是对jdbc的封装它特点:开发效率高, 执行效率低。
开发效率高:直接调用api即可。 就能完成对应的crud。
执行效率低:因为sq|语句它是自动生成的, 我们不能很好控制。
mybatis
mbatis特点:开发效率要比jdc高, 执行效率要比jpa高。
mybatis是一个orm框架, 它消除了重复代码,
mybatis是自己手动写sq|语句。
概念
ORM:对象关系映射(Object Relational Mapping,简称ORM),是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。
ORM框架映射方式
常用的有两种:
Sql操作方式(对jdbc进行封装):把SQL配置到配置文件中,通过不同SQL中完成对象实体和数据库关系相互转换的操作。(mybatis的实现方式)
完整映射:直接映射的是对象实体和数据库关系映射。操作数据库关系,不用写SQL有框架自己生成。(JPA、Hibenate实现方式)
映射的好处-原理
1、以一定的映射方式,把实体模型和数据库关系的映射
2、ORM框架启动时加载这些映射和数据库配置文件
3、ORM通过对最原生jdbc的封装提供更加便利的操作API
4、Dao通过ORM提供的便捷API以对象的方式操作数据库关系。
导包:
asm-3.3.1.jar
cglib-2.2.2.jar
commons-logging-1.1.1.jar
javassist-3.17.1-GA.jar
log4j-1.2.17.jar
mybatis-3.2.1.jar
mysql-connector-java-5.1.26-bin.jar
slf4j-api-1.7.2.jar
slf4j-log4j12-1.7.2.jar
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC">transactionManager>
<dataSource type="POOLED">
<property name="username" value="${username}"/>
<property name="password" value="${password}">property>
<property name="driver" value="${driver}">property>
<property name="url" value="${url}">property>
dataSource>
environment>
environments>
username=root
password=123456
driver=com.mysql.jdbc.Driver
url=jdbc:mysql:///mybatis
### 设置###
### 配置一个全局的###
log4j.rootLogger = ERROR,console
### 配置一个局部的###
log4j.logger.com.yyk=trace
### 输出信息到控制抬 ###
###打印的日志规则 日志信息打印在控制台里面###
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
###打印日志是有格式###
log4j.appender.console.layout = org.apache.log4j.PatternLayout
###打印日志的详细格式###
log4j.appender.console.layout.ConversionPattern = %d %p [%c] - %m%n
public interface IProductDao {
void save(Product product);
void delete(Long id);
void update(Product product);
Product findone(Long id);
List<Product> findAll() throws IOException;
}
private Long id;
private String productName;
private Long dir_id;
private Double salePrice;
private String supplier;
private String brand;
private Double cutoff;
private Double costPrice;
步骤:
public class ProductDaoImpl implements IProductDao {
@Override
public void save(Product product) {
SqlSession sqlSession = null;
try {
sqlSession = MybatisUtil.openSession();
String statement = "com.yyk.mybatis._01hello.dao.IProductDao.save";
sqlSession.insert(statement,product);
//只有提交事物后才能进行数据库的操作
//数据库的引擎为InnoDB
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
}finally {
if(sqlSession!=null){
sqlSession.close();
}
}
}
@Override
public void delete(Long id) {
SqlSession sqlSession = null;
try {
sqlSession = MybatisUtil.openSession();
String statement = "com.yyk.mybatis._01hello.dao.IProductDao.delete";
sqlSession.delete(statement,id);
//只有提交事物后才能进行数据库的操作
//数据库的引擎为InnoDB
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
}finally {
if(sqlSession!=null){
sqlSession.close();
}
}
}
@Override
public void update(Product product) {
SqlSession sqlSession = null;
try {
sqlSession = MybatisUtil.openSession();
String statement = "com.yyk.mybatis._01hello.dao.IProductDao.update";
sqlSession.update(statement,product);
//只有提交事物后才能进行数据库的操作
//数据库的引擎为InnoDB
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
}finally {
if(sqlSession!=null){
sqlSession.close();
}
}
}
@Override
public Product findone(Long id) {
SqlSession sqlSession = null;
try {
sqlSession = MybatisUtil.openSession();
String statement = "com.yyk.mybatis._01hello.dao.IProductDao.findone";
Product product = sqlSession.selectOne(statement, id);
return product;
} catch (Exception e) {
e.printStackTrace();
}finally {
if(sqlSession!=null){
sqlSession.close();
}
}
return null;
}
@Override
public List<Product> findAll() throws IOException {
//将session变为io流
InputStream inputStream = Resources.getResourceAsStream("mybaties-config.xml");
//获取SqlSessionFactoryBuilder对象就相当于jpa的EntityManagerFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession 就相当于jpa的EntityManager
SqlSession session = factory.openSession();
//statement 定位mybatis我要去查询哪条sql语句(namespace+id)
String statement = "com.yyk.mybatis._01hello.dao.IProductDao.findAll";
//查询
List<Product> list = session.selectList(statement);
return list;
}
}
<mapper namespace="com.yyk.mybatis._01hello.dao.IProductDao">
<resultMap id="productResultMap" type="Product">
<id column="id" property="sid">id>
<result column="dir_id" property="dirId">result>
resultMap>
<select id="findAll" resultType="Product">
SELECT * FROM product
select>
<select id="findone" parameterType="long" resultType="Product">
SELECT * FROM product WHERE id=#{id}
select>
<insert id="save" parameterType="Product" useGeneratedKeys="true"
keyColumn="id" keyProperty="id">
INSERT INTO product(productName, dir_id, salePrice, supplier, brand, cutoff, costPrice)
VALUES (#{productName},#{dir_id},#{salePrice},#{supplier},#{brand},#{cutoff},#{costPrice})
insert>
<delete id="delete" parameterType="Product">
DELETE FROM product WHERE id=#{id}
delete>
<update id="update" parameterType="Product">
UPDATE product SET productName=#{productName},dir_id=#{dir_id},salePrice=#{salePrice},supplier=#{supplier}
,brand=#{brand},costPrice=#{cutoff},costPrice=#{costPrice} WHERE id=#{id}
update>
mapper>
public class ProductDaoImplTest {
private ProductDaoImpl productDao = new ProductDaoImpl();
@org.junit.Test
public void save() {
Product product = new Product();
product.setBrand("七只狼");
product.setCostPrice(20.22);
product.setCutoff(0.34);
product.setDir_id(20L);
product.setProductName("狼七只");
product.setSupplier("狼友");
productDao.save(product);
System.out.println(product);
}
@org.junit.Test
public void delete() {
productDao.delete(21L);
}
@org.junit.Test
public void update() {
Product product = productDao.findone(22L);
product.setProductName("安踏");
productDao.update(product);
}
@org.junit.Test
public void findone() {
Product product = productDao.findone(1L);
System.out.println(product);
}
@org.junit.Test
public void findAll() throws IOException {
List<Product> list = productDao.findAll();
list.forEach(e-> System.out.println(e));
}
}
public class MybatisUtil {
public static SqlSessionFactory sqlSessionFactory;
static {
//将session变为io流
try {
InputStream inputStream = Resources.getResourceAsStream("mybaties-config.xml");
//获取SqlSessionFactoryBuilder对象就相当于jpa的EntityManagerFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
System.out.println("解析xml失败");
}
}
public static SqlSession openSession()throws Exception{
//获取SqlSession 就相当于jpa的EntityManager
if(sqlSessionFactory==null){
throw new Exception("解析xml异常");
}
return sqlSessionFactory.openSession();
}
}
private Long id;
private String name;
private Integer age;
private Boolean sex;
void save(Employee employee);
void delete(Long id);
void update(Employee employee);
Employee findOne(Long id);
List<Employee> findAll();
<?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">
<!--映射命名空间,写dao接口的全限定名-->
<!--如果你使用mybatis的映射器,你这个namespace必须是接口对应的全限定名-->
<mapper namespace="com.yyk.mybatis._02mapper.mapper.EmployeeMapper">
<!--
mybatis注意事项:
在mybatis中parameterType是可以缺省的
在mybatis中你做crud的时候,可以任意使用标签,但是最好不要这么做,什么操作就对应什么标签
只要用到查询sql,你要封装对象,必须返回resultType或者resultMap
-->
<!--useGeneratedKeys是否返回主键的id-->
<!-- keyColumn列-->
<!--keyProperty该列的键-->
<insert id="save" parameterType="Employee" useGeneratedKeys="true"
keyColumn="id" keyProperty="id">
INSERT INTO t_employee(name,age,sex)
VALUES (#{name},#{age},#{sex})
</insert>
<!--
抽取公共sql语句
能抽sql语句哪些部分呢?
1.where条件
2.sql查询的列
在写高级查询的时候有公共的部门提取出来
两种写法,标准的就是加上concat 另外一种直接写后面
-->
<sql id="whereSql">
<where>
<if test="name!=null and name!=''">
AND name LIKE CONCAT("%",#{name},"%")
</if>
<if test="sex!=null">
AND sex=#{sex}
</if>
<if test="minAge!=null">
AND age>=#{minAge}
</if>
<if test="maxAge!=null">
<!--这里也是两种写法,用CDATA或者使用lt都可以-->
<![CDATA[AND age<=#{maxAge}]]>
</if>
</where>
</sql>
<!--如果查询都是这些字段,那么字段也可以提取出来-->
<sql id="columnSql">
id,name,age,sex
</sql>
<delete id="delete" parameterType="Employee" >
DELETE FROM t_employee WHERE id=#{id}
</delete>
<update id="update" parameterType="Employee" >
UPDATE t_employee SET name=#{name},age=#{age},sex=#{sex} WHERE id=#{id}
</update>
<select id="findOne" parameterType="long" resultType="Employee">
SELECT * FROM t_employee WHERE id=#{id}
</select>
<!--模糊查询-->
<select id="selectByQuery" parameterType="EmployeeQuery" resultType="Employee">
SELECT <include refid="columnSql"/> FROM t_employee
<include refid="whereSql"></include>
</select>
<!--根据查出的条件显示总条数-->
<select id="selectCountByQuery" parameterType="EmployeeQuery" resultType="long">
SELECT COUNT(*) FROM t_employee
<include refid="whereSql"></include>
</select>
<!--批量删除要么用array 要么就是list-->
<delete id="batchDelete" parameterType="long[]">
DELETE FROM t_employee WHERE id in
<!--
open="" 开始位置
item="x" 循环迭代给每个元素取的别名
separator="," 循环每次以指定的字符进行分割
-->
<foreach collection="array" open="(" item="x" separator="," close=")">
#{x}
</foreach>
</delete>
<delete id="batchDelete2" parameterType="list">
DELETE FROM t_employee WHERE id in
<foreach collection="list" open="(" item="x" separator="," close=")">
#{x.id}
</foreach>
</delete>
<!--批量增加-->
<insert id="batchSave" parameterType="list">
INSERT INTO t_employee(name,age,sex) VALUES
<foreach collection="list" item="x" separator=",">
(#{x.name},#{x.age},#{x.sex})
</foreach>
</insert>
</mapper>
@Test
public void save() throws Exception {
SqlSession sqlSession = MybatisUtil.openSession();
//获取映射器
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
for(int i=1;i<=20;i++){
Employee employee = new Employee();
employee.setName("大嘴"+i);
employee.setAge(20);
employee.setSex(i%2==0?true:false);
employeeMapper.save(employee);
}
sqlSession.commit();
}
/**
*
根据列表查询条件
*/
List<Employee> selectByQuery(EmployeeQuery query);
/**
* 查询总的条数
*/
Long selectCountByQuery(EmployeeQuery query);
/**
* 批量删除
*/
void batchDelete(Long[] ids);
void batchDelete2(List<Employee> list);
/**
* 批量添加
*/
void batchSave(List<Employee> list);
private String name;
private Boolean sex;
private Integer minAge;
private Integer maxAge;
@Test
public void testQuery() throws Exception {
SqlSession sqlSession = MybatisUtil.openSession();
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
EmployeeQuery employeeQuery = new EmployeeQuery();
employeeQuery.setName("2");
List<Employee> list = employeeMapper.selectByQuery(employeeQuery);
list.forEach(e-> System.out.println(e));
Long count = employeeMapper.selectCountByQuery(employeeQuery);
System.out.println(count);
}
@Test
public void batchDelete1() throws Exception {
SqlSession sqlSession = MybatisUtil.openSession();
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
//根据数组删除
Long[] arr = {18L,19L};
employeeMapper.batchDelete(arr);
sqlSession.commit();
}
@Test
public void batchDelete2() throws Exception {
SqlSession sqlSession = MybatisUtil.openSession();
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
//根据数组删除
List<Employee> list = new ArrayList<>();
Employee employee1 = new Employee();
employee1.setId(16L);
Employee employee2 = new Employee();
employee2.setId(17L);
list.add(employee1);
list.add(employee2);
employeeMapper.batchDelete2(list);
sqlSession.commit();
}
@Test
public void batchSave() throws Exception {
SqlSession sqlSession = MybatisUtil.openSession();
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
//批量插入
List<Employee> list = new ArrayList<>();
Employee employee1 = new Employee();
employee1.setName("大傻子");
employee1.setAge(18);
employee1.setSex(true);
Employee employee2 = new Employee();
employee2.setName("笨蛋");
employee2.setAge(33);
employee2.setSex(false);
list.add(employee1);
list.add(employee2);
employeeMapper.batchSave(list);
sqlSession.commit();
}