对于数据库的连接,在java中简单的就是直接使用JDBC来控制数据库.传统的jdbc方式按照以下几步来操作数据库.
1.加载驱动 2. 创建并获取连接 3. 创建jdbc statement对象 4.设置sql语句 5.设置sql语句参数
6.执行sql并返回resultset结果 7.取出结果并释放连接
传统的方法存在以下几点问题:
1. 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
2. Sql语句在代码中硬编码,造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
3. 使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。
4. 对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便。
那么mybatis等框架的出现就是用来解决这些问题,解决方案就是重新对jdbc进行封装.
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis,实质上Mybatis对ibatis进行一些改进。
MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
1. SqlMapConfig.xml:mybatis的全局配置文件,配置了mybatis的运行环境等信息。
mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。
2. SqlSessionFactry:会话工厂,用于创建会话
3. SqlSession:会话,主要来进行数据库操作
4. Executor:mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。
5. Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。
6. Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
7. Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。
mybaits的代码由github.com管理,地址:https://github.com/mybatis/mybatis-3/releases
核心文件mybatis3.3.1.jar
首先导入mysql的包,mybatis的包,log4j的包
在代码中写上model类
public class User {
private int id;
private String username;
private String password;
private String nickname;
private int status;
//省略get和set方法
@Override
public String toString() {
return "id:"+id+"username:"+username+"password:"+password+"nickname:"+nickname;
}
}
使用log4j可以在调试mybatis的过程中省去很多麻烦,还可以直观的看到mybatis的sql语句.
首先把log4j的jar包导入到项目中,然后建立log4j.properties文件,按照官方文档写入配置
# Global logging configuration
#在开发环境中要设置为DEBUG,不然不会打印出信息
log4j.rootLogger=DEBUG, stdout
# 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就会在控制台打出相应的日志了.
SqlMapConfig.xml配置很简单,从官方文档直接拷贝下来就可以了,具体在里面都有介绍
<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/shopdemo?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="7946521" />
dataSource>
environment>
environments>
<mappers>
<mapper resource="mapper/User.xml"/>
mappers>
configuration>
根据mybatis整体流程,配置完SqlMapConfig.xml之后是创建相应的model类的映射.这里我们为User创建User.xml文件,并写上sql语句
<mapper namespace="test">
<select id="findUserById" parameterType="int" resultType="com.aust.model.User">
SELECT * FROM user WHERE id=#{id}
select>
mapper>
接下来在SqlMapConfig.xml中配置mapper映射,再其里面加入下面配置
<mappers>
<mapper resource="mapper/User.xml"/>
mappers>
然后写junit测试
//测试取出单个
@Test
public void findUserTest(){
//用于加载mybatis配置文件的输入流
InputStream is = null;
try {
is = Resources.getResourceAsStream("SqlMapperConfig.xml");
} catch (IOException e) {
System.out.println("加载mybatis配置文件出错");
e.printStackTrace();
}
//获取会话工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//获取会话
SqlSession session = factory.openSession();
//执行查询单条记录,返回的类型就是resultType
//第一个参数命名规则为: 命名空间+Statement id
User u = session.selectOne("test.findUserById",1);
//查询完要释放会话
session.close();
System.out.println(u.toString());
}
和上面一样的操作,先写sql语句
<select id="findUserByName" parameterType="java.lang.String" resultType="com.aust.model.User">
SELECT * from user WHERE nickname LIKE '%美元符号{value}%'
select>
这里和上面区别大的是使用了${}来配置,不过本质都是ognl来获取的
写junit测试类
//测试取出多个
@Test
public void findUserByNameTest(){
//用于加载mybatis配置文件的输入流
InputStream is = null;
try {
is = Resources.getResourceAsStream("SqlMapperConfig.xml");
} catch (IOException e) {
System.out.println("加载mybatis配置文件出错");
e.printStackTrace();
}
//获取会话工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//获取会话
SqlSession session = factory.openSession();
//查询多条数据返回值为list集合,list里面的类型是resultType配置的类型
List users = session.selectList("test.findUserByName","张");
session.close();
System.out.println(users);
}
自增主键的返回,可以使用mysql的SELECT last_insert_id()函数,不过该sql要在insert语句之后才能执行
<insert id="insertUser" parameterType="com.aust.model.User">
<selectKey keyProperty="id" resultType="java.lang.Integer" order="AFTER" >
SELECT last_insert_id()
selectKey>
INSERT INTO user(username,password,nickname,status) VALUE (#{username},#{password},#{nickname},#{status})
insert>
junit测试
//测试插入数据
@Test
public void insertUserTest(){
//用于加载mybatis配置文件的输入流
InputStream is = null;
try {
is = Resources.getResourceAsStream("SqlMapperConfig.xml");
} catch (IOException e) {
System.out.println("加载mybatis配置文件出错");
e.printStackTrace();
}
//获取会话工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//获取会话
SqlSession session = factory.openSession();
User u = new User();
u.setUsername("niuli");
u.setPassword("123456");
u.setNickname("牛李");
u.setStatus(2);
//返回的是受影响的行数
int a = session.insert("test.insertUser",u);
System.out.println(a);
//提交事务
session.commit();
session.close();
//获取主键
System.out.println("u id"+u.getId());
}
非自增主键和自增主键差不多,只是获取的函数和方式不同
需要增加通过select uuid()得到uuid值
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
"java.lang.String" order="BEFORE"
keyProperty="id">
select uuid()
insert into user(id,username,birthday,sex,address)
values(#{id},#{username},#{birthday},#{sex},#{address})
insert>
注意这里使用的order是“BEFORE”
更新和删除操作差不多,就一起写了
<delete id="deleteUser" parameterType="int">
DELETE FROM user WHERE id =#{id}
delete>
<update id="updateUser" parameterType="com.aust.model.User">
UPDATE user SET username=#{username},password=#{password},nickname=#{nickname} WHERE id = #{id}
update>
junit测试
//测试删除用户
@Test
public void deleteUserTest(){
//用于加载mybatis配置文件的输入流
InputStream is = null;
try {
is = Resources.getResourceAsStream("SqlMapperConfig.xml");
} catch (IOException e) {
System.out.println("加载mybatis配置文件出错");
e.printStackTrace();
}
//获取会话工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//获取会话
SqlSession session = factory.openSession();
//返回的是受影响的行数
int a = session.delete("test.deleteUser",10);
System.out.println(a);
//提交事务
session.commit();
session.close();
}
//测试更新用户
@Test
public void updateUserTest(){
//用于加载mybatis配置文件的输入流
InputStream is = null;
try {
is = Resources.getResourceAsStream("SqlMapperConfig.xml");
} catch (IOException e) {
System.out.println("加载mybatis配置文件出错");
e.printStackTrace();
}
//获取会话工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//获取会话
SqlSession session = factory.openSession();
User u = new User();
u.setId(1);
u.setUsername("niuli");
u.setPassword("123456");
u.setNickname("牛李");
u.setStatus(2);
//返回的是受影响的行数
int a = session.update("test.updateUser",u);
System.out.println(a);
//提交事务
session.commit();
session.close();
//获取主键
}
项目示例:
SSM框架整合: https://github.com/nl101531/JavaWEB
自己做的一个项目: https://github.com/nl101531/AUSTOJ