第一次写博客好激动,终于鼓足勇气迈出了第一步,有瑕疵的地方望大家批评指正。
下面开始正文
在SSM框架下用generate生成器会生成很多类似的方法。比如
public interface UsersDao {
int deleteByPrimaryKey(Integer userId);
int insert(Users users);
int insertSelective(Users users);
Users selectByPrimaryKey(Integer userId);
int updateByPrimaryKeySelective(Users users);
int updateByPrimaryKey(Users users);
}
所有自动生成的DAO层都有这6个相同的方法。下面我们用工厂模式把这些DAO层管理起来,达到我们这样的目的通用的数据库“增,删,改,查”,就是根据我们传入工厂的参数,自动调用对应的DAO和DAO中的方法。做一个简单的例子。
首先在数据库创建两个表 user表和city表
mysql> create table user(
-> id INT NOT NULL AUTO_INCREMENT,
-> name VARCHAR(100),
-> password VARCHAR(100),
-> PRIMARY KEY(id)
-> );
Query OK, 0 rows affected (0.05 sec)
mysql> create table city(
-> id INT NOT NULL AUTO_INCREMENT,
-> city_name VARCHAR(100),
-> city_code VARCHAR(100),
-> PRIMARY KEY(id)
-> );
Query OK, 0 rows affected (0.02 sec)
插入几条测试用的数据
mysql> INSERT INTO user(name,password)
-> VALUES('jack','111'),('rose','222');
mysql> INSERT INTO city(city_name,city_code)
-> VALUES ('北京','100000'),('天津','120000');
接下来创建entiey
public class City {
private Integer id;
private String cityName;
private String cityCode;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public String getCityCode() {
return cityCode;
}
public void setCityCode(String cityCode) {
this.cityCode = cityCode;
}
@Override
public String toString() {
return "City [id=" + id + ", cityName=" + cityName + ", cityCode=" + cityCode + "]";
}
}
public class User {
private String id;
private String name;
private String password;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public User(String name, String password) {
super();
this.name = name;
this.password = password;
}
public User() {
super();
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", password=" + password + "]";
}
}
创建一个Dao文件(持久层)的父接口(这里的方法要写子接口共有的)
import java.util.List;
public interface Dao {
Object findByName(String name);
List<Object> select(Object object);
}
和两个映射文件
import java.util.List;
public interface CityDao extends Dao{
City findByName(String name);
List<City> select(City city);
}
import java.util.List;
public interface UserDao extends Dao{
User findByName(String name);
List<User> select(User user);
}
两个都继承父接口DAO,然后写两个表的XML文件(映射文件)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="cn.tedu.demo3.dao.UserDao">
<select id="findByName"
parameterType="String"
resultType="cn.tedu.demo3.entity.User">
select
name as name,
password as password
from user
where name=#{name}
</select>
<select id="select" parameterType="cn.tedu.demo3.entity.User" resultType="cn.tedu.demo3.entity.User">
select
id id,
name name,
password password
from user
<where>
<if test="id != null">
and id=#{id}
</if>
<if test="name != null">
and name=#{name}
</if>
<if test="password != null">
and password=#{password}
</if>
</where>
</select>
</mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="cn.tedu.demo3.dao.CityDao">
<select id="findByName"
parameterType="String"
resultType="cn.tedu.demo3.entity.City">
select
id id,
city_name cityName,
city_code cityCode
from city
where city_name=#{name}
</select>
<select id="select" parameterType="cn.tedu.demo3.entity.City" resultType="cn.tedu.demo3.entity.City">
select
id id,
city_name cityName,
city_code cityCode
from city
<where>
<if test="id != null">
and id=#{id}
</if>
<if test="cityName != null">
and city_name=#{cityName}
</if>
<if test="id != cityCode">
and city_code=#{cityCode}
</if>
</where>
</select>
</mapper>
写工厂类
package cn.tedu.demo3.util;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.annotation.Resource;
import org.springframework.stereotype.Component;
import cn.tedu.demo3.dao.CityDao;
import cn.tedu.demo3.dao.Dao;
import cn.tedu.demo3.dao.UserDao;
@Component
public class MapperFactory {
@Resource
private UserDao userDao;
@Resource
private CityDao cityDao;
public CityDao getCityDao() {
return cityDao;
}
public void setCityDao(CityDao cityDao) {
this.cityDao = cityDao;
}
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
//这个方法比较局限,每增加一个DAO文件都要增加里边的逻辑
public Dao getDao(String tableName,MapperFactory factory) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
if(tableName == null){
return null;
}
if(tableName.equalsIgnoreCase("user")){
return userDao;
}
return null;
//return (Dao)getObject(tableName,factory);
}
//这个方法比较通用,只需要注入DAO,加上get方法就行
//这里是根据表名来拼接一个getter方法名,调用这个get方法获得对应的DAO
//因为spring管理起来的dao接口都是单例的(只能存在一个)所以只能通过注解注入,
//通过getter获得,不用new新的对象
public Dao getObject(String tableName ,MapperFactory factory) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
String firstLetter = tableName.substring(0, 1).toUpperCase();
String getter = "get" + firstLetter + tableName.substring(1)+"Dao";
Method method = factory.getClass().getMethod(getter, new Class[] {});
Object value = method.invoke(factory, new Object[] {});
return (Dao)value;
}
}
在业务层注入工厂类
@Resource
private MapperFactory factory;
封装一个通用的方法
/**
* @param tableName 表名
* @param object 对象(对象中set进去的就是搜索条件)
* @return 返回对象集合
*/
public List<Object> select(String tableName,Object object) throws Exception {
Dao dao = factory.getObject(tableName,factory);
List<Object> objectList = dao.select(object);
return objectList;
}
到这就完了,可以测试一下试试了
/**
* 测试方法
*/
public void test() throws Exception {
User user = new User();
user.setName("jack");
List<Object> list = select("user", user);
for (Object object : list) {
System.out.println(object);
}
}
打印结果
User [id=1, name=jack, password=111]
第二个测试方法
/**
* 测试方法
*/
public void test() throws Exception {
//User user = new User();
//user.setName("jack");
List<Object> list = select("city", null);
for (Object object : list) {
System.out.println(object);
}
}
打印结果
City [id=1, cityName=北京, cityCode=100000]
City [id=2, cityName=天津, cityCode=120000]
这个工厂模式扩展性不是很强,而且增加了理解和业务的难度,也就用起来比较方便
希望大神们能批评指正。谢谢CSDN里的前辈们让我学习到很多