解决方法:使用配置文件
解决方法:使用数据库连接池技术可解决
映射:数据库的列与对象的属性进行一一对应的关联,这就是mybatis的作用-ORM
是一个持久层框架,是Apache的的顶级项目,能够让程序员将精力放在SQL上,通过映射的方式,灵活的生成(半自动式)满足需求的SQL语句
可以将输入的参数进行自动的输入映射,将查询的结果集灵活的映射为java对象(输出映射)
SqlMapConfig.xml(mybatis的全局配置文件),配置数据源.事务等mybaits运行环境
配置映射:mapper.xml (重点)
根据用户的id(主键)查询用户信息
根据用户名模糊查询用户信息
添加用户
删除用户
更新用户
下载mybatis的jar包,下载位置: https://github.com/mybatis/mybatis-3/releases
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# MyBatis logging configuration
log4j.logger.org.mybatis.example.BlogMapper=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
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>
<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/mybatis?useUnicode=true&characterEncoding=UTF8" />
<property name="username" value="root" />
<property name="password" value="" />
dataSource>
environment>
environments>
<mappers>
<mapper resource="sqlmap/UserMapper.xml" />
mappers>
configuration>
pojo其实就是简单的Java对象,实际就是普通JavaBeans
package po;
public class User {
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 String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
private int id;
private String name;
private String age;
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
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="test">
<select id="findUserById" parameterType="int" resultType="po.User">
select * from user where id=#{id}
select>
mapper>
package mybatis;
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 org.junit.Test;
import po.User;
public class MybatisTest {
@Test
public void myTest() throws IOException {
//mybatis的配置文件
String resource = "SqlMapConfig.xml";
InputStream resourceAsStream = Resources.getResourceAsStream(resource);
//创建会化工厂,传入mybatis的配置文件信息
SqlSessionFactory SqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//通过工厂得到SqlSession
SqlSession openSession = SqlSessionFactory.openSession();
//通过SqlSession操作数据库
User selectOne = openSession.selectOne("test.findUserById",1);
//2050877487
//Builder/Factory设计模式
System.out.println(selectOne.toString());
//关闭会话
openSession.close();
}
}
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="test">
<select id="findUserById" parameterType="int" resultType="mybatis.User">
select * from user where id=#{value}
select>
<select id="findUserByName" parameterType="java.lang.String" resultType="mybatis.User">
select * from user where name like '%${value}%'
select>
mapper>
@Test
//根据name模糊查询用户信息
public void myTestName() throws IOException {
//加载mybatis的全局配置文件
String resource = "SqlMapConfig.xml";
InputStream resourceAsStream = Resources.getResourceAsStream(resource);
//创建会化工厂,传入mybatis的配置文件信息
SqlSessionFactory SqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//通过工厂得到SqlSession
SqlSession openSession = SqlSessionFactory.openSession();
//通过SqlSession操作数据库
//参数1为 命名空间.statemen的id
//参数2为 指定与映射文件中所匹配的映射文件的parameterType的参数,此处指向id
//由于是模糊查询,可能有一条记录,也可能多条,所以使用selectList,查询存储到list集合中
List
System.out.println(selectList.toString());
System.out.println(selectList.get(0).getName());
//关闭会话
openSession.close();
}
使用#{}和${}:
#{}:占位符,类似于?
${}:连接符,拼接SQL语句,可能引起SQL注入
使用selectOne()和selectList():
selectOne():查询一条,有多条的时候就不能使用,会报错
selectList():查询多条,也能实现selectOne的功能
编写接口,对应需要的操作数据库的方法
实现接口,对接口中的方法进行具体实现
测试
总结原始dao开发的问题
1 dao接口中存在大量的模板方法,尝试将这些重复的代码提取出来,减轻人员的工作量
2 调用 SQLSession方法时将statement硬编码
3 调用SQLSession方法时传入变量,由SQLSession方法使用泛型,即使传入变量类型错误,在编译阶段也不会报错,不呢及时发现错误,所以需要使用mapper代理的方式
1 List
2 即使mapper接口只有一个参数,也可以使用bean进行数据封装,对数据进行传入
properties(属性)
properties特性:
将数据库的配置信息提取出来,组成一个单独的配置文件db.properties
只要在sqlMapConfig.xml中加载db.properties的属性,就不用硬编码了
虽然在db.properties中配置也算是硬编码,但是,以后若是使用集群,数据库配置变得多了的时候,使用db.properties就能够方便的读取数据,进行维护升级,方便对参数进行统一管理
注意:mybatis会按照顺序加载属性
因此,通过parameterType传递的参数是
最好将properties中定义的属性名称定义复杂一些,防止和parameterType重名,造成参数的覆盖,否则会读取到properties中的属性值,因为parameterType中没有对应的名称,就会读取properties中的属性`
建议
不要在properties元素标签体内定义任何属性,只将属性定义在properties文件中
在properties文件中定义的属性名称要有一定的特殊性,如:xxx.xx=
settings(全局配置参数)
mybatis框架在运行时期可以调整一些运行参数
比如:开启二级缓存
typeAliasea(类型别名)[重点]
需求:
在mapper.xml中,定义很多的statement,statement需要parameterType指定输入参数类型,需要resultType指定输出结果映射类型
如果在指定类型时输入类型全路径,不方便开发,可以针对parameterType指定输入参数类型和resultType指定输出结果映射类型定义一些别名,在mapper.xml中通过别名定义,方便开发
typeHandlers(类型处理器)
mybatis通过typeHandlers完成jdbc和java类型的转换
通常情况下mybatis提供的类型处理器满足日常需要,不需要自定义
objectFactory(对象工厂)
整合之后一般不用
plugins(插件)
整合之后一般不用
environments(环境集合属性对象)
整合之后一般不用
environment(环境子属性对象)
整合之后一般不用
transactionManager(事务管理)
整合之后一般不用
dataSource(数据源)
整合之后一般不用
mappers(映射器)
mapper映射配置:
单个加载
mapper接口加载
定义pojo包装类
pojo类似于java bean,只是为了区分于web的java bean,所使用的不同的别名,本质还是javabean,只是用于mybatis进行参数的注入和输出参数,对其进行扩展可以直接创建子类,拓展类的字段包括子类,还可以自定义添加其他字段,并实现getsetf方法.
实现
resultType
使用resultType进行输出映射,只有查询出来的列名和pojo属性名称一致的时候,该列才可以查询成功,一般sql定义别名就会出现
如果查询出来的列名和pojo中的属性完全不一致,不会创建pojo对象
如果查询出的列名和pojo中的属性有一个一致,就会创建pojo对象
不管是输出的pojo单个对象还是一个列表(list中包括pojo),在mapper.xml中的resultType指定的类型是一样的,在mapper.java指定的方法返回值类型不一样:
resultMap
如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和属性名之间进行一个映射
定义resultMap
使用resultMap作为返回输出映射对象
什么是动态SQL
mybatis核心是对SQL语句进行灵活的操作,通过表达式进行判断,对SQL进行灵活的拼装,组接,如果某些条件不成立,就不会添加进这一条SQL语句
if判断
sql片段
定义SQL片段
引用SQL片段
foreach
向SQL传递数组或者list,使用foreach进行查询
例如:使用foreach解析传入的参数
select * from user where id=1 or id=10
select * from user where id in(1,10)
在list