文章目录
mybatis
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
mybatis的使用
非maven项目将 mybatis-x.x.x.jar 文件置于 classpath 中即可。
Maven项目,只需将下面的 dependency 代码置于 pom.xml 文件中即可
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
mybatis的XML 配置文件中包含了对 MyBatis 系统的核心设置,包含获取数据库连接实例的数据(DataSource)和决定事务作用域和控制方式的事务管理器(TransactionManager)。这里先给出一个简单的示例:
<?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>
<!-- 在db.properties文件中定义数据库的连接配置,在下面可以直接使用表达式-->
<properties resource="db.properties"></properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${className}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
db.properties文件中的配置如下
className=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8
username=root
password=123456
使用mybatis操作数据库
我这里使用的是mysql-connector-java的JDBC驱动maven配置如下
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
定义user对象并在数据库中建立相应的表
public class User {
private Integer id;
private String name;
private Integer age;
public User(Integer id, String name, Integer age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
public User( String name, Integer age) {
this.name = name;
this.age = age;
}
public User() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
创建映射文件
在映射文件中写sql语句
文件中的标签和属性的作用
标签
-
insert
– 映射插入语句 -
update
– 映射更新语句 -
delete
– 映射删除语句 -
select
– 映射查询语句属性
-
id
– 唯一的标识符,可以被用来引用这条语句 -
parameterType
– 将要传入的参数的完全限定类名或别名。如parameterType="sz.lz.vo.User"
就是表示传入的是一个User对象 -
resultType
– 返回的期望类型的类的完全限定名或别名。 注意如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身
<?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="sz.lz.vo">
<select id="queryAll" resultType="sz.lz.vo.User" >
select * from t_user
</select>
<insert id="addUser" parameterType="sz.lz.vo.User">
<!--"#{name}"这样的一个参数在JDBC SQL 中会由一个“?”来标识,-->
insert into t_user(name,age,list) value(#{name},#{age})
</insert>
<update id="updataUser" parameterType="sz.lz.vo.User">
update t_user set name=#{name},age=#{age} where id=#{id}
</update>
<delete id="deleteById" parameterType="int">
delete from t_user where id=#{id}
</delete>
<select id="queryById" parameterType="int" resultType="sz.lz.vo.User">
select * from t_user where id =#{id}
</select>
</mapper>
映射文件添加到mybatis的全局配置文件中
<?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>
<!-- jdbc的数据库连接配置写入到 db.properties -->
<properties resource="db.properties"></properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${className}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<!-- 注册映射文件 -->
<mappers>
<mapper resource="sz/lz/vo/userMapper.xml" />
</mappers>
</configuration>
测试查询
@org.junit.Test
public void select() throws IOException {
// 通过Resources加载配置文件
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
//获取SqlSessionFactory对象
SqlSessionFactory se = new SqlSessionFactoryBuilder().build(in);
//通过SqlSessionFactory对象获取SQLSession对象
SqlSession session = se.openSession();
//sz.lz.vo.queryAll是映射文件中 namespace的内容加 id的内容,定位要执行的SQL
List<User> list = session.selectList("sz.lz.vo.queryAll");
for (User user :list) {
System.out.println(user);
}
session.close();
in.close();
}
测试添加
@org.junit.Test
public void add() throws IOException {
// 通过Resources加载配置文件
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
//获取SqlSessionFactory对象
SqlSessionFactory sse = new SqlSessionFactoryBuilder().build(in);
//通过SqlSessionFactory对象获取SQLSession对象
SqlSession session = sse.openSession();
int i = session.insert("sz.lz.vo.addUser", new User("李四",37));
// 需要显示的提交
session.commit();
System.out.println("添加-->"+i);
session.close();
in.close();
}
mybatis接口和类型处理器(typeHandlers)使用方式
typeHandlers称做类型处理器。就是实现Java类型和数据库类型之间转换的。 除了系统提供的类型转换器之外,开发者也可以自定义类型转换
使用mapper接口方式必须注意的几点:
- 映射文件的
namespace
的值必须是接口的全路径名称 比如:sz.lz.dao.IUserDao
- 接口中的方法名在映射文件中必须有一个id值与之对应。
- 映射文件的名称必须和接口的名称一致
定义User类
package sz.lz.vo;
import java.util.List;
public class User {
private Integer id;
private String name;
private Integer age;
private List<String> list;
public User(Integer id, String name, Integer age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
public User(Integer id, String name, Integer age, List<String> list) {
super();
this.id = id;
this.name = name;
this.age = age;
this.setList(list);
}
public User( String name, Integer age, List<String> list) {
this.name = name;
this.age = age;
this.setList(list);
}
public User() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", age=" + age + ", list=" + list+ "]";
}
}
新定义的user类中有一个List属性的集合,mybatis没有提供它的转换器.这就需要我们自定义类型转换了.
定义转换器
继承一个类 org.apache.ibatis.type.BaseTypeHandler
然后重写方法.
注意需要在重写的方法上加上两个注解:
- 在类型处理器的类上(TypeHandler class)增加一个
@MappedTypes
注解来指定与其关联的 Java 类型列表。 - 在类型处理器的类上增加一个
@MappedJdbcTypes
注解来指定与其关联的 JDBC 类型列表。
/**
* 类型处理器
* List类型和String类型的相互转换
* @author Administrator
*
*/
@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(List.class)
public class ListToStringTypeHandler extends BaseTypeHandler<List<String>> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, List<String> parameter, JdbcType jdbcType)
throws SQLException {
if(parameter!=null&¶meter.size()>0) {
StringBuilder sb = new StringBuilder();
//把list中的字符串使用";"分隔开来
for(int a=0 ; a<parameter.size();a++) {
sb.append(parameter.get(a));
if(a!=(parameter.size()-1)) {
sb.append(";");
}
}
String str = sb.toString();
ps.setString(i, str);
}else {
ps.setString(i, null);
}
}
@Override
public List<String> getNullableResult(ResultSet rs, String columnName) throws SQLException {
String str = rs.getString(columnName);
if(str!=null&&str.length()>0) {
//把从数据库中获得的字符串利用";"分隔开来
String[] strs = str.split(";");
List<String> list = Arrays.asList(strs);
return list;
}else {
return null;
}
}
@Override
public List<String> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
// String str = rs.getString(columnIndex);
// String[] strs = str.split(";");
// List<String> list = Arrays.asList(strs);
// return list;
return null;
}
@Override
public List<String> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
// String str = cs.getString(columnIndex);
// String[] strs = str.split(";");
// List<String> list = Arrays.asList(strs);
// return list;
return null;
}
}
定义接口
public interface IUserDao {
public List<User> queryAll();
public int addUser(User user);
public int deleteById(int id);
public int updataUser(User user);
public User queryById(int id);
}
定义映射文件
<?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="sz.lz.dao.IUserDao">
<select id="queryAll" resultType="sz.lz.vo.User" >
select * from t_user
</select>
<insert id="addUser" parameterType="sz.lz.vo.User">
insert into t_user(name,age,list) value(#{name},#{age},#{list})
</insert>
<update id="updataUser" parameterType="sz.lz.vo.User">
update t_user set name=#{name},age=#{age},list=#{list} where id=#{id}
</update>
<delete id="deleteById" parameterType="int">
delete from t_user where id=#{id}
</delete>
<select id="queryById" parameterType="int" resultType="sz.lz.vo.User">
select * from t_user where id =#{id}
</select>
</mapper>
测试方法
public class Test {
public static void main(String[] args) {
//MybatisUtil是一个自定义的工具类getSqlSessionFactory()方法封装了1.通过Resources加载配置文件 2.获取SqlSessionFactory对象
SqlSession session = MybatisUtil.getSqlSessionFactory().openSession();
// 获取的IUserDao的实现 其实就是一个代理类
IUserDao dao = session.getMapper(IUserDao.class);
String [] strs = {"哈哈","呵呵","嘿嘿","嘻嘻"};
User user = new User();
user.setAge(28);
user.setName("小红");
user.setList(Arrays.asList(strs));
//往数据库中插入一条数据
int i = dao.addUser(user);
session.commit();
System.out.println(i);
//查询id为12的数据
// User user = dao.queryById(12);
// System.out.println(user);
}
}
数据插入结果
数据查询结果