框架:半成品,需要我们去补充核心代码才是完整的项目
dao(mybatis - 底层就是JDBC) - service - controller(servlet 接收请求 获取参数 处理请求 响应)
原生的JDBC代码:
1.代码量多,并且重复
2.SQL语句和Java写在一起了,耦合度高
3.自己释放连接
4.如果是执行查询语句,还要将结果集手动转换成集合或对象
Mybatis:
1.使用简单的API直接操作数据库,提高了开发效率
2.SQL语句与代码分离,存放于xml配置文件中,方便维护
3.Mybatis消除了几乎所有的JDBC代码和手工设置参数以及结果集的转换
4.提供XML标签,支持编写动态SQL,代替编写逻辑代码
注意:Mybatis底层还是JDBC代码,相当其他人写好的一个优秀的工具类【功能强大,性能较好】
Mybatis是一个持久层的半ORM框架,底层是JDBC
持久化 = 数据持久化:就是将数据保存在可掉电设备【文档 【txt、xml、Excel等】、数据库、U盘】中
数据库持久化:将对象和数据保存在数据库中,用JDBC,Mybatis等技术
ORM:Object Relational Mapping - 对象关系映射
有了ORM,我们查询数据库中的数据会自动转成java中对象,不需要做对象转换了
新建普通java项目(前面涉及交互一直用动态web项目来着),
入门案例:
1.准备数据(表, 实体类,持久层)
2.导包(数据库驱动包,mybatis相关jar包,日志jar)
3.核心配置文件(一般我们命名为mybatis-config.xml)------ 链接数据库
4.映射文件 xml文件-----(写sql语句的)
5.测试
tips:
1.日志包支持把执行的sql语句打印到控制台上,可以观看
2.web项目可以自动导包,普通java项目需要手动build path
IUserDao - UserDaoImpl
mybatis-config.xml,db.properties
IUserDao.xml,配置到核心配置文件
IUserDao,IUserDao.xml,UserDaoImpl,MybatisTest
IUserDao,IUserDao.xml
<mapper namespace="cn.itsource.dao.IUserDao">
<select id="findOne" resultType="cn.itsource.domain.User">
select * from user where id = #{id}
select>
mapper>
UserDaoImpl
@Override
public User findOne(Integer id) throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
// 参数一:要执行的sql语句 名称空间+id = 唯一的SQL,参数二: sql语句中需要的参数 id
User user = session.selectOne("cn.itsource.dao.IUserDao.findOne", id);
return user;
}
MybatisTest
@Test
public void findOne() throws Exception {
// 获取对象
IUserDao dao = new UserDaoImpl(); // 多态的写法
User user = dao.findOne(2);
System.out.println(user);
}
IUserDao,IUserDao.xml
<delete id="delete">
delete from user where id = #{id}
delete>
UserDaoImpl
@Override
public void delete(Integer id) throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
session.delete("cn.itsource.dao.IUserDao.delete", id);
// 提交事务
session.commit();
}
MybatisTest
@Test
public void delete() throws Exception {
// 获取对象
IUserDao dao = new UserDaoImpl();
dao.delete(6);
}
public class MybatisUtils {
static SqlSessionFactory sqlSessionFactory = null;
static{
try {
// 获取sqlSessionFactory
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 返回一个sqlSession
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
UserMapper,UserMapper.xml,配置到核心配置文件,MapperTest
UserMapper
public interface UserMapper {
User findOne(Integer id) throws IOException;
List<User> findAll() throws IOException;
void add(User user);
void delete(Integer id) throws IOException;
void update(User user);
}
UserMapper.xml
<mapper namespace="cn.itsource.mapper.UserMapper">
<select id="findOne" resultType="cn.itsource.domain.User">
select * from user where id = #{id}
select>
<select id="findAll" resultType="user">
select * from user
select>
<delete id="delete">
delete from user where id = #{id}
delete>
<update id="update">
update user set name = #{name},age = #{age}, sex = #{sex}
where id = #{id}
update>
<insert id="add">
insert into user(name,age,sex) values(#{name},#{age},#{sex})
insert>
mapper>
mybatis-config.xml
<mappers>
<mapper resource="cn/itsource/mapper/UserMapper.xml" />
mappers>
MapperTest
@Test
public void findName() throws Exception {
// 获取sqlSession
SqlSession session = MybatisUtils.getSqlSession();
// 接口new对象么? mapper:代理对象
UserMapper mapper = session.getMapper(UserMapper.class);
// System.out.println(mapper);
// 根据id查询
User user = mapper.findOne(3);
System.out.println(user);
/* // 查询所有
List list = mapper.findAll();
System.out.println(list);
// 添加
mapper.add(new User(null, "杨过", 30, "男"));
// 删除
mapper.delete(4);
// 修改
mapper.update(new User(3, "小龙女", 50, "女"));
// 提交事务
session.commit();*/
}
1.在mybatis的主配置文件中配置
<typeAliases>
<package name="cn.itsource.domain"/>
typeAliases>
2.在mapper映射文件中使用别名
直接类名或类名的首字母小写
有了日志我们可以看到数据的执行过程,还可以帮助我们去解决问题
1.导入jar包
log4j-1.2.17.jar,slf4j-api-1.7.2.jar,slf4j-log4j12-1.7.2.jar
2.在resources下面新建属性文件log4j.properties,内容直接拷贝,修改包名
#5.控制台输出+自定义布局
log4j.rootLogger=DEBUG,my
#指定输出器
log4j.appender.my=org.apache.log4j.ConsoleAppender
#指定布局器(自定义布局)
#指定布局为自定义布局
log4j.appender.my.layout=org.apache.log4j.PatternLayout
#指定在自定义布局的格式,%d -- 表示当前系统时间,%t -- 执行该业务的线程名称,%p -- 日记器的级别,-5 -- 5表示输出字符的个数,符号表示右对齐
#%c -- 表示指定业务所在的类的完全限定名(包名.类名),%m -- 输出额外信息,%n -- 表示换行
log4j.appender.my.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.cn.itsource=debug
#{}:相当于PrepareStatement,会预编译,先编译(未填参数用占位符),再传参数,然后执行,不会出现sql注入问题
${}:相当于Statement,拼接字符串后再编译,会出现sql注入问题