主要内容
框架(Framework)是一个框子——指其约束性,也是一个架子——指其支撑性。是一个基本概念上的结构,用于去解决或者处理复杂的问题。框架这个广泛的定义使用的十分流行,尤其在软件概念。
框架( Framework )是构成一类特定软件可复用设计的一组相互协作的类。框架规定了 你的应用的体系结构。它定义了整体结构,类和对象的分割,各部分的主要责任,类和对象 怎么协作,以及控制流程。框架预定义了这些设计参数,以便于应用设计者或实现者能集中 精力于应用本身的特定细节。
如果将开发完成的软件比作是一套已经装修完毕的新房,那框架就好比是一套已经修建 好的毛坯房。用户直接购买毛坯房,建筑质量和户型合理有保证,还省去了自己建造房屋的 时间,一举多得。
在开发过程是使用框架,同样可以保证减少开发时间、降低开发难度,并且还保证设计质量。好比和世界上最优秀的软件工程师是一个项目的,并且他们完成的还是基础、全局的 工作。想想是不是很嗨的一件事情。
框架还有一个作用是约束。莎士比亚说,“一千个观众眼中有一千个哈姆雷特” 即仁者见 仁,智者见智.说每个人都会对作品有不同的理解,每个人对待任何事物都有自己的看法,一 千个人就有可能有一千种不同的看法 1000 人心中有 1000 个哈姆雷特。同样的技术解决同 样的问题会产生不同流程和风格的解决方案,而采用一种框架其实就是限制用户必须使用其 规定的方案来实现,可以降低程序员之间沟通以及日后维护的成本。
总之,框架是一个半成品,已经对基础的代码进行了封装并提供相应的 API,开发者在 使用框架是直接调用封装好的 API 可以省去很多代码编写,从而提高工作效率和开发速度。
使用框架可以带来的好处:
ORM,Object-Relationl Mapping,对象关系映射,它的作用是在关系型数据库和对 象之间作一个映射处理。
JDBC 的缺点:需要手动的完成面向对象的 Java 语言、面向关系的数据库之间数据的 转换,代码繁琐无技术含量,影响了开发效率。
如图所示,查询是需要手动的将结果集的列数据转换为 Java 对象的属性;而添加操作 时需要手动将 Java 对象的属性转换为数据库表的列字段。
关于面向对象的 Java 语言、面向关系的数据库之间数据的转换必须要做,问题在于这个转换是否可以不由开发者来做?答案是可以的。ORM 框架就是专门来解决这个问题的, 相当于在面向对象语言和关系数据库之间搭建一个桥梁。这样我们在具体的操作数据库的时 候,只要像平时操作对象一样操作它就可以了,ORM 框架会根据映射完成对数据库的操作, 就不需要再去和复杂的 SQL 语句打交道了。
MyBatis 本是 Apache 的一个开源项目 iBatis, 2010 年这个项目由 Apache Software Foundation 迁移到了 Google Code,且改名为 MyBatis 。2013 年 11 月迁移到 GitHub。
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。 MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使 用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java 对象)映射成数据库中的记录。
简单的说:MyBatis 是一个半自动 ORM 框架,其本质是对 JDBC 的封装。使用 MyBatis 重点需要程序员编写 SQL 命令,不需要写一行 JDBC 代码。
与 Hibernate 的比较
Hibernate 是一个全自动的 ORM 框架。因为 Hibernate 创建了 Java 对象和数据库表 之间的完整映射,可以完全以面向对象的思想来操作数据库,程序员不需要手写 SQL 语句, 而 MyBatis 中还需要手写 SQL 语句,所以是半自动化的,工作量要大于 Hibernate。
为什么半自动化的 Mybatis 比自动化的 Hibernate 受欢迎?
MyBatis 需要手写 SQL 语句,所以工作量要大于Hibernate。但是也正是由于自定义 SQL 语句,所以其灵活性、可优化性就超过了 Hibernate。
Hibernate 封装了 SQL 语句,由开发者对对象操作,Hibernate 来生成 SQL 语句。虽 然也可以通过映射配置来控制生成的 SQL 语句,但是对于要生成复杂的 SQL 语句,很难实 现,或者实现后导致性能的丢失。
而 MyBatis 将手写 SQL 语句的工作丢给开发者,可以更加精确的定义 SQL,更加灵活, 也便于优化性能。完成同样功能的两条 SQL 语句的性能可能相差十几倍到几十倍,在高并 发、快响应要求下的互联网系统中,对性能的影响更明显。
MyBatis 对存储过程可提供很好的支持。另外 MyBatis 的开发工作量大不意味着学习 成本大。对于新手,学习 Hibernate 时间成本比 Mybatis 大很多,Mybatis 很快就上手了。
总之,因为 MyBatis 具有封装少、映射多样化、支持存储过程、可以进行 SQL 语句优 化等特点,符合互联网高并发、大数据、高性能、高响应的要求,使它取代 Hibernate 成 为了 Java 互联网中首选的持久框架。而对于对性能要求不高的比如内部管理系统、ERP 等 可以使用 Hibernate。
https://github.com/mybatis/mybatis-3/releases
SqlSessionFactoryBuilder
SqlSessionFactoryBuilder 的作用是使用构建者模式创建 SqlSessionFactory 接口 对象。
SqlSessionFactory
SqlSessionFactory 可以被认为是一个数据库连接池,它的作用是创建 SqlSession 接口对象。
SqlSession
如果说 SqlSessionFactory 相当于数据库连接池,那么 SqlSession 就相当于一个数 据库连接(Connection 对象),你可以在一个事务里面执行多条 SQL,然后通过它的 commit、rollback 方法提交或者回滚事务。
Mapper
映射器。由一个 Java 接口和 XML 文件(或者注解构成),需要给出对应的 SQL 和映 射规则,负责发送 SQL 去执行并返回结果。
https://mybatis.org/mybatis-3/zh/configuration.html
在 Mybatis 中配置文件有两种:
全局配置文件的名称是自定义的,在 JavaProject 项目中需要放到 src 目录下。
全局配置文件的作用是完成一些全局性的配置,如:对 Mybatis 框架的设置、别名设置、 环境设置、指定映射配置文件等相关配置。
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
configuration>
Mybatis 配置文件中的属性定义。properties 标签中允许内部定义属性,也可以是外部的 properties 文件定义属性。无论是内部定义还是外部定义,都可以使用${name}获取值。
配置文件中内部定义
<properties>
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="jdbc.url" value="jdbc:mysql://localhost:3306/bjsxt"/>
<property name="jdbc.username" value="root"/>
<property name="jdbc.password" value="root"/> properties>
配置文件中外部定义
<properties resource="db.properties">properties>
setting 标签的配置是配置 MyBatis 框架运行时的一些行为的,例如缓存、延迟加载、 结果集控制、执行器、分页设置、命名规则等一系列控制性参数,其所有的 setting 配置都 放在父标签 settings 标签中。
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="multipleResultSetsEnabled" value="true"/>
<setting name="useColumnLabel" value="true"/>
<setting name="useGeneratedKeys" value="false"/>
<setting name="autoMappingBehavior" value="PARTIAL"/>
<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
<setting name="defaultExecutorType" value="SIMPLE"/>
<setting name="defaultStatementTimeout" value="25"/>
<setting name="defaultFetchSize" value="100"/>
<setting name="safeRowBoundsEnabled" value="false"/>
<setting name="mapUnderscoreToCamelCase" value="false"/>
<setting name="localCacheScope" value="SESSION"/>
<setting name="jdbcTypeForNull" value="OTHER"/>
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
settings>
类型别名可为 Java 类型设置一个缩写名字。
<typeAliases>
<typeAlias alias="user" type="com.bjsxt.pojo.User" />
typeAliases>
也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean
<typeAliases>
<package name="com.bjsxt.pojo"/>
typeAliases>
下面是一些为常见的 Java 类型内建的类型别名。它们都是不区分大小写的
MyBatis 可以配置多个环境。这可以帮助你 SQL 映射对应多种数据库等。比如说,想为 开发、测试、发布产品配置不同的环境。
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
dataSource>
environment>
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
dataSource>
environment>
environments>
事务处理器。
在 MyBatis 中有两种类型的事务管理器(也就是 type="[JDBC|MANAGED]")
JDBC :这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来 管理事务作用域。
MANAGED :不做事务处理。
指定映射配置文件
使用相对于类路径指定映射配置文件
<mappers>
<mapper resource="com/bjsxt/mapper/UserMapper.xml"/>
mappers>
使用 filter:///协议指定映射配置文件
<mappers>
<mapper url="file:///D:\code\mybatis\src\com\bjsxt\mapper\UserMapper.xml" />
mappers>
指定映射接口
<mappers>
<mapper class="com.bjsxt.mapper.UserMapper"/>
mappers>
通过包名指定映射接口
<mappers>
<package name="com.bjsxt.mapper"/>
mappers>
映射配置文件主要是用来编写 sql 语句的,结果集的映射关系的指定,以及缓存的一些 配置等等。
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bjsxt.mapper.UserMapper">
mapper>
指定查询结果集与对象的映射关系,是最复杂也是最强大的标签。
id:唯一标识。
type:类的完全名, 或者一个类型别名
<resultMap id="userMapper" type="com.bjsxt.pojo.User">
<id property="userid" column="user_id"/>
<result property="username" column="user_name"/>
resultMap>
指定主键中的值,用于标识一个结果映射。
指定非主键中的值,用于标识一个结果映射。
通常用来映射一对一的关系。
通常用来映射一对多的关系。
查询语句。
<select id="selectUser" parameterType="int" resultType="u">
select * from users where userid = #{userid}
select>
添加语句。
<insert id="insertUser" parameterType="com.bjsxt.pojo.User">
insert into users values(default ,#{username},#{usersex})
insert>
更新语句。
<update id="updateUser" parameterType="com.bjsxt.pojo.User">
update users set username=#{username},usersex=#{usersex} where userid =#{userid}
update>
<delete id="deleteUser" parameterType="int">
delete from users where userid = #{userid}
delete>
可以用来定义可重用的 SQL 代码片段。通过标签引入该片段。
<sql id="userColumns">
userid,username,usersex
sql>
<select id="selectUser" parameterType="int" resultType="u">
select <include refid="userColumns"/> from users
select>
CREATE TABLE `users` (
`userid` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(20) DEFAULT NULL,
`usersex` varchar(10) DEFAULT NULL,
PRIMARY KEY (`userid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
在没有联网的情况下,如果让 dtd 约束继续起作用,并且出现标签提示,可以通过引入 本地 dtd 文件来实现。
下 载 dtd : 在 浏 览 器 中 输 入 dtd 的 网 络 地 址 即 可 实 现 下 载 。 比 如 : http://mybatis.org/dtd/mybatis-3-config.dtd
将下载的 dtd 拷贝到本地的一个目录下
Idea 操作路径:File—Settings—Languages & Frameworks
其中 URI 复制 dtd 的网络地址即可。File 选择 dtd 文件在本地的地址。OK!
【注】:在 MyBatis 的核心 jar 包中就提供了 mybatis-3-config.dtd
package com.bjsxt.pojo;
public class Users {
private int userid;
private String username;
private String usersex;
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUsersex() {
return usersex;
}
public void setUsersex(String usersex) {
this.usersex = usersex;
}
}
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/bjsxt
jdbc.username=root
jdbc.password=root
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="db.properties"/>
<settings>
<setting name="logImpl" value="SLF4J"/>
settings>
<typeAliases>
<typeAlias type="com.bjsxt.pojo.Users" alias="u"/>
<package name="com.bjsxt.pojo"/>
typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/bjsxt/mapper/UsersMapper.xml"/>
mappers>
configuration>
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bjsxt.mapper.UserMapper">
mapper>
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bjsxt.mapper.UserMapper">
<select id="selectUsersAll" resultType="com.bjsxt.pojo.Users">
select * from users
select>
mapper>
package com.bjsxt.dao;
import com.bjsxt.pojo.Users;
import java.io.IOException;
import java.util.List;
import java.util.Map;
public interface UsersDao {
List<Users> selectUsersAll()throws IOException;
}
package com.bjsxt.dao.impl;
import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Users;
import com.bjsxt.utils.MybatisUtils;
import org.apache.ibatis.cursor.Cursor;
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 java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class UsersDaoImpl implements UsersDao {
/**
* 查询所有用户
* @return
*/
@Override
public List<Users> selectUsersAll()throws IOException {
//创建SqlSessionFactory对象
InputStream inputStream = Resources.getResourceAsStream("mybatis-cfg.xml");
SqlSessionFactory sqlSessionFacotry = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象
SqlSession sqlSession = sqlSessionFacotry.openSession();
//通过SqlSession对象下的API完成对数据库的操作
List<Users> list = sqlSession.selectList("com.bjsxt.mapper.UserMapper.selectUsersAll");
//关闭SqlSession对象
sqlSession.close();
return list;
}
}
package com.bjsxt.test;
import com.bjsxt.dao.UsersDao;
import com.bjsxt.dao.impl.UsersDaoImpl;
import com.bjsxt.pojo.Users;
import java.io.IOException;
import java.util.List;
public class Test {
public static void main(String[] args)throws IOException {
UsersDao usersDao = new UsersDaoImpl();
List<Users> list = usersDao.selectUsersAll();
for(Users users:list){
System.out.println(users.getUserid()+"\t"+users.getUsername()+"\t"+users.getUsersex());
}
}
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bjsxt.mapper.UserMapper">
<select id="selectUsersAll" resultType="com.bjsxt.pojo.Users">
select * from users
select>
<select id="selectUsersById" parameterType="int" resultType="users">
select * from users where userid = #{suibian}
select>
mapper>
package com.bjsxt.dao;
import com.bjsxt.pojo.Users;
import java.io.IOException;
import java.util.List;
import java.util.Map;
public interface UsersDao {
List<Users> selectUsersAll()throws IOException;
Users selectUsersById(int userid)throws IOException;
}
package com.bjsxt.dao.impl;
import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Users;
import com.bjsxt.utils.MybatisUtils;
import org.apache.ibatis.cursor.Cursor;
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 java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class UsersDaoImpl implements UsersDao {
/**
* 查询所有用户
* @return
*/
@Override
public List<Users> selectUsersAll()throws IOException {
//创建SqlSessionFactory对象
InputStream inputStream = Resources.getResourceAsStream("mybatis-cfg.xml");
SqlSessionFactory sqlSessionFacotry = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象
SqlSession sqlSession = sqlSessionFacotry.openSession();
//通过SqlSession对象下的API完成对数据库的操作
List<Users> list = sqlSession.selectList("com.bjsxt.mapper.UserMapper.selectUsersAll");
//关闭SqlSession对象
sqlSession.close();
return list;
}
/**
* 根据用户ID查询用户
* @param userid
* @return
* @throws IOException
*/
@Override
public Users selectUsersById(int userid) throws IOException {
//创建SqlSessionFactory对象
InputStream inputStream = Resources.getResourceAsStream("mybatis-cfg.xml");
SqlSessionFactory sqlSessionFacotry = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象
SqlSession sqlSession = sqlSessionFacotry.openSession();
Users users = sqlSession.selectOne("com.bjsxt.mapper.UserMapper.selectUsersById",userid);
sqlSession.close();
return users;
}
}
package com.bjsxt.test;
import com.bjsxt.dao.UsersDao;
import com.bjsxt.dao.impl.UsersDaoImpl;
import com.bjsxt.pojo.Users;
import java.io.IOException;
import java.util.List;
public class Test {
public static void main(String[] args)throws IOException {
UsersDao usersDao = new UsersDaoImpl();
/*List list = usersDao.selectUsersAll();
for(Users users:list){
System.out.println(users.getUserid()+"\t"+users.getUsername()+"\t"+users.getUsersex());
}*/
Users users = usersDao.selectUsersById(1);
System.out.println(users.getUserid()+"\t"+users.getUsername()+"\t"+users.getUsersex());
}
}
在映射配置文件中向 SQL 语句中绑定参数的语法结构为#{ }和${ }
。
#{ } 和 ${ }
的区别:
#{ }
解析为一个 JDBC 预编译语句(PreparedStatement)的参数标记符占位符 ?
。使 用该方式可避免 SQL 注入。
${ }
仅仅为一个纯碎的 String 替换,在 Mybatis 的动态 SQL 解析阶段将会进行变量替 换。${ }
在预编译之前已经被变量替换了,这会存在 SQL 注入问题。
ThreadLocal 提供了线程内存储变量的能力,这些变量不同之处在于每一个线程读取的 变量是对应的互相独立的。通过get
和set
方法就可以得到当前线程对应的值。
如果多个 DML 操作属于一个事务,因为 commit()和 rollback()都是由 SqlSession 完成的, 所以必须保证使用一个 SqlSession。但是多个不同的 DML 操作可能在不同类的不同方法中, 每个方法中要单独的获取 SqlSession。比如商城下订单时,其实涉及商品库存变化、订单添 加、订单明细添加、付款、日志添加等多个 DML 操作,分布在不同类中。
如何在多个 DML 操作之间使用同一个 SqlSession 呢,可以使用 ThreadLocal 来存储。保 证一个线程中的操作使用的都是一个 SqlSession。
在 Web 项目中用户的每次请求会启动一个新的线程,比如点击”结算”完成购物车结 算。在 Java 项目中每次启动 main()也会自动开启一个 main 线程
package com.bjsxt.utils;
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 java.io.IOException;
import java.io.InputStream;
public class MybatisUtils {
private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<>();
private static SqlSessionFactory sqlSessionFactory = null;
static{
//创建SqlSessionFactory
InputStream is = null;
try{
is = Resources.getResourceAsStream("mybatis-cfg.xml");
}catch (IOException e){
e.printStackTrace();
}
sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
}
//获取SqlSession
public static SqlSession getSqlSession(){
SqlSession sqlSession = threadLocal.get();
if(sqlSession == null){
sqlSession = sqlSessionFactory.openSession();
threadLocal.set(sqlSession);
}
return sqlSession;
}
//关闭SqlSession
public static void closeSqlSession(){
SqlSession sqlSession = threadLocal.get();
if(sqlSession != null){
sqlSession.close();
threadLocal.set(null);
}
}
}
在 Mybatis 中事务提交方式默认为手动提交,这与 JDBC 是不同的。在 JDBC 中事务默认 提交方式为自动提交。
手动提交事务(默认)
SqlSession sqlSession = sqlSessionFacotry.openSession();
自动提交事务
SqlSession sqlSession = sqlSessionFacotry.openSession(true);
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bjsxt.mapper.UserMapper">
<select id="selectUsersAll" resultType="com.bjsxt.pojo.Users">
select * from users
select>
<select id="selectUsersById" parameterType="int" resultType="users">
select * from users where userid = #{suibian}
select>
<insert id="insertUsers" >
insert into users value(default ,#{username},#{usersex})
insert>
mapper>
package com.bjsxt.dao;
import com.bjsxt.pojo.Users;
import java.io.IOException;
import java.util.List;
import java.util.Map;
public interface UsersDao {
List<Users> selectUsersAll()throws IOException;
Users selectUsersById(int userid)throws IOException;
void insertUsers(Users users);
}
package com.bjsxt.dao.impl;
import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Users;
import com.bjsxt.utils.MybatisUtils;
import org.apache.ibatis.cursor.Cursor;
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 java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class UsersDaoImpl implements UsersDao {
/**
* 查询所有用户
* @return
*/
@Override
public List<Users> selectUsersAll()throws IOException {
//创建SqlSessionFactory对象
InputStream inputStream = Resources.getResourceAsStream("mybatis-cfg.xml");
SqlSessionFactory sqlSessionFacotry = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象
SqlSession sqlSession = sqlSessionFacotry.openSession();
//通过SqlSession对象下的API完成对数据库的操作
List<Users> list = sqlSession.selectList("com.bjsxt.mapper.UserMapper.selectUsersAll");
//关闭SqlSession对象
sqlSession.close();
return list;
}
/**
* 根据用户ID查询用户
* @param userid
* @return
* @throws IOException
*/
@Override
public Users selectUsersById(int userid) throws IOException {
//创建SqlSessionFactory对象
InputStream inputStream = Resources.getResourceAsStream("mybatis-cfg.xml");
SqlSessionFactory sqlSessionFacotry = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象
SqlSession sqlSession = sqlSessionFacotry.openSession();
Users users = sqlSession.selectOne("com.bjsxt.mapper.UserMapper.selectUsersById",userid);
sqlSession.close();
return users;
}
@Override
public void insertUsers(Users users) {
SqlSession sqlSession = MybatisUtils.getSqlSession();
sqlSession.insert("com.bjsxt.mapper.UserMapper.insertUsers", users);
}
}
package com.bjsxt.service;
import com.bjsxt.pojo.Users;
import java.util.Map;
public interface UsersService {
void addUsers(Users users);
}
package com.bjsxt.service.impl;
import com.bjsxt.dao.UsersDao;
import com.bjsxt.dao.impl.UsersDaoImpl;
import com.bjsxt.pojo.Users;
import com.bjsxt.service.UsersService;
import com.bjsxt.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import java.util.Map;
public class UsersServiceImpl implements UsersService {
/**
* 添加用户
* @param users
*/
@Override
public void addUsers(Users users) {
SqlSession sqlSession = MybatisUtils.getSqlSession();
try{
UsersDao usersDao = new UsersDaoImpl();
usersDao.insertUsers(users);
sqlSession.commit();
}catch (Exception e){
e.printStackTrace();
sqlSession.rollback();
}finally{
MybatisUtils.closeSqlSession();
}
}
}
package com.bjsxt.test;
import com.bjsxt.pojo.Users;
import com.bjsxt.service.UsersService;
import com.bjsxt.service.impl.UsersServiceImpl;
public class AddUserTest {
public static void main(String[] args) {
UsersService usersService = new UsersServiceImpl();
Users users = new Users();
users.setUsername("zhangsan");
users.setUsersex("male");
usersService.addUsers(users);
}
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bjsxt.mapper.UserMapper">
<select id="selectUsersAll" resultType="com.bjsxt.pojo.Users">
select * from users
select>
<select id="selectUsersById" parameterType="int" resultType="users">
select * from users where userid = #{suibian}
select>
<insert id="insertUsers" >
insert into users value(default ,#{username},#{usersex})
insert>
<select id="selectUserById2" resultType="com.bjsxt.pojo.Users">
select * from users where userid = ${userid}
select>
mapper>
package com.bjsxt.dao;
import com.bjsxt.pojo.Users;
import java.io.IOException;
import java.util.List;
import java.util.Map;
public interface UsersDao {
List<Users> selectUsersAll()throws IOException;
Users selectUsersById(int userid)throws IOException;
void insertUsers(Users users);
Users selectUsersById2(int userid);
void updateUsersById(Users users);
}
package com.bjsxt.dao.impl;
import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Users;
import com.bjsxt.utils.MybatisUtils;
import org.apache.ibatis.cursor.Cursor;
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 java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class UsersDaoImpl implements UsersDao {
/**
* 查询所有用户
* @return
*/
@Override
public List<Users> selectUsersAll()throws IOException {
//创建SqlSessionFactory对象
InputStream inputStream = Resources.getResourceAsStream("mybatis-cfg.xml");
SqlSessionFactory sqlSessionFacotry = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象
SqlSession sqlSession = sqlSessionFacotry.openSession();
//通过SqlSession对象下的API完成对数据库的操作
List<Users> list = sqlSession.selectList("com.bjsxt.mapper.UserMapper.selectUsersAll");
//关闭SqlSession对象
sqlSession.close();
return list;
}
/**
* 根据用户ID查询用户
* @param userid
* @return
* @throws IOException
*/
@Override
public Users selectUsersById(int userid) throws IOException {
//创建SqlSessionFactory对象
InputStream inputStream = Resources.getResourceAsStream("mybatis-cfg.xml");
SqlSessionFactory sqlSessionFacotry = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象
SqlSession sqlSession = sqlSessionFacotry.openSession();
Users users = sqlSession.selectOne("com.bjsxt.mapper.UserMapper.selectUsersById",userid);
sqlSession.close();
return users;
}
@Override
public void insertUsers(Users users) {
SqlSession sqlSession = MybatisUtils.getSqlSession();
sqlSession.insert("com.bjsxt.mapper.UserMapper.insertUsers", users);
}
//预更新用户的查询
@Override
public Users selectUsersById2(int userid) {
SqlSession sqlSession = MybatisUtils.getSqlSession();
Users users = sqlSession.selectOne("com.bjsxt.mapper.UserMapper.selectUserById2",userid);
return users;
}
//更新用户
@Override
public void updateUsersById(Users users) {
SqlSession sqlSession = MybatisUtils.getSqlSession();
sqlSession.update("com.bjsxt.mapper.UserMapper.updateUsersById", users);
}
}
package com.bjsxt.service;
import com.bjsxt.pojo.Users;
import java.util.Map;
public interface UsersService {
void addUsers(Users users);
Users preUpdateUsers(int userid);
void modifyUsers(Users users);
}
package com.bjsxt.service.impl;
import com.bjsxt.dao.UsersDao;
import com.bjsxt.dao.impl.UsersDaoImpl;
import com.bjsxt.pojo.Users;
import com.bjsxt.service.UsersService;
import com.bjsxt.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import java.util.Map;
public class UsersServiceImpl implements UsersService {
/**
* 添加用户
* @param users
*/
@Override
public void addUsers(Users users) {
SqlSession sqlSession = MybatisUtils.getSqlSession();
try{
UsersDao usersDao = new UsersDaoImpl();
usersDao.insertUsers(users);
sqlSession.commit();
}catch (Exception e){
e.printStackTrace();
sqlSession.rollback();
}finally{
MybatisUtils.closeSqlSession();
}
}
@Override
public Users preUpdateUsers(int userid) {
Users users = null;
try{
SqlSession sqlSession = MybatisUtils.getSqlSession();
UsersDao usersDao = new UsersDaoImpl();
users = usersDao.selectUsersById2(userid);
}catch(Exception e){
e.printStackTrace();
}finally {
MybatisUtils.closeSqlSession();
}
return users;
}
@Override
public void modifyUsers(Users users) {
SqlSession sqlSession = MybatisUtils.getSqlSession();
try{
UsersDao usersDao = new UsersDaoImpl();
usersDao.updateUsersById(users);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
}finally {
MybatisUtils.closeSqlSession();
}
}
}
package com.bjsxt.test;
import com.bjsxt.pojo.Users;
import com.bjsxt.service.UsersService;
import com.bjsxt.service.impl.UsersServiceImpl;
public class UpdateUsersTest {
public static void main(String[] args) {
UsersService usersService = new UsersServiceImpl();
Users users = usersService.preUpdateUsers(2);
System.out.println(users.getUserid());
users.setUsername("OLDLU");
users.setUsersex("MALE");
usersService.modifyUsers(users);
}
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bjsxt.mapper.UserMapper">
<select id="selectUsersAll" resultType="com.bjsxt.pojo.Users">
select * from users
select>
<select id="selectUsersById" parameterType="int" resultType="users">
select * from users where userid = #{suibian}
select>
<insert id="insertUsers" >
insert into users value(default ,#{username},#{usersex})
insert>
<select id="selectUserById2" resultType="com.bjsxt.pojo.Users">
select * from users where userid = ${userid}
select>
<update id="updateUsersById" >
update users set username = #{username},usersex=#{usersex} where userid = #{userid}
update>
<delete id="deleteUsersById">
delete from users where userid = #{userid}
delete>
mapper>
package com.bjsxt.dao;
import com.bjsxt.pojo.Users;
import java.io.IOException;
import java.util.List;
import java.util.Map;
public interface UsersDao {
List<Users> selectUsersAll()throws IOException;
Users selectUsersById(int userid)throws IOException;
void insertUsers(Users users);
Users selectUsersById2(int userid);
void updateUsersById(Users users);
void deleteUsersById(int userid);
}
package com.bjsxt.dao.impl;
import com.bjsxt.dao.UsersDao;
import com.bjsxt.pojo.Users;
import com.bjsxt.utils.MybatisUtils;
import org.apache.ibatis.cursor.Cursor;
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 java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class UsersDaoImpl implements UsersDao {
/**
* 查询所有用户
* @return
*/
@Override
public List<Users> selectUsersAll()throws IOException {
//创建SqlSessionFactory对象
InputStream inputStream = Resources.getResourceAsStream("mybatis-cfg.xml");
SqlSessionFactory sqlSessionFacotry = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象
SqlSession sqlSession = sqlSessionFacotry.openSession();
//通过SqlSession对象下的API完成对数据库的操作
List<Users> list = sqlSession.selectList("com.bjsxt.mapper.UserMapper.selectUsersAll");
//关闭SqlSession对象
sqlSession.close();
return list;
}
/**
* 根据用户ID查询用户
* @param userid
* @return
* @throws IOException
*/
@Override
public Users selectUsersById(int userid) throws IOException {
//创建SqlSessionFactory对象
InputStream inputStream = Resources.getResourceAsStream("mybatis-cfg.xml");
SqlSessionFactory sqlSessionFacotry = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象
SqlSession sqlSession = sqlSessionFacotry.openSession();
Users users = sqlSession.selectOne("com.bjsxt.mapper.UserMapper.selectUsersById",userid);
sqlSession.close();
return users;
}
@Override
public void insertUsers(Users users) {
SqlSession sqlSession = MybatisUtils.getSqlSession();
sqlSession.insert("com.bjsxt.mapper.UserMapper.insertUsers", users);
}
//预更新用户的查询
@Override
public Users selectUsersById2(int userid) {
SqlSession sqlSession = MybatisUtils.getSqlSession();
Users users = sqlSession.selectOne("com.bjsxt.mapper.UserMapper.selectUserById2",userid);
return users;
}
//更新用户
@Override
public void updateUsersById(Users users) {
SqlSession sqlSession = MybatisUtils.getSqlSession();
sqlSession.update("com.bjsxt.mapper.UserMapper.updateUsersById", users);
}
@Override
public void deleteUsersById(int userid) {
SqlSession sqlSession = MybatisUtils.getSqlSession();
final int delete = sqlSession.delete("com.bjsxt.mapper.UserMapper.deleteUsersById", userid);
}
}
package com.bjsxt.service;
import com.bjsxt.pojo.Users;
import java.util.Map;
public interface UsersService {
void addUsers(Users users);
Users preUpdateUsers(int userid);
void modifyUsers(Users users);
void dropUsersById(int userid);
}
package com.bjsxt.service.impl;
import com.bjsxt.dao.UsersDao;
import com.bjsxt.dao.impl.UsersDaoImpl;
import com.bjsxt.pojo.Users;
import com.bjsxt.service.UsersService;
import com.bjsxt.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import java.util.Map;
public class UsersServiceImpl implements UsersService {
/**
* 添加用户
* @param users
*/
@Override
public void addUsers(Users users) {
SqlSession sqlSession = MybatisUtils.getSqlSession();
try{
UsersDao usersDao = new UsersDaoImpl();
usersDao.insertUsers(users);
sqlSession.commit();
}catch (Exception e){
e.printStackTrace();
sqlSession.rollback();
}finally{
MybatisUtils.closeSqlSession();
}
}
@Override
public Users preUpdateUsers(int userid) {
Users users = null;
try{
SqlSession sqlSession = MybatisUtils.getSqlSession();
UsersDao usersDao = new UsersDaoImpl();
users = usersDao.selectUsersById2(userid);
}catch(Exception e){
e.printStackTrace();
}finally {
MybatisUtils.closeSqlSession();
}
return users;
}
@Override
public void modifyUsers(Users users) {
SqlSession sqlSession = MybatisUtils.getSqlSession();
try{
UsersDao usersDao = new UsersDaoImpl();
usersDao.updateUsersById(users);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
}finally {
MybatisUtils.closeSqlSession();
}
}
@Override
public void dropUsersById(int userid) {
SqlSession sqlSession = MybatisUtils.getSqlSession();
try{
UsersDao usersDao = new UsersDaoImpl();
usersDao.deleteUsersById(userid);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
}finally{
MybatisUtils.closeSqlSession();
}
}
}
package com.bjsxt.test;
import com.bjsxt.service.UsersService;
import com.bjsxt.service.impl.UsersServiceImpl;
public class DeleteUsersTest {
public static void main(String[] args) {
UsersService usersService = new UsersServiceImpl();
usersService.dropUsersById(3);
}
}
对于一个应用程序来说日志记录是必不可少的一部分。线上问题追踪,错误排查,基于 日志的业务逻辑统计分析等都离不日志。
日志的管理是系统很重要的一部分,千万不可忽略其重要性。完整的日志将会在系统维 护中起着异常重要的作用。
在 Java 领域存在多种日志框架,目前常用的日志框架包括 Log4j,Log4j2,Commons Logging,Slf4j,Logback,Jul。
Log4j: Log For Java(Java 的日志) 是 Apache 提供的一个开源的 Java 主流的日志框架。
Log4j 定义了 8 个日志级别(除去 OFF 和 ALL,可以说分为 6 个级别),优先级从高到 低依次为:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、 ALL。
在 Log4j 中建议只使用 DEBUG、INFO、WARN、ERROR 四个日志级别。
log4j 配置文件名:log4j.properties
Log4j 配值文件存放位置:项目的 src 的根目录中
log4j.rootLogger = [level],appenderName,appenderName2,...
level 是日志记录的优先级,优先级从低到高分别是 DEBUG,INFO,WARN,ERROR。通过在 这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关,比如在这里定义了 INFO 级别,则应用程序中所有 DEBUG 级别的日志信息将不被打印出来
appenderName 就是指定日志信息输出到哪个地方。可同时指定多个输出目的地。
### appender.console 输出到控制台 ###
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=<%d> %5p (%F:%L) [%t] (%c) - %m%n
log4j.appender.console.Target=System.out
### appender.logfile 输出到日志文件 ###
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.File=SysLog.log
log4j.appender.logfile.MaxFileSize=500KB
log4j.appender.logfile.MaxBackupIndex=7
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=<%d> %p (%F:%L) [%t] %c - %m%n
log4j.appender.logDB=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.logDB.layout=org.apache.log4j.PatternLayout
log4j.appender.logDB.Driver=com.mysql.jdbc.Driver
log4j.appender.logDB.URL=jdbc:mysql://localhost:3306/bjsxt
log4j.appender.logDB.User=root
log4j.appender.logDB.Password=root
log4j.appender.logDB.Sql=INSERT INTO
logs(project_name,create_date,level,category,file_name,thread_name,line,all_ category,message)values('logDemo','%d{yyyy-MM-ddHH:mm:ss}','%p','%c','%F','% t','%L','%l','%m')
log4j.logger.org.apache=FATAL
log4j.logger.org.apache.commons=ERROR
log4j.logger.org.springframework=ERROR
log4j.logger.com.bjsxt=ERROR
Log4J 采用类似 C 语言中的 printf 函数的打印格式格式化日志信息,打印参数如下:
%m
输出代码中指定的消息%p
输出优先级,即 DEBUG,INFO,WARN,ERROR,FATAL%r
输出自应用启动到输出该 log 信息耗费的毫秒数%c
输出所属的类目,通常就是所在类的全名%t
输出产生该日志事件的线程名%n
输出一个回车换行符,Windows 平台为“\r\n”,Unix 平台为“\n”%d
输出日志时间点的日期或时间,默认格式为 ISO8601,也可以在其后指定格式%l
输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数 如: Testlog.main(TestLog.java:10)%F
输出日志消息产生时所在的文件名称%L
输出代码中的行号%x
输出和当前线程相关联的 NDC(嵌套诊断环境),像 java servlets 多客户多线程的应用 中%%
输出一个"%"字符可以在%与模式字符之间加上修饰符来控制其最小宽度、最大宽度、和文本的对齐方式。 如:
%5c
: 输出 category 名称,最小宽度是 5,category<5,默认的情况下右对齐%-5c
:输出 category 名称,最小宽度是 5,category<5,"-"号指定左对齐,会有空格%.5c
:输出 category 名称,最大宽度是 5,category>5,就会将左边多出的字符截掉,<5 不会有空格%20.30c
:category 名称<20 补空格,并且右对齐,>30 字符,就从左边交远销出的字符截掉添加 jar 包:log4j.jar
添加配置文件:log4j.properties
通过 Log4j 的 API 完成日志
import org.apache.log4j.Logger;
public class LogDemo {
private final static Logger logger = Logger.getLogger(LogDemo.class);
}
commons-logging 是 Apache 的 Commons 项目中提供的一个高层的日志框架,是门面模 式的典型应用。commons-logging 本身没有实现真正的日志能力。它可以挂接不同的日志系 统,默认情况下,Commons Loggin 自动搜索并使用 Log4j,如果没有找到 Log4j,再使用JDK。
Logging。
log4j.jar
commons-loggin.jar
项目中常用使用
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class LogDemo {
private static final Log logger = LogFactory.getLog(LogDemo.class);
}
SLF4J 的全称是 Simple Logging Facade for Java,即简单日志门面应用。SLF4J 并不是具体 的日志框架,而是作为一个简单门面服务于各类日志框架,如 java.util.logging, logback 和 log4j。
slf4j-api.jar
slf4j-log4j.jar
log4j.jar
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LogDemo {
private static final Logger logger = LoggerFactory.getLogger(LogDemo.class);
}
Mybatis 的内置日志工厂(LogFactory)提供日志处理功能,内置日志工厂将日志交 给以下其中一种工具作代理:
指定 SLF4J 作为日志处理器
<settings>
<setting name="logImpl" value="SLF4J"/>
settings>
Mybatis 中的别名配置它只和 XML 配置有关, 只用来减少类完全限定名的多余部分。注 意:别名都是大小写不敏感的。
在配置文件中为类的完整路径定义别名,可以采用两种方式
使用 typeAlias 指定单个类的别名,在全局配置文件中配置,【注意】:直接放到setting标签之后
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="db.properties"/>
<settings>
<setting name="logImpl" value="SLF4J"/>
settings>
<typeAliases>
<typeAlias type="com.bjsxt.pojo.Users" alias="u"/>
<package name="com.bjsxt.pojo"/>
typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/bjsxt/mapper/UsersMapper.xml"/>
mappers>
configuration>
<select id="selectUsersById" parameterType="int" resultType="u">
select * from users where userid = #{suibian}
select>
使用 package 指定某个包下所有类的默认别名
<typeAliases>
<package name="com.bjsxt.pojo"/>
typeAliases>
引入别名后的映射文件